From 1be1d2841c773c01bee8289f55f7463b6e2c2539 Mon Sep 17 00:00:00 2001 From: Nick Miyake Date: Wed, 22 Nov 2017 16:13:03 -0800 Subject: [PATCH] Make rootCmd private Update Cobra generator to make rootCmd private rather than exporting it. Also update examples in README to use the exported Execute() command rather than referencing unexported rootCmd. Fixes #556 --- README.md | 40 +++++++++++++------------------ cobra/cmd/add.go | 4 ++-- cobra/cmd/init.go | 12 +++++----- cobra/cmd/testdata/root.go.golden | 10 ++++---- cobra/cmd/testdata/test.go.golden | 2 +- 5 files changed, 31 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index a422cf7..11bc5ec 100644 --- a/README.md +++ b/README.md @@ -158,10 +158,7 @@ import ( ) func main() { - if err := cmd.RootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } + cmd.Execute() } ``` @@ -174,7 +171,7 @@ commands you want. It's the easiest way to incorporate Cobra into your applicati ## Using the Cobra Library -To manually implement Cobra you need to create a bare main.go file and a RootCmd file. +To manually implement Cobra you need to create a bare main.go file and a rootCmd file. You will optionally provide additional commands as you see fit. ### Create rootCmd @@ -184,7 +181,7 @@ Cobra doesn't require any special constructors. Simply create your commands. Ideally you place this in app/cmd/root.go: ```go -var RootCmd = &cobra.Command{ +var rootCmd = &cobra.Command{ Use: "hugo", Short: "Hugo is a very fast static site generator", Long: `A Fast and Flexible Static Site Generator built with @@ -212,14 +209,14 @@ import ( func init() { cobra.OnInitialize(initConfig) - RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") - RootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/") - RootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution") - RootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)") - RootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration") - viper.BindPFlag("author", RootCmd.PersistentFlags().Lookup("author")) - viper.BindPFlag("projectbase", RootCmd.PersistentFlags().Lookup("projectbase")) - viper.BindPFlag("useViper", RootCmd.PersistentFlags().Lookup("viper")) + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") + rootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory eg. github.com/spf13/") + rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution") + rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)") + rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration") + viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) + viper.BindPFlag("projectbase", rootCmd.PersistentFlags().Lookup("projectbase")) + viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper")) viper.SetDefault("author", "NAME HERE ") viper.SetDefault("license", "apache") } @@ -267,10 +264,7 @@ import ( ) func main() { - if err := cmd.RootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } + cmd.Execute() } ``` @@ -292,7 +286,7 @@ import ( ) func init() { - RootCmd.AddCommand(versionCmd) + rootCmd.AddCommand(versionCmd) } var versionCmd = &cobra.Command{ @@ -329,7 +323,7 @@ command it's assigned to as well as every command under that command. For global flags, assign a flag as a persistent flag on the root. ```go -RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") +rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") ``` ### Local Flags @@ -337,7 +331,7 @@ RootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out A flag can also be assigned locally which will only apply to that specific command. ```go -RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") +rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") ``` ### Local Flag on Parent Commands @@ -360,8 +354,8 @@ You can also bind your flags with [viper](https://github.com/spf13/viper): var author string func init() { - RootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution") - viper.BindPFlag("author", RootCmd.PersistentFlags().Lookup("author")) + rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution") + viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) } ``` diff --git a/cobra/cmd/add.go b/cobra/cmd/add.go index 993ae16..fb22096 100644 --- a/cobra/cmd/add.go +++ b/cobra/cmd/add.go @@ -24,7 +24,7 @@ import ( func init() { addCmd.Flags().StringVarP(&packageName, "package", "t", "", "target package name (e.g. github.com/spf13/hugo)") - addCmd.Flags().StringVarP(&parentName, "parent", "p", "RootCmd", "variable name of parent command for this command") + addCmd.Flags().StringVarP(&parentName, "parent", "p", "rootCmd", "variable name of parent command for this command") } var packageName, parentName string @@ -35,7 +35,7 @@ var addCmd = &cobra.Command{ Short: "Add a command to a Cobra Application", Long: `Add (cobra add) will create a new command, with a license and the appropriate structure for a Cobra-based CLI application, -and register it to its parent (default RootCmd). +and register it to its parent (default rootCmd). If you want your command to be public, pass in the command name with an initial uppercase letter. diff --git a/cobra/cmd/init.go b/cobra/cmd/init.go index 149aabe..b2e5217 100644 --- a/cobra/cmd/init.go +++ b/cobra/cmd/init.go @@ -150,8 +150,8 @@ import ( var cfgFile string{{end}} -// RootCmd represents the base command when called without any subcommands -var RootCmd = &cobra.Command{ +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ Use: "{{.appName}}", Short: "A brief description of your application", Long: ` + "`" + `A longer description that spans multiple lines and likely contains @@ -168,7 +168,7 @@ to quickly create a Cobra application.` + "`" + `, // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - if err := RootCmd.Execute(); err != nil { + if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } @@ -180,12 +180,12 @@ func init() { {{if .viper}} // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, // will be global for your application.{{ if .viper }} - RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ else }} - // RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ end }} + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ else }} + // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ end }} // Cobra also supports local flags, which will only run // when this action is called directly. - RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }{{ if .viper }} // initConfig reads in config file and ENV variables if set. diff --git a/cobra/cmd/testdata/root.go.golden b/cobra/cmd/testdata/root.go.golden index 8eeeae8..a76a767 100644 --- a/cobra/cmd/testdata/root.go.golden +++ b/cobra/cmd/testdata/root.go.golden @@ -25,8 +25,8 @@ import ( var cfgFile string -// RootCmd represents the base command when called without any subcommands -var RootCmd = &cobra.Command{ +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ Use: "testproject", Short: "A brief description of your application", Long: `A longer description that spans multiple lines and likely contains @@ -43,7 +43,7 @@ to quickly create a Cobra application.`, // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - if err := RootCmd.Execute(); err != nil { + if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } @@ -55,11 +55,11 @@ func init() { // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, // will be global for your application. - RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.testproject.yaml)") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.testproject.yaml)") // Cobra also supports local flags, which will only run // when this action is called directly. - RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } // initConfig reads in config file and ENV variables if set. diff --git a/cobra/cmd/testdata/test.go.golden b/cobra/cmd/testdata/test.go.golden index 5840568..ed64427 100644 --- a/cobra/cmd/testdata/test.go.golden +++ b/cobra/cmd/testdata/test.go.golden @@ -36,7 +36,7 @@ to quickly create a Cobra application.`, } func init() { - RootCmd.AddCommand(testCmd) + rootCmd.AddCommand(testCmd) // Here you will define your flags and configuration settings.