❯ go-clikit
v0.10.0 pkg.go.dev ↗

packages › command line › cobratree

cobratree

import "github.com/GSI-HPC/go-clikit/cobratree"

Make a cobra command tree strict, mark the errors of a command line as usage errors, and read the build info.

since v0.4.0 imports: no package of the kitrequires: github.com/spf13/cobra, github.com/spf13/pflag decisions 24 · 29 · 39
The place of cobratree in go-clikit: the packages it imports, and the packages that import it.termtextprogressdisplaycliprogressprogresstestmcpprogresseventlogfanoutfanouttestclioutdoctorfsutilcobratreecobratreetestlocalwebsessionsselocalwebtestlaunchassetspagehtmx

cobra is lenient where a script needs it strict. A command that only holds subcommands succeeds for a word that names none of them. help succeeds for a topic that names no command. And an argument check returns an error that names neither the arguments nor the command. cobratree.Strict fixes the three once the tree is built:

prog gte          unknown command "gte" for "prog" (did you mean "get"?)
prog status       unknown command "status" for "prog" (it is now "get cluster")
prog help crate   unknown help topic "crate": unknown command "crate" for "prog" (did you mean "create"?)
prog power on     requires at least 1 arg(s), only received 0 (usage: prog power on NODES)
root := &cobra.Command{Use: "prog", SilenceErrors: true, SilenceUsage: true}
get := &cobra.Command{Use: "get", Short: "Show things"}
get.AddCommand(&cobra.Command{
	Use:  "cluster [NAME]",
	Args: cobra.MaximumNArgs(1),
	RunE: func(*cobra.Command, []string) error { return nil },
})
root.AddCommand(get)
cobratree.Strict(root, cobratree.Moved(map[string]string{"status": "get cluster"}))

for _, args := range [][]string{
	{"gte"},
	{"status"},
	{"help", "get", "clustr"},
	{"get", "cluster", "a", "b"},
	{"get", "cluster", "--bogus"},
} {
	root.SetArgs(args)
	err := root.Execute()
	code := 1
	if cobratree.IsUsage(err) {
		code = 2
	}
	fmt.Printf("%d %v\n", code, err)
}
2 unknown command "gte" for "prog" (did you mean "get"?)
2 unknown command "status" for "prog" (it is now "get cluster")
2 unknown help topic "get clustr": unknown command "clustr" for "prog get" (did you mean "cluster"?)
2 accepts at most 1 arg(s), received 2 (usage: prog get cluster [NAME])
2 unknown flag: --bogus
ExampleStrict in cobratree/example_test.go. CI runs it and checks its output.

The main names#

NameWhat it does
cobratree.Strict, cobratree.Moved, cobratree.Topicsthe strict tree; renamed commands; help topics that are no command
cobratree.Usage, cobratree.Usagef, cobratree.IsUsagemark and tell a usage error, for the exit code
cobratree.InvalidValue, cobratree.FlagErrorone form for a value refused by pflag or by the program
cobratree.Coded, cobratree.Statusan exit status where the cause is known, read in main
cobratree.ReadBuildInfo, cobratree.BuildInfothe version, the commit and its time, for a version command
NOTE

The package names no exit code. A program maps a usage error to its own, commonly 2.

Fixed interfaces#

The texts of the errors that the checks of Strict return (decision 24), and those of InvalidValue and FlagError (decision 29). cobra and pflag are imported here and in cobratreetest alone.