命令基本结构
cobra可以通过简洁的代码实现一个完善的命令行工具,其内置的函数足以应付大多数场景,下面学习一下cobra的用法。
在使用cobra之前要了解一个命令的基本结构,下面以npm i为例
npm i axios --save-dev
i: i就是command本身,在cobra下使用cobra.Command定义,一个command至少会包含User(命令本身),Short(简短描述),Long(完整描述),Run(命令执行时的函数)
axios:install命令的参数
–save-dev:install命令的flag,flag可以有各种各样的值,常见的是bool。
实现一个简易命令行工具
看完了命令的基本结构下面实现一个简单的命令行工具(这里不会包含具体的功能,只是演示cobra用法)
// 项目结构
.
├── go.mod
├── main.go
|
├── cmd
├── install.go
└── root.go
//main.go
package main
import "study/cmd"
func main() {
cmd.Execute()
}
main函数只需要执行cmd包的Execute方法,该方法内部会执行Command.Execute,这是command的核心执行函数。
// root.go
package cmd
import "github.com/spf13/cobra"
//定义npm命令
var rootCmd = &cobra.Command{
Use: "npm",
Short: "npm project",
Long: "npm project",
Run: func(cmd *cobra.Command, args[]string){
print("npm...")
},
}
func Execute(){
rootCmd.Execute()
}
rootCmd内包含一个npm命令,执行后会调用run方法打印一个string。
函数Execute就是对rootCmd.Execute的包装
此时npm命令已经是可用状态了,执行go build
go build -o npm.exe
npm.exe // npm...
使用arg和flag
然后添加一个install命令完善以下我们的npm
//install.go
package cmd
import (
"github.com/spf13/cobra"
"log"
)
//用来保存flag
var(
devFlag bool
)
//install命令
var installCmd = &cobra.Command{
Use: "install",
Short: "install package",
Long: "install npm package",
//arg就是install后面跟着的字符,比如npm i axios,axios就是arg
Run: func(cmd *cobra.Command, args []string){
if !devFlag {
log.Printf("install %s ...", args[0])
}else{
log.Printf("install %s as dev dependency", args[0])
}
},
}
func init(){
//AddCommand将install作为root的子命令
rootCmd.AddCommand(installCmd)
//定义flag,这里的flag是bool类型
installCmd.Flags().BoolVarP(&devFlag, "save-dev", "D", false, "install dev dependency")
}
在使用install命令后会执行Run方法,通过参数args可以拿到install后面的参数。在init内通过Flags().BoolVarP()定义了一个flag,该flag的值会被写入devFlag。
go build -o npm.exe
npm.exe install axios // install axios ...
npm.exe install axios --save-dev // install axios as dev dependency
npm.exe install axios -D // install axios as dev dependency
cobra包内的flag分类
在解释flag分类之前先看一下定义一个flag的常见参数(以BoolVarP为例)
- p *bool:保存该flagValue的内存地址
- name string:flag 名字,比如前面的save-dev
- shorthand string:name短格式,定义name后长格式使用–save-dev,短格式就是-D
- value bool:默认值,如果命令内没传入-D或者–save-dev该值为false
- usage string:解释该命令作用
是否使用指针接收value
函数名带有var的需要传入一个address接受value
testFlag := installCmd.Flags().Bool("test", false, "test") // 没有var,不需要传入bool类型的pointer,这里的testFlag是bool类型的pointer
installCmd.Flags().BoolVar(&devFlag, "save-dev", false, "install dev dependency") // 带有var需要使用address接受value
是否支持shortHand
testFlag := installCmd.Flags().BoolP("test", "T", false, "test") //后面带有P说明支持shortHand,可以使用--test或者-T
testFlag := installCmd.Flags().Bool("test", false, "test") //不支持shortHand
PersistentFlags
前面定义的flag只能给特定的命令使用(比如给installCmd定义的test),在cobra支持子命令的情况下如果可以给一组命令定义flag可以减少代码量的同时提高维护性,PersistentFlags可以实现此功能
//PersistentFlags
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
rootCmd定义PersistentFlags后该command的child command都可以使用该flag。