hidden@hidden:~$ ls -al $GOPATH/bin | grep cobra -rwxr-xr-x 1 zhuzhonghua zhuzhonghua 11411056 Aug 12 15:48 cobra
使用Cobra生成应用程序
假设现在我们要开发一个基于CLI的命令程序,名字为demo。执行如下命令:
hidden@hidden:~$ cd $GOPATH/src/github.com/spf13/ hidden@hidden:~/go/src/github.com/spf13$ cobra init demo --pkg-name=github.com/spf13/demo Your Cobra applicaton is ready at /home/zhuzhonghua/go/src/github.com/spf13/demo
hidden@hidden:~/cobra/demo$ go run main.go 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.
hidden@hidden:~/go/src/github.com/spf13/demo$ go run main.go version version called
生成的version代码如下(cmd/version.go):
package cmd
import ( "fmt"
"github.com/spf13/cobra" )
// versionCmd represents the version command var versionCmd = &cobra.Command{ Use: "version", 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("version called") }, }
func init() { rootCmd.AddCommand(versionCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // versionCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command // is called directly, e.g.: // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
注:命令的名称使用驼峰式命名(camelCase),而不能使用蛇形命名(snake_case)。读者可以自行创建一个蛇形命名的命令来查看一下实际的效果(hint: camelCase to snake_case)。
// rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "demo", 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() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } }
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/.demo.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. func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := homedir.Dir() if err != nil { fmt.Println(err) os.Exit(1) }
// Search config in home directory with name ".demo" (without extension). viper.AddConfigPath(home) viper.SetConfigName(".demo") }
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } }
versionCmd.PersistentFlags().String("global_foo", "global_val", "A help for global_foo") versionCmd.Flags().String("local_foo","local_val", "A help for local_foo")
现在运行go run main.go version -h得到如下结果:
hidden:demo hidden$ go run main.go version -h 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.
Usage: demo version [flags] demo version [command]
Available Commands: help show command info
Flags: --global_foo string A help for global_foo (default "global_val") -h, --help help for version --local_foo string A help for local_foo (default "local_val")
Global Flags: --config string config file (default is $HOME/.demo.yaml)
Use "demo version [command] --help" for more information about a command.
接着我们对比着再运行go run main.go help -h试试:
hidden:demo hidden$ go run main.go version help -h <snip>
Usage: demo version help [flags]
Flags: -h, --help help for help
Global Flags: --config string config file (default is $HOME/.demo.yaml) --global_foo string A help for global_foo (default "global_val")
var versionCmd = &cobra.Command{ Use: "version", 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("Version 1.0.0 for demo") }, }
var argsCmd = &cobra.Command{ Use: "args", Short: "args demo", Long: `<snip>`, Args: func(cmd *cobra.Command, args []string) error { if len(args)<1{ return errors.New("requires at least one arg") } return nil }, Run: func(cmd *cobra.Command, args []string) { fmt.Println("args called, args: ", args) }, }
func init() { rootCmd.AddCommand(argsCmd) }
示例中限定参数的格式至少为一个否则会报错。我们来运行一下看一看结果如何,首先是不添加参数(go run main.go args):
hidden:demo hidden$ go run main.go args Error: requires at least one arg Usage: demo args [flags]
Flags: -h, --help help for args
Global Flags: --config string config file (default is $HOME/.demo.yaml)
requires at least one arg exit status 1
可以看到报错:Error: requires at least one arg。
我们再来试一下添加参数的结果:
hidden:demo hidden$ go run main.go args 1 args called, args: [1] hidden:demo hidden$ go run main.go args 1 2 3 4 args called, args: [1 2 3 4]
示例中的Args函数可以替换为
Args: cobra.MinimumNArgs(1),
读者可以自行验证一下效果。
Help命令
前面的示例中出现了cmd/help.go,为了不产生迷惑,我们把这个文件先删除掉。
当您有子命令时,Cobra会自动为您的应用程序添加一个帮助命令。当用户运行“app help”时会调用此方法。此外,帮助还将支持所有其他命令作为输入。比如说,你有一个名为’create’的命令,没有任何额外的配置; 当’app help create’被调用时,Cobra会工作。每个命令都会自动添加’ - help’标志。
可以在终端输入cobra或者cobra help命令看一下实际的效果:
hidden@hidden:~$ cobra help 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.
Usage: cobra [command]
Available Commands: add Add a command to a Cobra Application help Help about any command init Initialize a Cobra Application
Flags: -a, --author string author name for copyright attribution (default "YOUR NAME") --config string config file (default is $HOME/.cobra.yaml) -h, --help help for cobra -l, --license string name of license for the project --viper use Viper for configuration (default true)
Use "cobra [command] --help" for more information about a command.
Available Commands: add Add a command to a Cobra Application help Help about any command init Initialize a Cobra Application
Flags: -a, --author string author name for copyright attribution (default "YOUR NAME") --config string config file (default is $HOME/.cobra.yaml) -h, --help help for cobra -l, --license string name of license for the project --viper use Viper for configuration (default true)
Use "cobra [command] --help" for more information about a command.
[root] PersistentPreRun with args: [] [root] PreRun with args: [] [root] Run with args: [] [root] PostRun with args: [] [root] PersistentPostRun with args: []
[root] PersistentPreRun with args: [arg1 arg2] [sub] PreRun with args: [arg1 arg2] [sub] Run with args: [arg1 arg2] [sub] PostRun with args: [arg1 arg2] [sub] PersistentPostRun with args: [arg1 arg2]