flaeg
flaeg copied to clipboard
Cannot parse root and sub commands together
There seems to be a problem with parsing both root- and sub-commands together.
I've put together this example which illustrates the in-ability to parse sub commands and their flags when a root flag is added. In this example, a GlobalConfiguration
would be used to store the verbosity of logging under the -l
or --loglevel
flag. A subcomand, foo
, is added which has is own FooConfiguration
containing the flag --bar
to be used solely by its processor and not necessarily elsewhere:
package main
import (
"fmt"
"os"
"github.com/containous/flaeg"
)
type GlobalConfiguration struct {
LogLevel string `short:"l" long:"loglevel" description:"Output verbosity"`
}
type FooConfiguration struct {
Bar string `description:"Foo"`
}
var globalConfig = &GlobalConfiguration{
LogLevel: "info",
}
var globalPointersConfig = &GlobalConfiguration{}
var fooConfig = &FooConfiguration{
Bar: "bar",
}
var fooPointersConfig = &FooConfiguration{}
func main() {
rootCmd := &flaeg.Command{
Name: "test",
Description: `Test flaeg sub-commands`,
Config: globalConfig,
DefaultPointersConfig: globalPointersConfig,
Run: func() error {
fmt.Println("I should have access to --loglevel but not --bar!")
fmt.Println("Loglevel: ", globalConfig.LogLevel)
fmt.Println("Bar: ", fooConfig.Bar)
return nil
},
}
fooCmd := &flaeg.Command{
Name: "foo",
Description: `Foo sub-command`,
Config: fooConfig,
DefaultPointersConfig: fooPointersConfig,
Run: func() error {
fmt.Println("I should have access to --loglevel and --bar!")
fmt.Println("Loglevel: ", globalConfig.LogLevel)
fmt.Println("Bar: ", fooConfig.Bar)
return nil
},
}
// init flaeg
flaeg := flaeg.New(rootCmd, os.Args[1:])
// add sub-command foo
flaeg.AddCommand(fooCmd)
// run test
if err := flaeg.Run(); err != nil {
fmt.Println("Error %s", err.Error())
}
}
Under the normal assumption, and as per the declaration of usage, [flags]
can be put aftere the command name, in this case test
.
$ ./test -h
Test flaeg sub-commands
Usage: test [flags] <command> [<arguments>]
Use "test <command> --help" for help on any command.
Commands:
foo Foo sub-command
Flag's usage: test [--flag=flag_argument] [-f[flag_argument]] ... set flag_argument to flag(s)
or: test [--flag[=true|false| ]] [-f[true|false| ]] ... set true/false to boolean flag(s)
Flags:
-l, --loglevel Output verbosity (default "info")
-h, --help Print Help (this message) and exit
Error %s pflag: help requested
A subcommand, foo
, is available and still makes these assumptions:
$ ./test foo -h
Foo sub-command
Usage: foo [flags] <command> [<arguments>]
Use "foo <command> --help" for help on any command.
Flag's usage: foo [--flag=flag_argument] [-f[flag_argument]] ... set flag_argument to flag(s)
or: foo [--flag[=true|false| ]] [-f[true|false| ]] ... set true/false to boolean flag(s)
Flags:
--bar Foo (default "bar")
-h, --help Print Help (this message) and exit
Error %s pflag: help requested
However, when adding "global", or root, flags to a sub-command call, we are immediately prompted with the inability to recognise the subcommand foo
:
./test --loglevel=debug foo --bar=foo
Error here : unknown flag: --bar
Test flaeg sub-commands
Usage: test [flags] <command> [<arguments>]
Use "test <command> --help" for help on any command.
Commands:
foo Foo sub-command
Flag's usage: test [--flag=flag_argument] [-f[flag_argument]] ... set flag_argument to flag(s)
or: test [--flag[=true|false| ]] [-f[true|false| ]] ... set true/false to boolean flag(s)
Flags:
-l, --loglevel Output verbosity (default "info")
-h, --help Print Help (this message) and exit
Error %s unknown flag: --bar
Running the following yields the same result:
$ ./test --loglevel=debug --bar=foo foo
This problem could largely be addressed in merging the GlobalConfiguration
and FooConfiguration
, but seeing as one seems to stem from the other, the assumption is that rootCmd
options are available to sub-commands.