How to invoke help by default for a Cobra Subcommand?
Asked Answered
T

3

27

I want sub command to print out the help menu if no argument or flags are passed (The main command does this by default).

For example, the main command without any arguments or flags:

chris@pop-os:~$ ./tk
Command line application to deploy

Usage:
  tk [command]

Available Commands:
  addon       Install packages
  cluster     Used to create cloud infrastructures
  help        Help about any command

Flags:
      --config string   config file (default is $HOME/.tk8.yaml)
  -h, --help            help for tk
  -t, --toggle          Help message for toggle

Use "tk [command] --help" for more information about a command.

I want a subcommand like "tk addon" to also return its own help menu if no arguments or flags is entered, currently it only gives a blank line.

addon code :

var addonCmd = &cobra.Command{
    Use:   "addon",
Short: "Install addon packages",
Long: `Install additional packages`,
Run: func(cmd *cobra.Command, args []string) {

        }
    },
}
True answered 7/3, 2018 at 9:59 Comment(0)
B
43

It is possible to do with checking of amount of passed arguments to your program. If there is more then 0 args you will do actual work, but if it less then you will just show the "help" for the command.

var addonCmd = &cobra.Command{
    Use:   "addon",
    Short: "Install addon packages",
    Long: `Install additional packages`,
    Run: func(cmd *cobra.Command, args []string) {
        if len(args) == 0 {
            cmd.Help()
            os.Exit(0)
        }
        // do actual work
    },
}
Beanstalk answered 7/3, 2018 at 14:0 Comment(0)
J
3

I think it is better to handle that on PreRunE.

var addonCmd = &cobra.Command{
    Use:   "addon",
    Short: "Install addon packages",
    Long: `Install additional packages`,
    PreRunE: func(cmd *cobra.Command, args []string) error {
        if len(args) == 0 {
            cmd.Help()
            os.Exit(0)
        }
        return nil
    },
    Run: func(cmd *cobra.Command, args []string) {
        // do actual work
    },
}
Japeth answered 12/9, 2020 at 3:46 Comment(2)
This is not working. even it shows the cmd.Help(), after then Run: func() will start.Unclothe
Maybe comment on why you think this is better would help?Keelby
S
1

I am entirely new to Go and arrived at this because I too was needing the help to be displayed if no arguments were provided. The accepted answer is good and this is meant only as an alternative.

My sub-command requires exactly 2 arguments and so I found that Cobra provided a nice mechanism for this

var subCmd = &cobra.Command {
    Use : "subc",
    Args : cobra.ExactArgs(2),
    ...
}

The problem was this did not allow for me to print the help even with conditionals as discussed in Run in the accepted answer. So, after further digging I found that the definition of Args in the Command structure is the same as the *RunE fields (see docs for PositionalArgs). It's nothing more than a function with the exact same signaure as RunE or PreRunE.

So, an alternative solution for checking arguments and printing help in whatever circumstance is needed, consider

var subCmd = &cobra.Command {
    ...
    Args : func (cmd *cobra.Command, args []string) error {
        if len(args) == 0 {
            cmd.Help()
            os.Exit(0)
        } else if len(args) < 2 {
            fmt.Println("Incorrect number of args.  <arg1> <arg2> are required")
            os.Exit(1)
        }
        // as written, the command ignores anything more than 2
        return nil
    },
}

This has the benefit of being clear and concise that this pertains to arguments and not "functionality" implemented by the command.

Standfast answered 9/11, 2021 at 20:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.