Package cli is a tiny and minimalistic CLI library for Go.
This package aims to reach out these goals:
- To be simple as possible.
- To be flexible until you not violate (1).
There are few libraries to build CLI for sure, but sometimes you don't want to
spend much time on learning their philosophy. To be honest it's almost always
much easier to write your own map[string]func()
. This library allows you to
save the time spent on writing that.
There is a cli.Command
interface which has single Run()
method.
You can group commands by using cli.Commands
map type.
Additional behaviour can be added by implementing few optional interfaces such
as cli.FlagDefiner
.
There is no "persistent" or "global" flags. That is, flags are parsed exactly for command they appear after.
Implementing this is not a big deal, but it complicates library API enough. However, it's possible to "mixin" global flags into each command's flag set manually (optionally resolving cases when global flag was set twice on the path or was rewritten by env value if custom flags parsing used).
package main
import (
"context"
"flag"
"time"
"github.com/gobwas/cli"
)
func main() {
cli.Main(cli.Commands{
"sleep": new(sleepCommand),
})
}
type sleepCommand struct {
duration time.Duration
}
func (s *sleepCommand) DefineFlags(fs *flag.FlagSet) {
fs.DurationVar(&s.duration,
"d", s.duration,
"how long to sleep",
)
}
func (s *sleepCommand) Run(ctx context.Context, _ []string) error {
select {
case <-ctx.Done(): // SIGINT, SIGTERM or SIGQUIT received.
return ctx.Err()
case <-time.After(s.duration):
return nil
}
}
Note that
context.Context
instance passed to theRun()
method will be cancelled by default if process receives SIGTERM, SIGINT or SIGQUIT signals. Seecli.Runner
andcli.DefaultRunner
docs for more info.
Without help message customization, help request will output this:
$ go run ./example sleep -h
Usage:
example sleep
Options:
-d duration
how long to sleep (default 1s)
However, you can implement optional cli.NameProvider
and, say,
cli.SynopsisProvider
to make help message more specific:
func (s *sleepCommand) Name() string {
return "Suspends execution for a given amount of time."
}
func (s *sleepCommand) Synopsis() string {
return "[-d duration]"
}
Now the output will look like this:
$ go run ./examples/simple help sleep
Suspends execution for a given amount of time.
Usage:
example sleep [-d duration]
Options:
-d duration
how long to sleep (default 1s)
Help for whole binary will look like this:
$ go run ./example help
Usage:
example [help] <command>
Commands:
sleep Suspends execution for a given amount of time.
To customize the cli.Commands
help output you can use cli.Container
wrapper.
See the example folder for more info.