Skip to content
This repository has been archived by the owner on Apr 27, 2022. It is now read-only.

Cannot parse root and sub commands together #57

Open
nderjung opened this issue Sep 10, 2019 · 1 comment
Open

Cannot parse root and sub commands together #57

nderjung opened this issue Sep 10, 2019 · 1 comment

Comments

@nderjung
Copy link

nderjung commented Sep 10, 2019

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
Copy link
Author

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant