一、简介
Cobra 是一个流行的命令行库,它用于创建命令行应用程序,是用 Go 语言编写并广泛被用于各种 Go 项目中。Cobra 既是一个用于创建命令行接口(CLI)的库,也是一个生成应用程序和命令文件的程序。笔者选择了解这个框架有两方面的原因,一方面是笔者在为命令行工具的开发进行技术选型,另一方面是因为笔者在k8s的源码阅读过程中,发现在k8s中广泛应用了该框架进行开发。官方文档非常健全,文档中给出的代码用例对于cobra的使用方式介绍的也很很全面,下面给出比较关键的文档链接方便各位持续关注并了解这项技术。本文的行文思路是在官方文档的基础之上,添加自己使用的心得体会和实践过程,类似于给文档加注的形式,期望能够帮助大家快速上手该项技术。
官方Github主页:https://github.com/spf13/cobra
cobra框架用户指南:https://github.com/spf13/cobra/blob/main/site/content/user_guide.md
脚手架生成工具:https://github.com/spf13/cobra-cli/blob/main/README.md
二、命令行开发基础知识
在开始学习框架之前,各位应该对命令行的语法格式有一个基础的了解,一条命令行指令往往包含以下几个组成成分(不同文章可能对于组成成分的分类方式有微小的差别):
- command:命令
- subcommmand: 子命令
- flag: 标识
- args:参数
以k8s的kubectl命令为例,我们可以清晰的识别命令行指令中的不同的组成成分:
上述组成成分除了command外都是可选的,命令的不同组成部分可以丰富命令行指令表达的信息,也方便对于指令描述的信息进行分组识别和解析。关于flag的特殊解析模式,–help 和 -h 两者对于同一条命令行指令而言是相同的flag,紧跟在其后的数据会被解析成类似于map的数据结构,map的key就是flag的名称,map的value就是紧跟在flag后的相关数据。
至此,大家对于命令行应该有了基础的了解,如果想深入学习命令行的详细设计规范,可以参考文章https://clig.dev/
三、实验环境描述
golang版本:1.20.4
操作系统:centos7
四、cobra的安装
#cobra框架的安装
go get -u github.com/spf13/cobra@latest
#cobra-cli工具安装
go install github.com/spf13/cobra-cli@latest
#ps 如果出现连接超时等异常,可以重复执行几遍
注意,请首先执行章节五中step1和step2后再执行cobra的安装
命令执行结果如下图所示:
五、cobra-cli 脚手架生成工具
cobra-cli是cobra框架脚手架生成工具,通过该程序可以快捷的搭建工程、添加指令。下面描述一下这个脚手架工具的具体用法。
- step1: 创建工程目录,一般都放在gopath下的src目录下
mkdir -p $GOPATH/src/cli-demo
cd $GOPATH/src/cli-demo
- step2: 初始化go mod
go mod init cli-demo
- step3: 可以初始化一个cobra的脚手架工程了
cobra-cli init
注意: 笔者曾遇到报错bash: cobra-cli: 未找到命令,解决方案如下
cp $GOPATH/bin/cobra-cli /usr/local/bin
附上cobra-cli自带的flags,读者可自行添加以下flag来达到一些自定义的效果,下文中的-h是命令行默认flag,意思是展示当前命令的帮助信息,它可以展示当前命令下可用的args、flag和子命令信息。
[root@master ~]# cobra-cli -h
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-cli [command]
Available Commands:
add Add a command to a Cobra Application
completion Generate the autocompletion script for the specified shell
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-cli
-l, --license string name of license for the project
--viper use Viper for configuration
当执行完上述指令后,会在当前目录下生成脚手架代码,其中,/cmd文件夹下方放置的是各级命令的代码。main.go是程序入口。
├── cmd
│ └── root.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go
- step5: 现在我们可以执行main函数了
[root@master cli-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.
- step6:添加命令。cobra-cli的add指令可以添加命令
cobra-cli add serve
cobra-cli add config
cobra-cli add create -p 'configCmd'
#该步骤是为命令config添加一个子命令create,
默认情况下,cobra-cli将附加Cmd到提供的父级名称并使用该聚合的名称作为内部变量名称。指定父级时,请确保与代码中使用的变量名称匹配。
//这里展示了config命令在代码中对应位置,我们可以看出config命令对应的变量名是configCmd
// 代码路径cmd/config.go
var configCmd = &cobra.Command{
.....
}
上述命令执行完毕后可以发现工程目录结构发生了变化
.
├── cmd
│ ├── config.go
│ ├── create.go
│ ├── root.go
│ └── serve.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go
我们来依次验证上面定义的命令,下文中的-h是命令行默认flag,意思是展示当前命令的帮助信息,它可以展示当前命令下可用的args、flag和子命令信息。
[root@master cli-demo]# go run main.go config
config called
[root@master cli-demo]# go run main.go serve
serve called
[root@master cli-demo]# go run main.go config -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:
cli-demo config [flags]
cli-demo config [command]
Available Commands:
create A brief description of your command #这里展示子命令信息
Flags:
-h, --help help for config
Global Flags:
--config string config file (default is $HOME/.cli-demo.yaml)
Use "cli-demo config [command] --help" for more information about a command.
[root@master cli-demo]# go run main.go config create
create called
至此,一个基础cobra框架就已经搭建完毕。
- step7: 对于企业开发过程中,可能需要在代码开头添加一些版权信息,还记得前文中cobra-cli init指令中的–config flag吗,这个指令可以指向一个cobra-cli的配置文件(默认路径是~/…cobra.yaml)。其实本质上,使用配置文件和使用cobra-cli init指令后附加上–author,–licnese的效果是一致。
author: Steve Francia <spf@spf13.com>
year: 2020
license:
header: This file is part of CLI application foo.
text: |
{{ .copyright }}
This is my license. There are many like it, but this one is mine.
My license is my best friend. It is my life. I must master it as I must
master my life.
首先,我们先将上文步骤生成的cobra脚手架内容清空,将上述配置文件内容保存在一个cobra.yaml文件,当前目录结构如下:
├── cobra.yaml
├── go.mod
└── go.sum
执行cobra-cli init --config ./cobra.yaml,即可生成一个定制化的cobra脚手架,生成完毕后的目录结构如下:
├── cmd
│ └── root.go
├── cobra.yaml
├── go.mod
├── go.sum
├── LICENSE
└── main.go
其中,license文件内容如下:
Copyright © 2020 Steve Francia <spf@spf13.com>
This is my license. There are many like it, but this one is mine.
My license is my best friend. It is my life. I must master it as I must
master my life.
在每一个.go代码的header头,添加了自定义的copyright内容:
/*
Copyright © 2020 Steve Francia <spf@spf13.com>
This file is part of CLI application foo.
*/
未完待续…