guinea icon indicating copy to clipboard operation
guinea copied to clipboard

Adding global flags to all subcommands is not simple

Open boreq opened this issue 7 years ago • 1 comments

Example: a --verbosity flag which can be added to all subcommands.

It would obviously be annoying and wrong to add this flag to every subcommand and modify their run methods. Either a better way of doing this has to be devised or an automated way of doing this should be documented in the godoc.

This is how this can be solved right now:

func main() {
	injectGlobalBehaviour(&commands.MainCmd)
	err := guinea.Run(&commands.MainCmd)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func injectGlobalBehaviour(cmd *guinea.Command) {
	cmd.Options = append(cmd.Options, guinea.Option{
		Name:        "verbosity",
		Type:        guinea.String,
		Default:     "info",
		Description: "One of: debug, info, warn, error or crit. Default: info",
	})
	oldRun := cmd.Run
	cmd.Run = func(c guinea.Context) error {
		level, err := logging.LevelFromString(c.Options["verbosity"].Str())
		if err != nil {
			return err
		}
		logging.SetLoggingLevel(level)
		if oldRun != nil {
			return oldRun(c)
		}
		return nil
	}
	for _, subCmd := range cmd.Subcommands {
		injectGlobalBehaviour(subCmd)
	}
}

boreq avatar Aug 08 '18 23:08 boreq

This is a different approach which can be used:

var globalOpt = []guinea.Option{
	guinea.Option{
		Name:        "help",
		Type:        guinea.Bool,
		Default:     false,
		Description: "Display help",
	},
}

func main() {
	cmd, cmdName, cmdArgs := guinea.FindCommand(&commands.MainCmd, os.Args)
	cmd.Options = append(cmd.Options, globalOpt...)
	if err := cmd.Execute(cmdName, cmdArgs); err != nil {
		fmt.Fprintln(os.Stderr, err)
                os.Exit(1)
	}
}

boreq avatar Jul 08 '19 22:07 boreq