[golang] 15, cobra cli command line library


Cobra is the most popular command-line library for golang, see the documentation

1. Scaffolding

mkdir pt && cd pt && go mod init
cobra-cli init # 在项目下运行即可生成脚手架

# tree
.
├── LICENSE
├── cmd # 生成了cmd目录
│   └── root.go # 生成了root.go, 其中定义了rootCmt变量
├── go.mod
├── go.sum
└── main.go

# go run main.go
Usage:
  pt [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  show        Display current time

Flags:
  -h, --help     help for pt
  -t, --toggle   Help message for toggle

2. Child instruction

# cobra-cli add show # 添加名为show的子命令, 则会自动生成cmd/show.go代码

# go run main.go show # 执行名为show的子命令
2023-08-28 22:00:58.263991 +0800 CST m=+0.000923251

# go run main.go show -h # 获取名为show的子命令的帮助信息
will display like 2023-08-28 22:00:58.263991 +0800 CST m=+0.000923251

Usage:
  pt show [flags]

Flags:
  -h, --help   help for show

Three, flag parameter

3.1 Definition

// 添加参数
func init() {
    
    
	rootCmd.AddCommand(proto2jsonCmd)
	proto2jsonCmd.Flags().StringP("content", "c", "", "byte content of a.proto")
	proto2jsonCmd.Flags().StringP("filepath", "f", "", "filepath of proto file")
}

// 输出如下:
with a.proto protocol

Usage:
  pt p2j [flags]

Flags:
  -c, --content string    byte content of a.proto
  -f, --filepath string   filepath of proto file
  -h, --help              help for p2j

3.2 use

If you need to use a global flag or a local flag, you need to define a variable in the appropriate scope to store the flag value, so that the flag can take effect in a specific scope.

3.2.1 Using global flags

To make a flag effective for all commands, you need to create a variable in the root.go file to store the flag value.

If you need to define a global flag name:

// 在root.go 文件中添加一个变量name
var name string
 
// 在init函数中添加全局flag,将flag值存储到变量name中
rootCmd.PersistentFlags().StringVar(&name, "name", "", "set name")
 
// 在子命令version的Run方法中输出name  
Run: func(cmd *cobra.Command, args []string) {
    
      
    fmt.Println("name is: ", name)
}
 
// 执行命令  
./demo version --name a
输出:
name is:  a

3.2 Using local flags

To make a flag effective for a certain command, a variable needs to be created in the command file to store the flag value.

If you need to define a local flag name for the version command:

// 定义变量content  
var content string
 
// 在version.go的init函数中添加flag  
versionCmd.Flags().StringVarP(&content, "content", "s", "false", "you are my sunshine")
 
// 在子命令version.go的Run方法中输出  
Run: func(cmd *cobra.Command, args []string) {
    
      
    fmt.Println("name is: ", name)
    fmt.Println("content is: ", content)
}
 
// 执行命令  
./demo version --name a --content b
输出:
name is:  a
content is:  b  

3.3 cmd can only access the flag value defined by itself

Note: If flags are stored in local variables, then other commands "cannot" use the local flag of a command. Although the local flag is defined in a command file as a local variable, other files under the cmd folder can access this variable, but if other commands do not define their own local flags to obtain the same flag value, the obtained value is the The zero value of a local variable. Examples are as follows:

// 1. 添加一个新命令helloworld  
> cobra add helloworld
 
// 2.输出content值  
Run: func(cmd *cobra.Command, args []string) {
    
      
    fmt.Println("content is: ", sunshine)
}

// 3.执行命令  
> ./demo helloworld --content b
Error: unknown flag: --content  // 输出错误未知flag, 原因就是该命令并未定义名为content的局部flag

3.4 required flag

// init文件中增加flag定义  
versionCmd.Flags().StringVarP(&sunshine, "content", "c", "", "my content")  
versionCmd.MarkFlagRequired("content")
 
// 执行  
> ./demo version
 
// 输出  
Error: required flag(s) "content" not set // 说明必须要设置flag content
 
// 传入content flag  
> ./demo version --content b // 输出: content is:  b

3.5 Global flag configuration

MinimumNArgs(int) 当参数数目低于配置的最小参数个数时报错  
MaximumNArgs(int) 当参数数目大于配置的最大参数个数时报错  
ExactArgs(int)    如果参数数目不是配置的参数个数时报错  
NoArgs            没有参数则报错  

Examples are as follows:

// 添加一个命令path  
> cobra add path
 
// 设置该命令需要且仅需要一个参数,并在Run方法中取出参数  
var pathCmd = &cobra.Command{
    
      
    Use:   "path [path]",
    Short: "A brief description of your command",
    Long: "",  
    Args: cobra.ExactArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
    
    
        fmt.Println("path called")
        fmt.Println("path:", args[0])
    },
}
 
// 执行命令并输出  
> ./demo path /home // 输出path: /home  

Guess you like

Origin blog.csdn.net/jiaoyangwm/article/details/132548793