https://github.com/spf13/cobra
Kubernetes、Docker、etcd 等很多著名的项目使用 Cobra 构建其命令行接口。
概述
Cobra 库提供简单的接口来创建类似 git 和 go tools 的强大的现代命令行接口。
主要功能:
- 基于子命令的 CLI,如
app server
、app fetch
- 完全符合 POSIX 标准的参数标志(长短标志都支持)
- 嵌套的子命令
- 全局、本地和级联的参数标志
- 通过
cobra init appname
和cobra add cmdname
生成应用程序和命令 - 智能提示(app srver… did you mean app server?)
- 自动生成命令行和参数标志
- 自动识别
-h
,--help
等 - 为程序自动生成 bash 自动补全
- 为应用程序自动生成 man 手册
- 命令别名,便于无破坏地修改内容
- 灵活定义你的 help 、usage等
- 可选与viper紧密集成
命令行结构
一个好的命令行应该是类人言的。人们通过阅读命令行就可以理解如何使用应用程序。
命令行主要由四部分组成:
- APPNAME 应用名,主语
- Commands 命令,谓语
- Args 命令参数,宾语
- Flags 标志参数,设置命令的动作如何执行,定语/状语/补语
如:
git(主语) clone(谓语) URL(参数,宾语) --bear(参数,定语/状语/补语)
使用Cobra
建议的代码结构
▾ appName/
▾ cmd/
add.go
your.go
commands.go
here.go
main.go
安装包
go get -u github.com/spf13/cobra/cobra
使用标志参数(flags)
定义两个标志参数
var Verbose bool
var Source string
flags(标志参数)分为两类:
- 持久(全局)标志参数,对于一个命令的子命令也有效
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
- 局部标志参数,只对当前命令有效
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
建议从 main 函数执行 root 命令。
简单示例
文件结构
$ tree demo_cobra/
demo_cobra/
├── cmd
│ └── root.go
├── demo_cobra
└── main.go
main.go
package main
import (
"fmt"
"github.com/yourrepo/cmd"
"os"
)
func main() {
if err := cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
cmd/root.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"strings"
)
var (
verbose bool
rootCmd = &cobra.Command{
Use: "demo_cobra",
Short: "print flag parameters to screen",
Long: `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.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(strings.Join(args, " "))
},
}
cloneCmd = &cobra.Command{
Use: "clone [remote repo's url]",
Short: "clone remote repo",
Long: `clone copy a remote repository to your local storage`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Print("you are cloning ", args[0])
if verbose == true {
fmt.Println(" with verbose")
}
},
}
)
func Execute() error {
return rootCmd.Execute()
}
func init() {
cloneCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "whether output the detail information")
rootCmd.AddCommand(cloneCmd)
}
运行结果
$ go run main.go help clone
clone copy a remote repository to your local storage
Usage:
demo_cobra clone [remote repo's url] [flags]
Flags:
-h, --help help for clone
-v, --verbose whether output the detail information
$ go run main.go abc 123 haha
abc 123 haha
Cobra 还有可以为 Run 函数定义几个钩子函数
- PersistentPreRun
- PreRun
- Run
- PostRun
- PersistentPostRun
还可以与 Viper 集成绑定配置文件的设置值等,功能强大。