From 6a65f945801bac9bdef65bd0466a089a37eeb14b Mon Sep 17 00:00:00 2001 From: jxsl13 Date: Tue, 1 Mar 2022 22:20:33 +0100 Subject: [PATCH] refactor generated command & subcommand boilerplate --- cmd/add.go | 4 +- cmd/project.go | 7 ++- cmd/testdata/root.go.golden | 60 ++++++++++++--------- cmd/testdata/test.go.golden | 34 +++++++----- tpl/main.go | 105 +++++++++++++++++++++--------------- 5 files changed, 123 insertions(+), 87 deletions(-) diff --git a/cmd/add.go b/cmd/add.go index 8377411..85c09be 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -31,7 +31,7 @@ var ( 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 root). If you want your command to be public, pass in the command name with an initial uppercase letter. @@ -66,7 +66,7 @@ Example: cobra add server -> resulting in a new cmd/server.go`, 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", "root", "variable name of parent command for this command") cobra.CheckErr(addCmd.Flags().MarkDeprecated("package", "this operation has been removed.")) } diff --git a/cmd/project.go b/cmd/project.go index ec8980e..3ca5fac 100644 --- a/cmd/project.go +++ b/cmd/project.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "os" + "strings" "text/template" "github.com/spf13/cobra" @@ -89,7 +90,11 @@ func (c *Command) Create() error { } defer cmdFile.Close() - commandTemplate := template.Must(template.New("sub").Parse(string(tpl.AddCommandTemplate()))) + commandTemplate := template.Must( + template.New("sub").Funcs(template.FuncMap{ + "title": strings.Title, + }).Parse(string(tpl.AddCommandTemplate())), + ) err = commandTemplate.Execute(cmdFile, c) if err != nil { return err diff --git a/cmd/testdata/root.go.golden b/cmd/testdata/root.go.golden index f23bb6d..8b24c48 100644 --- a/cmd/testdata/root.go.golden +++ b/cmd/testdata/root.go.golden @@ -23,22 +23,10 @@ import ( "github.com/spf13/viper" ) -var cfgFile string - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "cmd", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, -} +var ( + cfgFile string + rootCmd = NewRootCmd() +) // 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. @@ -51,16 +39,6 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - - // 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/.cmd.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") } // initConfig reads in config file and ENV variables if set. @@ -86,3 +64,33 @@ func initConfig() { fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) } } + +// NewRootCmd returns a new command which +// represents the base command when called without any subcommands +func NewRootCmd() *cobra.Command { + var rootCmd = &cobra.Command{ + Use: "cmd", + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains + examples and usage of using your application. For example: + + Cobra is a CLI library for Go that empowers applications. + This application is a tool to generate the needed files + to quickly create a Cobra application.`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, + } + + // 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/.cmd.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") + + return rootCmd +} diff --git a/cmd/testdata/test.go.golden b/cmd/testdata/test.go.golden index 1fb39e2..43c9518 100644 --- a/cmd/testdata/test.go.golden +++ b/cmd/testdata/test.go.golden @@ -21,23 +21,27 @@ import ( "github.com/spf13/cobra" ) -// testCmd represents the test command -var testCmd = &cobra.Command{ - Use: "test", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("test called") - }, -} +var testCmd = NewTestCmd() func init() { rootCmd.AddCommand(testCmd) +} + +// NewTestCmd creates a new test command +func NewTestCmd() *cobra.Command { + var testCmd = &cobra.Command{ + Use: "test", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples + and usage of using your command. For example: + + Cobra is a CLI library for Go that empowers applications. + This application is a tool to generate the needed files + to quickly create a Cobra application.`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("test called") + }, + } // Here you will define your flags and configuration settings. @@ -48,4 +52,6 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: // testCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + return testCmd } diff --git a/tpl/main.go b/tpl/main.go index 009524c..529bbb8 100644 --- a/tpl/main.go +++ b/tpl/main.go @@ -46,24 +46,14 @@ import ( ) {{ if .Viper -}} -var cfgFile string +var ( + cfgFile string + rootCmd = NewRootCmd() +) +{{- else -}} +var rootCmd = NewRootCmd() {{- end }} -// 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 -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.` + "`" + `, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, -} - // 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() { @@ -73,22 +63,11 @@ func Execute() { } } +{{ if .Viper -}} func init() { -{{- if .Viper }} cobra.OnInitialize(initConfig) -{{ end }} - // 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 }} - // 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") } +{{- end }} {{ if .Viper -}} // initConfig reads in config file and ENV variables if set. @@ -115,6 +94,38 @@ func initConfig() { } } {{- end }} + +// NewRootCmd returns a new command which +// represents the base command when called without any subcommands +func NewRootCmd() *cobra.Command { + var rootCmd = &cobra.Command{ + Use: "{{ .AppName }}", + Short: "A brief description of your application", + Long: ` + "`" + `A longer description that spans multiple lines and likely contains + examples and usage of using your application. For example: + + Cobra is a CLI library for Go that empowers applications. + This application is a tool to generate the needed files + to quickly create a Cobra application.` + "`" + `, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, + } + + // 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 }} + // 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") + + return rootCmd +} `) } @@ -131,23 +142,27 @@ import ( "github.com/spf13/cobra" ) -// {{ .CmdName }}Cmd represents the {{ .CmdName }} command -var {{ .CmdName }}Cmd = &cobra.Command{ - Use: "{{ .CmdName }}", - Short: "A brief description of your command", - Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.` + "`" + `, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("{{ .CmdName }} called") - }, -} +var {{ .CmdName }}Cmd = New{{ .CmdName | title }}Cmd() func init() { - {{ .CmdParent }}.AddCommand({{ .CmdName }}Cmd) + {{ .CmdParent }}Cmd.AddCommand({{ .CmdName }}Cmd) +} + +// New{{ .CmdName | title }}Cmd creates a new {{ .CmdName }} command +func New{{ .CmdName | title }}Cmd() *cobra.Command { + var {{ .CmdName }}Cmd = &cobra.Command{ + Use: "{{ .CmdName }}", + Short: "A brief description of your command", + Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples + and usage of using your command. For example: + + Cobra is a CLI library for Go that empowers applications. + This application is a tool to generate the needed files + to quickly create a Cobra application.` + "`" + `, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("{{ .CmdName }} called") + }, + } // Here you will define your flags and configuration settings. @@ -158,6 +173,8 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: // {{ .CmdName }}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + return {{ .CmdName }}Cmd } `) }