An intentionally minimal Go package for building CLI applications. Extends the standard library's
flag package to support flags
anywhere in command arguments,
adds nested subcommands, and gets out of the way.
go get github.com/pressly/cli@latestRequires Go 1.21 or higher.
root := &cli.Command{
Name: "greet",
ShortHelp: "Print a greeting",
Exec: func(ctx context.Context, s *cli.State) error {
fmt.Fprintln(s.Stdout, "hello, world!")
return nil
},
}
if err := cli.ParseAndRun(ctx, root, os.Args[1:], nil); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}ParseAndRun parses the command hierarchy, handles --help automatically, and executes the
resolved command. For applications that need work between parsing and execution, use Parse and
Run separately. See the examples directory for more complete applications.
FlagsFunc is a convenience for defining flags inline. Use FlagOptions to extend the standard
flag package with features like required flag enforcement and short aliases:
Flags: cli.FlagsFunc(func(f *flag.FlagSet) {
f.Bool("verbose", false, "enable verbose output")
f.String("output", "", "output file")
}),
FlagOptions: []cli.FlagOption{
{Name: "verbose", Short: "v"},
{Name: "output", Short: "o", Required: true},
},Short aliases register -v as an alias for --verbose, -o as an alias for --output, and so on.
Both forms are shown in help output automatically.
Access flags inside Exec with the type-safe GetFlag function:
verbose := cli.GetFlag[bool](s, "verbose")
output := cli.GetFlag[string](s, "output")Child commands automatically inherit flags from parent commands, so a --verbose flag on the root
is accessible from any subcommand via GetFlag.
Commands can have nested subcommands, each with their own flags and Exec function:
root := &cli.Command{
Name: "todo",
Usage: "todo <command> [flags]",
ShortHelp: "A simple CLI for managing your tasks",
SubCommands: []*cli.Command{
{
Name: "list",
ShortHelp: "List all tasks",
Exec: func(ctx context.Context, s *cli.State) error {
// ...
return nil
},
},
},
}For a more complete example with deeply nested subcommands, see the todo example.
Help text is generated automatically and displayed when --help is passed. To customize it, set the
UsageFunc field on a command.
See docs/usage-syntax.md for conventions used in usage strings.
This project is in active development and undergoing changes as the API gets refined. Please open an issue if you encounter any problems or have suggestions for improvement.
There are many great CLI libraries out there, but I always felt they were too heavy for my needs.
Inspired by Peter Bourgon's ff library, specifically the v3
branch, which was so close to what I wanted. The v4 branch took a different direction, and I
wanted to keep the simplicity of v3. This library carries that idea forward.
This project is licensed under the MIT License - see the LICENSE file for details.