😄 CLI manager library, heavily inspired by ffcli.
This package is originally based on peterbourgon's ff
package (Apache2 License).
It implements small changes that don't fit with the original's author Goals and Non-goals.
Changes include:
- Adding an optional
Command.FlagSetBuilder
callback to configure commands and subcommands dynamically and support sharing the same flag targets. - Using
flag.ContinueOnError
by default instead offlag.ExitOnError
. - Printing usage instead of an returning an error if a command does not implements an
Exec
func. - Use a different
DefaultUsageFunc
.
import (
"context"
"flag"
"fmt"
"log"
"os"
"github.com/peterbourgon/ff/v3"
"moul.io/climan"
)
var opts struct {
debug bool
fooFlag string
}
func Example() {
root := &climan.Command{
Name: "example",
ShortUsage: "example [global flags] <subcommand> [flags] [args...]",
ShortHelp: "example's short help",
LongHelp: "example's longer help.\nwith more details.",
FlagSetBuilder: func(fs *flag.FlagSet) {
fs.BoolVar(&opts.debug, "debug", opts.debug, "debug mode")
},
Exec: doRoot,
Subcommands: []*climan.Command{
&climan.Command{
Name: "foo",
FlagSetBuilder: func(fs *flag.FlagSet) {
fs.BoolVar(&opts.debug, "debug", opts.debug, "debug mode")
fs.StringVar(&opts.fooFlag, "flag", opts.fooFlag, "foo's flag")
},
ShortUsage: "foo [flags]",
ShortHelp: "foo things",
Exec: doFoo,
},
},
FFOptions: []ff.Option{ff.WithEnvVarPrefix("EXAMPLE")},
}
if err := root.Parse(os.Args[1:]); err != nil {
log.Fatal(fmt.Errorf("parse error: %w", err))
}
if err := root.Run(context.Background()); err != nil {
log.Fatal(fmt.Errorf("run error: %w", err))
}
}
func doRoot(ctx context.Context, args []string) error {
fmt.Println("args", args)
return nil
}
func doFoo(ctx context.Context, args []string) error {
fmt.Println("flag", opts.fooFlag)
return nil
}
TYPES
type Command struct {
Name string
Exec func(context.Context, []string) error
FlagSetBuilder func(fs *flag.FlagSet)
Subcommands []*Command
ShortUsage string
ShortHelp string
LongHelp string
FFOptions []ff.Option
FlagSet *flag.FlagSet
UsageFunc func(c *Command) string
// Has unexported fields.
}
func (c *Command) Parse(args []string) error
func (c *Command) Run(ctx context.Context) error
go get moul.io/climan
See https://github.com/moul/climan/releases
I really welcome contributions. Your input is the most precious material. I'm well aware of that and I thank you in advance. Everyone is encouraged to look at what they can do on their own scale; no effort is too small.
Everything on contribution is sum up here: CONTRIBUTING.md
Pre-commit script for install: https://pre-commit.com
Thanks goes to these wonderful people (emoji key):
Manfred Touron 🚧 📖 |
moul-bot 🚧 |
This project follows the all-contributors specification. Contributions of any kind welcome!
© 2021 Manfred Touron
Licensed under the Apache License, Version 2.0
(LICENSE-APACHE
) or the MIT license
(LICENSE-MIT
), at your option.
See the COPYRIGHT
file for more details.
SPDX-License-Identifier: (Apache-2.0 OR MIT)