commit | 9af9c4aa2431b37aa273ccefc34745ac85c4e9c1 | [log] [tgz] |
---|---|---|
author | Nicolas Lacasse <nicolas.lacasse@gmail.com> | Mon Sep 15 13:40:24 2025 -0700 |
committer | GitHub <noreply@github.com> | Mon Sep 15 13:40:24 2025 -0700 |
tree | 7ec7a528ca29f769982c2a9b81f4b35767ac3a0a | |
parent | c9109cd15e4d71bea15fea5231b0ac57203cb36c [diff] |
Subcommands return ExitSuccess when handling --help and -h flags. (#43) The flags package handles top-level `--help` and `-h` flags by printing usage info and then exiting with status 0. Subcommands should handle these help flags similarly, by treating them as success. With this changes, we can correctly distinguish between the following calls: ``` $ cmd subcommand --help # treated as a successful call $ cmd subcommand --bogus # treated as a usage error ```
Subcommands is a Go package that implements a simple way for a single command to have many subcommands, each of which takes arguments and so forth.
This is not an official Google product.
Set up a ‘print’ subcommand:
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/google/subcommands"
)
type printCmd struct {
capitalize bool
}
func (*printCmd) Name() string { return "print" }
func (*printCmd) Synopsis() string { return "Print args to stdout." }
func (*printCmd) Usage() string {
return `print [-capitalize] <some text>:
Print args to stdout.
`
}
func (p *printCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&p.capitalize, "capitalize", false, "capitalize output")
}
func (p *printCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
for _, arg := range f.Args() {
if p.capitalize {
arg = strings.ToUpper(arg)
}
fmt.Printf("%s ", arg)
}
fmt.Println()
return subcommands.ExitSuccess
}
Register using the default Commander, also use some built in subcommands, finally run Execute using ExitStatus as the exit code:
func main() {
subcommands.Register(subcommands.HelpCommand(), "")
subcommands.Register(subcommands.FlagsCommand(), "")
subcommands.Register(subcommands.CommandsCommand(), "")
subcommands.Register(&printCmd{}, "")
flag.Parse()
ctx := context.Background()
os.Exit(int(subcommands.Execute(ctx)))
}