flaeg icon indicating copy to clipboard operation
flaeg copied to clipboard

Cannot parse root and sub commands together

Open nderjung opened this issue 5 years ago • 1 comments

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

nderjung avatar Sep 10 '19 08:09 nderjung

This problem could largely be addressed in merging the GlobalConfigurationand FooConfiguration, but seeing as one seems to stem from the other, the assumption is that rootCmd options are available to sub-commands.

nderjung avatar Sep 10 '19 08:09 nderjung