This project is no longer maintained by Turbine Labs, which has shut down.
The cli
package provides a simple library for creating command-line
applications with multiple sub-commands.
We feel strongly that all Turbine Labs executables should have high-quality
and consistent ergonomics. We use the cli
package for all our command line
tools, private and public.
Why on earth did we choose to roll our own CLI package, with several high-quality alternatives already available (e.g. github.com/urfave/cli, github.com/spf13/cobra)? As with most libraries, it came from a combination of good intentions and hubris.
Chiefly, we wanted:
- something fairly lightweight
- to use the existing Go flag package
- to support both single- and sub-command apps
- to minimize external dependencies
- for flags to be configurable via environment flag
- for usage text to be both auto-generated and fairly customizable
We started with the excellent github.com/jonboulle/yacli, a "micro-pseudo-framework" which recognizes a central truth:
All CLI frameworks suck. This one just sucks slightly less.
Indeed we were attracted to its simplicity and ease of use, and used it for a time, but quickly grew weary of the attendant boilerplate necessary for each new project. We began to adapt it, to centralize code, and ended up writing a whole thing.
Now that we have it, we like it, and we welcome you to use it, or not, write your own, or contribute to ours, or whatever. It's all fine with us.
- Go 1.10.3 or later (previous versions may work, but we don't build or test against them)
The cli project depends on our nonstdlib package; The tests depend on our test package and gomock. It should always be safe to use HEAD of all master branches of Turbine Labs open source projects together, or to vendor them with the same git tag.
Additionally, we vendor github.com/mattn/go-isatty and golang.org/x/sys/unix. This should be considered an opaque implementation detail, see Vendoring for more discussion.
go get -u github.com/turbinelabs/cli/...
mkdir -p $GOPATH/src/turbinelabs
git clone https://github.com/turbinelabs/cli.git > $GOPATH/src/turbinelabs/cli
go test github.com/turbinelabs/cli/...
The cli
package includes:
- Support for both global and per-sub-command flags
- Automatic generation of help and version flags and (if appropriate) sub-commands
- Basic terminal-aware formatting of usage text, including pre-formatted blocks, and bold and underlined text
- Auto-wrapping of usage text to the terminal width
- Support for the use of environment variables to set both global and per-sub-command flags
Both global and per sub-command flags can be set by environment variable. Vars are all-caps, underscore-delimited, and replace all non-alphanumeric symbols with underscores. They are prefixed by the executable name, and by then by the subcommand if relevant.
For example, the following are equivalent:
somecmd --global-flag=a somesubcmd --cmd-flag=b
SOMECMD_GLOBAL_FLAG=a SOMECMD_SOMESUBCMD_CMD_FLAG=b somecmd
A runtime validation is available to ensure that there are no variable name collisions for a given CLI.
Help text is generated from:
- The description passed into
cli.NewWithSubCmds
- The
.Description
,.Summary
and.Usage
fields of eachcommand.Cmd
- The
.Usage
field of eachflag.Flag
Since our target is Terminal windows, we chose to keep formatting fairly simple.
All text is passed through text/template; As such, double curly braces ("{{") in text will trigger template actions.
The cli package provides two text-styling functions for help text, for terminals that support them:
`text may rendered in {{bold "some bold text"}}`
`text may be {{ul "some underlined text}}`
To render text that contains "{{", use a pipeline action:
`here are some curlies {{ "{{something inside braces}}" }}`
Help text is also passed through go/doc, to support a few simple formatting primitives:
- Text wraps to the current terminal width, if available, or 80 columns otherwise.
- Whitespace, including single newlines, is collapsed in a given paragraph.
- New paragraphs are signaled with two newlines.
- A 4-space indent signals pre-formatted text, which is not wrapped.
Single- and multiple-command examples are available in the godoc.
Please see Versioning of Turbine Labs Open Source Projects.
Patches accepted! Please see Contributing to Turbine Labs Open Source Projects.
All Turbine Labs open-sourced projects are released with a Contributor Code of Conduct. By participating in our projects you agree to abide by its terms, which will be carefully enforced.