cobra cobra 是go的cli框架,包含cli库和生成基于cobra cli应用的命令行工具
简介
子命令,如app server
、app sub
等
完整兼容POSIX的flag,包括长命名和短命名
子命令的嵌套(子命令)
全局、本地、级联三种flag
好用的工具命令,如cobra init appname
初始化cli程序,cobra add cmdname
为cli程序增加子命令
智能提示
生成命令help,以及为每个flag、cmd生成-h
,--help
帮助
生成自动补全功能
生成man帮助文档
命令别名
自定义帮助、用法
为达到saas的12-factor 可选择viper
安装 go get -u github.com/spf13/cobra/cobra
会自动安装最新版本库和命令行工具,国内下不下来可以手动下载放到对应的文件夹中,然后就可以在你的code里应用它import "github.com/spf13/cobra"
概念 cobra主要管理commands、args、flags,commands代表一个命令或动作,一般用动词命名,args代表输入的参数,一般用名词命名,flags是对commands的修饰,一般用形容词命名;好的cli应用应该学习成本低,用户容易理解 cli的含义,git的例子能很好的说明这一点: git clone URL --bare
,clone是commands是动词,URL是args是你的输入,bare是flag是形容词
commands commands是cli应用的核心,每次交互都包含在一个command中,command可以拥有可选的子命令(sub commands)
flags flag 是修饰command的一种方式,cobra支持完全兼容的POSIX flag以及go的 flag包,一个flag可以被定义成仅对当前命令生效或对当前及子孙命令生效(对于写代码时增加flag来说),flag功能由pflag library 提供
开始使用 虽然你可以自定义你自己的应用工程结构,但推荐你使用以下cobra-cli应用的典型结构
1 2 3 4 5 6 7 ▾ appName/ ▾ cmd/ add.go your.go commands.go here.go main.go
在cobra应用中,main.go通常只提供初始化cobra的功能,like that
1 2 3 4 5 6 7 8 9 package mainimport ( "{pathToYourApp}/cmd" ) func main () { cmd.Execute() }
使用cobra生成工具 cobra提供了帮你生成模板的cli工具,有如下命令:
初始化应用init cobra init [name] [flags]
,name是你cobra应用的名字,--pkg-name
pkg 的名字 flag可以选择-a
作者名,-l
添加license,默认Apache2.0,--viper
添加viper等功能,具体如下
1 2 3 4 5 --pkg-name string fully qualified pkg name -a, --author string author name for copyright attribution (default "YOUR NAME") --config string config file (default is $HOME/.cobra.yaml) -l, --license string name of license for the project --viper use Viper for configuration (default true)
初始化应用后一般go mod init
初始化应用,golang基础,在此不赘述
添加commands cobra add [name] -p 'parentComand'
-p
可以为特定命令添加子命令,缺省为根命令
使用Cobra库 手动创建需要新建一个rootCmd文件,然后添加若干command
创建rootCmd cobra不需要创建一个特定的实例,可以直接使用&cobra.Commaand
,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 love by spf13 and friends in Go. Complete documentation is available at http://hugo.spf13.com` , Run: func (cmd *cobra.Command, args []string ) { }, } func Execute () { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1 ) } }
你可以在init中定义flatgs以及处理配置,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import ( "fmt" "os" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" ) 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" )) viper.SetDefault("author" , "NAME HERE <EMAIL ADDRESS>" ) viper.SetDefault("license" , "apache" ) } func initConfig () { if cfgFile != "" { viper.SetConfigFile(cfgFile) } else { home, err := homedir.Dir() if err != nil { fmt.Println(err) os.Exit(1 ) } viper.AddConfigPath(home) viper.SetConfigName(".cobra" ) } if err := viper.ReadInConfig(); err != nil { fmt.Println("Can't read config:" , err) os.Exit(1 ) } }
添加命令 添加的命令可以创建在cmd目录下单独的go文件,比如创建一个version命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package cmdimport ( "fmt" "github.com/spf13/cobra" ) func init () { rootCmd.AddCommand(versionCmd) } var versionCmd = &cobra.Command{ Use: "version" , Short: "Print the version number of Hugo" , Long: `All software has versions. This is Hugo's` , Run: func (cmd *cobra.Command, args []string ) { fmt.Println("Hugo Static Site Generator v0.9 -- HEAD" ) }, }
使用flag 我们有两种