命令行工具库cobra
作者:程序员CKeen
博客:http://ckeen.cn
长期坚持做有价值的事!积累沉淀,持续成长,升维思考!希望把编码作为长期兴趣爱好😄
1. Cobra介绍
Cobra是一个用于创建强大的现代CLI应用程序的库。Cobra被用于许多go项目中,如Kubernetes, Hugo和Github CLI等。官方列举了使用cobra库的列表
Cobra主要特点:
- 简单的子命令模式: 例如server start,app fetch,等等。
- 完全兼容posix的命令行的选项标志(包括短版本和长版本)
- 支持嵌套的子命令
- 支持全局、本地和级联选项
- 智能提醒 (当你输入app ser时,会提示你是否想输入的是app server)
- 自动帮你生成命令和选项
- 自动帮你做选项的识别,例如识别flag -h, --help
- 自动生成应用程序在 bash 下命令自动完成功能
- 为您的应用程序自动生成的man手册
- 可以自定义 help 和 usage 信息
2. Cobra的三个重要概念
首先需要明确 3 个基本概念:
- 命令(Command):需要执行的操作;
- 参数(Arg):命令的参数,即要操作的对象;
- 选项(Flag):命令选项可以调整命令的行为。
下面拿我们经常使用git的命令对举例
git clone -b develop https://xxxx.git
git config --global user.name "bettyaner"
git commit -m "xxxx"
上述的命令中
git是应用程序的名称,
clone/config/commit是一个命令(Command)或者子命令
-b/-m/--global为选项(Flag)
选项后面的值为具体的参数(Arg)
3. 安装cobra库
go get -u github.com/spf13/cobra@latest
使用的时候我们需要在项目中引用cobra
import (
"github.com/spf13/cobra"
)
4. 使用cobra配置使用
我们先在cmd的目录下cobra.go创建cobra的根命令:
var author string
var rootCmd = &cobra.Command{
Use: "cobra [string to action]",
Short: "cobra command tool",
Long: "cobra is a simple cli command tool",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
log.Println("1. rootCmd PersistentPreRun")
},
PreRun: func(cmd *cobra.Command, args []string) {
log.Println("2. rootCmd PreRun")
//setup()
},
Run: func(cmd *cobra.Command, args []string) {
log.Println("3. rootCmd Run, auth:" + author)
run()
},
PostRun: func(cmd *cobra.Command, args []string) {
log.Println("4. rootCmd PostRun")
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
log.Println("5. rootCmd PersistentPostRun")
},
}
func init(){
rootCmd.PersistentFlags().StringVar(&author, "author", "CKeen", "Author name for copyright attribution")
rootCmd.AddCommand(version.VersionCmd)
}
func run(){
fmt.Println("go root cmd run")
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
我们在工程目录创建一个main.go,来调用上面的命令:
func main(){
cmd.Execute()
}
我们将代码编译为cobra的执行文件:
go build -o cobra
我们可以看到生成了一个cobra的可执行文件,然后我们来查看一下使用帮助:
$./cobra --help
我们可以看到控制台打印了如下信息:
cobra is a simple cli command tool
Usage:
cobra [string to action] [flags]
cobra [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
version app version
Flags:
--author string Author name for copyright attribution (default "YOUR NAME")
-h, --help help for cobra
Use "cobra [command] --help" for more information about a command.
对比以上我们可以内容,我们知道:
- Use的字段对应的内容为帮助中Usage的选项
- Short是对指令的使用的简短描述
- Long是对指令的使用的详细描述,这里我们可以看到执行./cobra --help第一行就答应的该描述信息
- AddCommand添加子命令。这里我们通过rootCmd的AddCommand将子命令添加进来,子命令在Available Commands部分进行展示,这里我们添加了一个查看version的命令
- PersistentFlags()解析参数选项。 这里我们使用rootCmd.PersistentFlags().StringVar(),函数来解析选项。这里我们可以看到StringVar函数可以绑定参数值,设置默认值,还支持描述信息。
我们在cmd/version的目录下来看下VersionCmd的代码:
var version string
var VersionCmd = &cobra.Command{
Use: "version",
Short: "app version",
Long: "print this app current version",
Example: "./cobra version",
Args: nil,
Version: "v1.0",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
log.Println("1. versionCmd PersistentPreRun")
},
PreRun: func(cmd *cobra.Command, args []string) {
log.Println("2. versionCmd PreRun")
},
Run: func(cmd *cobra.Command, args []string) {
log.Println("3. versionCmd Run")
},
PostRun: func(cmd *cobra.Command, args []string) {
log.Println("4. versionCmd PostRun")
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
log.Println("5. versionCmd PersistentPostRun")
},
}
func init(){
VersionCmd.PersistentFlags().StringVarP(&version, "v", "v", "v.10", "app version")
}
我们可以使用子命令的help来查看
$./cobra version --help
我们可以看到打印了如下部分:
print this app current version
Usage:
cobra version [flags]
Examples:
./cobra version
Flags:
-h, --help help for version
-v, --v string app version (default "v.10")
--version version for version
Global Flags:
--author string Author name for copyright attribution (default "YOUR NAME")
我们可以看到这里的描述跟rootCmd查不多,也是配置的那几个参数,这里我们多配置了一个Example示例,这个Example在help打印中也展示出来了。
同时这里可以看到还支持Global Flags,这个参数是我们在rootCmd中进行配置的,这里说明我们这里可以使用rootCmd的中的flag值。
5. cobra中command执行
首先我们执行一下上一节中编译的cobra的可执行文件,同时传入--author的flag选项
$./cobra --author CKeen
我们可以看到如下打印信息:
2022/07/10 01:01:41 1. rootCmd PersistentPreRun
2022/07/10 01:01:41 2. rootCmd PreRun
2022/07/10 01:01:41 3. rootCmd Run, auth:CKeen
go root cmd run
2022/07/10 01:01:41 4. rootCmd PostRun
2022/07/10 01:01:41 5. rootCmd PersistentPostRun
我们看到author选项设置了值,在rootCmd的Run方法中打印出来了,同时我们可以看到Command执行提供如下的回调执行顺序:
1. PersistentPreRun2. PreRun3.Run4.PostRun5.PersistentPostRun
我们一般将主要执行的业务逻辑放到Run中去执行,PreRun和PostRun可以做一些预处理的工作和执行后的清尾工作。
6.参考资料
cobra源码github: https://github.com/spf13/cobra
cobra的包介绍: https://pkg.go.dev/github.com/spf13/cobra