Cobra: Why does `--version` not work?

Created on 2 Sep 2019  路  2Comments  路  Source: spf13/cobra

One of the issues and README indicates that if one adds:

rootCmd.SetVersionTemplate("Version: ")

that --version would return Version: in this case, but instead:

Error: unknown flag: --version
Usage:

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

unknown flag: --version
exit status 1

was returned. What was missed?

Most helpful comment

Hi @030! Please, read carefully the paragraph/section you are referring to. I believe that both the description and the functionality are correct, but you might have read too fast:

Cobra adds a top-level '--version' flag if the Version field is set on the root command. Running an application with the '--version' flag will print the version to stdout using the version template. The template can be customized using the cmd.SetVersionTemplate(s string) function.

Hence, you are customizing the format/template, but you did not enable it.

Example of adding a Version field to a command:

var rootCmd = &cobra.Command{
  Use:   "hugo",
  Version: "myver0.1.8",
  Short: "Hugo is a very fast static site generator",
}

Furthermore, I think that the description is correct, but incomplete. It might/should say "Cobra adds a top-level '--version' flag if the Version field is set on the root command". This is because I believe that you can add a Version field to any command (be it the root or a subcommand at any level). Flag --version will be enabled in each of the commands/subcommands that have the field set, but not in any other. Note, that the content of the Version fields does not need to be the same. I.e., if you have a single CLI binary that can work as a client and as a server, you can have separate versioning schemes for each of the subcommands and for the wrapper/package:

# myclitool --version
stringA

# myclitool client --version
stringB

# myclitool server --version
stringC

Of course, you might also want to have --version available in all subcommands, but you don't want to write the string multiple times, or use a variable for that. You can achieve this by defining the field in a single command (say root) and then referring it. For example:

var rootCmd = &cobra.Command{
  Use:   "hugo",
  Version: "myver0.1.8",
}

var clientCmd = &cobra.Command{
  Use:   "client",
  Version: rootCmd.Version,
}

var serverCmd = &cobra.Command{
  Use:   "server",
  Version: rootCmd.Version,
}

For completeness, in #724 you will find an example to add a version subcommand that produces the same output as --version.

All 2 comments

Hi @030! Please, read carefully the paragraph/section you are referring to. I believe that both the description and the functionality are correct, but you might have read too fast:

Cobra adds a top-level '--version' flag if the Version field is set on the root command. Running an application with the '--version' flag will print the version to stdout using the version template. The template can be customized using the cmd.SetVersionTemplate(s string) function.

Hence, you are customizing the format/template, but you did not enable it.

Example of adding a Version field to a command:

var rootCmd = &cobra.Command{
  Use:   "hugo",
  Version: "myver0.1.8",
  Short: "Hugo is a very fast static site generator",
}

Furthermore, I think that the description is correct, but incomplete. It might/should say "Cobra adds a top-level '--version' flag if the Version field is set on the root command". This is because I believe that you can add a Version field to any command (be it the root or a subcommand at any level). Flag --version will be enabled in each of the commands/subcommands that have the field set, but not in any other. Note, that the content of the Version fields does not need to be the same. I.e., if you have a single CLI binary that can work as a client and as a server, you can have separate versioning schemes for each of the subcommands and for the wrapper/package:

# myclitool --version
stringA

# myclitool client --version
stringB

# myclitool server --version
stringC

Of course, you might also want to have --version available in all subcommands, but you don't want to write the string multiple times, or use a variable for that. You can achieve this by defining the field in a single command (say root) and then referring it. For example:

var rootCmd = &cobra.Command{
  Use:   "hugo",
  Version: "myver0.1.8",
}

var clientCmd = &cobra.Command{
  Use:   "client",
  Version: rootCmd.Version,
}

var serverCmd = &cobra.Command{
  Use:   "server",
  Version: rootCmd.Version,
}

For completeness, in #724 you will find an example to add a version subcommand that produces the same output as --version.

@umarcor Thanks for the comprehensive explanation. Now it works. :+1:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

phanirithvij picture phanirithvij  路  5Comments

andygrunwald picture andygrunwald  路  6Comments

joernott picture joernott  路  6Comments

jjzcru picture jjzcru  路  3Comments

mdaymard picture mdaymard  路  5Comments