cobra是一个命令行框架, 它可以生成和解析命令行。 Cobra具有非常干净的界面和简单的设计,而不需要不必要的构造函数或初始化方法。
用Cobra命令构建的应用程序被设计成尽可能方便用户使用。可以在命令之前或之后放置flag。可以使用短的和长的flag。命令甚至不需要完全键入,help是自动生成的,它是应用程序使用help命令或–help flag时调用的特定命令.
概念
Cobra是建立在命令、参数结构之上的。
Commands代表行动,Args是事物,Flags表示对行为的修饰。
比较好的应用程序使用起来就像句子一样。用户将知道如何使用应用程序因为他们本来就知道如何使用它。
一般模式就像下面一样:
一些好的现实世界的例子可以更好地说明这一点。
在下面的例子中,server 是一个命令, port是一个参数
Commands
命令是应用程序的中心点。应用程序支持的每个交互都将包含在命令中。命令可以拥有子命令并且可选地运行操作。
命令具有以下结构:
1 2 3 4 5 6
| type Command struct { Use string Short string Long string Run func(cmd *Command, args []string) // Run runs the command. }
|
flags
flags是修改命令行为的一种方式。Cobra完全兼容POSIX命令行模式以及flags。
flag的功能由pflag库提供,它是flag标准库的一个fork,保持相同的接口的同时兼容POSIX标准。
使用
Cobra的工作原理是创建一组命令,然后将它们组织成一棵树。命令树树定义应用程序的结构。
一旦每个命令都定义了相应的flag,那么树将被分配给最终执行的command。
Cobra提供的功能
- 简易的子命令行模式,如 app server, app fetch等等
- 完全兼容posix命令行模式
- 嵌套子命令subcommand
- 支持全局,局部,串联flags
- 使用Cobra很容易的生成应用程序和命令,使用cobra create appname和cobra add cmdname
- 如果命令输入错误,将提供智能建议,如 app srver,将提示srver没有,是否是app server
- 自动生成commands和flags的帮助信息
- 自动生成详细的help信息,如app help
- 自动识别-h,–help帮助flag
- 自动生成应用程序在bash下命令自动完成功能
- 自动生成应用程序的man手册
- 命令行别名
- 自定义help和usage信息
- 可选的紧密集成的viper apps
如何使用
下面简单介绍一下如何使用Cobra,基本能够满足一般命令行程序的需求,如果需要更多功能,可以研究一下源码github。
安装
cobra的源工程地址在github.com/spf13/cobra/cobra, 同其他Go开源项目一样,我们通过go get来拉取:
1
| $ go get -u github.com/spf13/cobra/cobra
|
安装完成后,打开GOPATH目录,bin目录下应该有已经编译好的cobra或cobra.exe程序,当然你也可以使用源代码自己生成一个最新的cobra程序。
通过下面语句import到工程:
1
| import "github.com/spf13/cobra"
|
通过cobra命令生成工程
1 2 3 4 5
| $ cobra init cobra-demo Your Cobra application is ready at /Users/yang/lib/go/src/cobra-demo Give it a try by going there and running `go run main.go` Add commands to it by running `cobra add [cmdname]`
|
生成后的工程目录结构如下:
1 2 3 4 5 6
| $ tree cobra-demo cobra-demo ├── LICENSE ├── cmd │ └── root.go └── main.go
|
cobra生成的工程, 默认文件都放在cmd目录下, 以root.go作为根命令. cobra可以嵌套flag, pflag, viper一起使用. 其中init()里面调用了initConfig(), 并可以调用pflag:
1 2 3 4 5 6 7 8 9 10 11 12
| func init() { cobra.OnInitialize(initConfig) RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra-demo.yaml)") RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
|
flag的操作中, 分为全局的flag和当前子命令的flag. 什么是子命令呢? cobra支持多级子命令, 比如: mycmd sub1 sub2, 其中mycmd是根命令, sub1是mycmd的子命令, sub2是sub1的子命令. 因此, RootCmd.PersistentFlags()是一个全局flag, RootCmd.Flags()是当前命令的flag. 由于是根命令,其实二者是相同的, 但是如果在子命令中, 二者是不同的.
下面是使用viper的地方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func initConfig() { if cfgFile != "" { viper.SetConfigFile(cfgFile) } viper.SetConfigName(".cobra-demo") viper.AddConfigPath("$HOME") viper.AutomaticEnv() if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } }
|
cobra对象初始化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var RootCmd = &cobra.Command{ Use: "cobra-demo", Short: "A brief description of your application", Long: `A longer description that spans multiple lines and likely contains demos and usage of using your application. For demo:
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) { }, }
|
上面这个对象就是cobra的根命令对象, 默认生成的时候Run字段是被注释的, 打开以后就可以在函数里面写入自己的处理函数. 下面是运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ go run main.go -h A longer description that spans multiple lines and likely contains demos and usage of using your application. For demo: 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-demo [flags] Flags: --config="": config file (default is $HOME/.cobra-demo.yaml) -t, --toggle[=false]: Help message for toggle
|
执行下列命令, 生成子命令:
1 2 3
| cobra add serve cobra add config cobra add create -p 'configCmd'
|
之后,工程结构变为:
1 2 3 4 5 6 7 8 9 10 11
| $ tree cobra-demo cobra-demo ├── LICENSE ├── cmd │ ├── config.go │ ├── create.go │ ├── root.go │ └── serve.go └── main.go 1 directory, 8 files
|
通过上述命令,我们生成了3个子命令, config, serve, create:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ go run main.go -h A longer description that spans multiple lines and likely contains demos and usage of using your application. For demo: 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-demo [flags] cobra-demo [command] Available Commands: config A brief description of your command serve A brief description of your command Flags: --config="": config file (default is $HOME/.cobra-demo.yaml) -t, --toggle[=false]: Help message for toggle
|
执行config子命令
1 2
| $ go run main.go config config called
|
执行config的create子命令
1 2
| $ go run main.go config create create called
|
我们可以看到代码里面config是作为根命令的子命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| func init() { RootCmd.AddCommand(configCmd) configCmd.PersistentFlags().String("foo", "", "A help for foo") configCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") }
|
当我们输入错误时,会有相应提示
1 2 3 4 5 6 7 8 9 10 11 12 13
| $ go run main.go serv Error: unknown command "serv" for "cobra-demo" Did you mean this? serve Run 'cobra-demo --help' for usage. unknown command "serv" for "cobra-demo" Did you mean this? serve exit status 1
|