Golang现代命令行应用框架Cobra
   
本文介绍强大的命令行应用框架Cobra,让我们专注业务快速搭建强大的命令行应用。
    
    
    1. 认识Cobra
   
Cobra是非常便利和流行的Golang包,用于开发强大命令行应用,包括命令、子命令、配置文件等。如果你了解docker的常用命令,你大概能理解Cobra的强大功能,docker就是使用Cobra作为其基础。
Cobra作为命令行应用框架,其强大功能还包括生成代码模板,让你只需关注业务实现。
    
    
    1.1 安装Cobra
   
go get github.com/spf13/cobra/cobra
    上面命令即在
    
     gopath/bin
    
    目录下下载
    
     cobra.exe
    
    文件。这时可以使用cobra名称初始化项目,然后创建命令或子命令,最后你对生成的命令模板文件进行修改加入必要的业务逻辑。
   
cobra init xapp --pkg-name xapp
上述命令即初始化项目xapp应用。其生成xapp目录并包括下列文件:
.
├── LICENSE
├── cmd
│   └── root.go
└── main.go
    如果不需要licence,可以在上面命令后面加上标记
    
     cobra init xapp --pkg-name xapp -l none
    
    .
   
    
    
    1.2 增加依赖管理
   
    打开上面生成的项目,默认需要一些依赖,这里使用mod作为依赖管理工具。在xapp目录下执行命令:
    
     go mod init
    
    ,执行后在当前目录下生成go.mod文件。
   
    下面进行
    
     go build
    
    ,会自动下载相关依赖。
   
    
    
    1.3 cobra命令
   
- 增加命令
cobra add 命令名称 -p -l
增加命令, -p 指定父命令,不指定默认增加至根命令。-l 指定 license 字符串
作为约定命令名称一般使用动词。
    
    
    2. 示例
   
我们先增加一个say 命令,可以实现问候功能。
    
     cobra add say -l none
    
打开生成的文件say.go,我们看到默认命令实现:
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("say called")
	},
在init函数中把该命令增加至rootCmd:
func init() {
	rootCmd.AddCommand(sayCmd)
}
下面我们实现其功能:
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 1 {
			fmt.Println("Hello World!")
		}else {
			for _,item := range args{
				fmt.Println("Hello", item, "!")
			}
		}
	},
    编译并运行:
    
     xapp say
    
    ,带上参数
    
     xapp say tom
    
    , 分别输出Hello World! 和 Hello tom!
   
    
    
    2.1 增加标识
   
    假设我们要给say命令增加标识 -n 标识问候人名称。
    
    修改init函数,在原
    
     rootCmd.AddCommand(sayCmd)
    
    行后面增加标识注册:
   
	rootCmd.AddCommand(sayCmd)
	sayCmd.Flags().StringP("name", "n", "", "Set your name")
上面设置了name标识,可以使用–name 或 -n 后面跟上参数,下面修改命令实现代码并解析name标识:
	Run: func(cmd *cobra.Command, args []string) {
		name, _:= cmd.Flags().GetString("name")
		if name == "" {
			name = "World"
		}
		fmt.Println("Hello " + name)
	},
编译测试:
xapp say hello -n jack
会输出“Hello jack”
    
    
    2.2 使用环境变量作为缺省值
   
如果敏感数据不想显示在历史中,我们可以使用环境变量。这里使用Viper包,Cobra在生成的代码中已经依赖了Viper,Viper可以获取配置文件和环境的值。
下面代码使用环境变量作为缺省值,修改init函数代码:
func init() {
	rootCmd.AddCommand(sayCmd)
	sayCmd.Flags().StringP("name", "n", viper.GetString("ENVNAME"), "Set your name")
}
    
    
    2.3 使用配置文件
   
    如果命令行应用需要提供很多参数,通过标识逐个提供非常不方便,这时可以使用配置文件。
    
    下面示例我们定义扩展名为
    
     .yaml
    
    文件,并设置参数:
   
name: "Golang"
greeting: "Howdy"
    我们前面的命令是通过cobra生成,其已经包括配置文件选项。在
    
     root.go
    
    的
    
     initConfig()
    
    方法里我们能看到Viper负责实现该功能。
   
真是好消息,我们不需要自己实现,仅需要在命令中处理配置文件相关参数值:
    
     Run: func(cmd *cobra.Command, args []string) { greeting := "Hello" name, _ := cmd.Flags().GetString("name") if name == "" { name = "World" } if viper.GetString("name")!=""{ name = viper.GetString("name") } if viper.GetString("greeting")!=""{ greeting = viper.GetString("greeting") } fmt.Println(greeting + " " + name) },
    
编译并测试:
xapp say hello --config config.yml
输出结果: Howdy Golang
    
    
    3. 总结
   
本文介绍了Cobra框架,用于快速开发现代命令行应用。可以自动生成命令框架代码,支持命令、子命令、标识以及配置文件。
 
