An opinionated CLI framework:
- declarative nested commands
- detailed, colored
--help
output (including what a flag is currently set to) - update flags from
os.Args
, config files, environment variables, and app defaults - extend with new flag types, config file formats, or
--help
output - snapshot testing support
warg
is still a work in progress, but the "bones" are where I want them - I don't intend to change the basic way warg works, but I do plan to experiment with a few APIs (make the value and config APIs simpler) and add TUI generation. I think the largest breaking changes are behind me (see the CHANGELOG). Read Go Project Notes to help understand the tooling.
I'm watching issues; please open one for any questions and especially BEFORE submitting a Pull request.
All of the CLIs on my profile use warg.
See API docs (including code examples) at pkg.go.dev
Simple "butler" example (full source here):
app := warg.New(
"butler",
"v1.0.0",
section.New(
string("A virtual assistant"),
section.NewCommand(
"present",
"Formally present a guest (guests are never introduced, always presented).",
present,
command.NewFlag(
"--name",
"Guest to address.",
scalar.String(),
flag.Alias("-n"),
flag.EnvVars("BUTLER_PRESENT_NAME", "USER"),
flag.Required(),
),
),
section.CommandMap(warg.VersionCommandMap()),
),
warg.GlobalFlagMap(warg.ColorFlagMap()),
)
By design, warg apps have the following requirements:
- must contain at least one subcommand. This makes it easy to add further subcommands, such as a
version
subcommand. It is not possible to design a warg app such that calling<appname> --flag <value>
does useful work. Instead,<appname> <command> --flag <value>
must be used. - warg does not support positional arguments. Instead, use a required flag:
git clone <url>
would begit clone --url <url>
. This makes parsing much easier, and I like the simplicity of it, even though it's more to type/tab-complete.