「GoCN酷Go推荐」​cobra 强大的cli命令工具

共 7252字,需浏览 15分钟

 ·

2021-08-29 06:28

1.cobra简介


cobra是目前最流行的命令行工具编写库,其友好的信息提示,简洁明了的嵌套层级,对命令行参数的便捷解析,让其成为众多优秀软件的cli编写库。

2.cobra安装

go get -v [github.com/spf13/cobra/cobra](http://github.com/spf13/cobra/cobra)

3.cobra 的命令

下面我们以一个例子来完成cobra的使用说明。此案例基于golang module 包管理机制之下。

3.1 cobra init demo1 —pkg-name demo

此命令创建一个名为demo1的文件夹生成带有根命令的目录结构及文件。其中包的引用结构的根节点为demo。

    .
    ├── cmd
    │   └── root.go
    ├── LICENSE
    └── main.go

3.2 go mod init demo

初始化模块对应上命令的—pkg-name值。此时命令行程序已经完整。go build即可生成可执行文件。

3.3 cobra add sub1添加一个sub1的子命令

 .
 ├── cmd
 │   ├── root.go
 │   └── sub1.go
 ├── demo
 ├── go.mod
 ├── go.sum
 ├── LICENSE
 └── main.go

可以看到cmd目录中增加了sub1.go的文件。重新生成可执行文件,验证子命令的成功添加。

    Usage:
      demo [command]

    Available Commands:
      completion  generate the autocompletion script for the specified shell
      help        Help about any command
      sub1        A brief description of your command

    Flags:
          --config string   config file (default is $HOME/.demo.yaml)
      -h, --help            help for demo
      -t, --toggle          Help message for toggle

4.参数,标识


参数

参数用来确定要运行的子命令,cobra工具自动生成文件只支持一级子命令。但是通过对cmd中代码分析我们发现通过修改cmd/xxx.go文件中的init函数我们可以做到多层级子命令。

func init() {
        rootCmd.AddCommand(sub1Cmd) // => xxxCmd.AddCommand(sub1Cmd)
}

例:./demo sub1 sub2的命令则需要修改sub2.go中init函数,sub1Cmd.AddCommand(sub2Cmd)。

标识

标识通常为命令的执行提供所需的配置和所需数值。

标识可以分为两类:一类是全局标识,另一类是局部标识。

全局标识的获取

globalstr = xxxCmd.PersistentFlags().String("foo","default","help of foo")
globalstrP = xxxCmd.PersistentFlags().StringP("foo","f","default","help of foo")
xxxCmd.PersistentFlags().StringVar("foo","default","help of foo")
xxxCmd.PersistentFlags().StringVarP(&str, "foo""f""""A help for foo")

可以看到获取参数的方法一共四种。

前两种会返回一个类型的指针,后两种会将获得的值存入传入的地址中。

第一种和第三种无法设置shorthand。

局部标识获取

局部标识仅仅当此命令运行时会去获取标识的值。

curstr = xxxCmd.Flags().String("foo","default","help of foo")
curstrP = xxxCmd.Flags().StringP("foo","f","default","help of foo")
xxxCmd.Flags().StringVar("foo","default","help of foo")
xxxCmd.Flags().StringVarP(&str, "foo""f""""A help for foo")

下面我们通过-h命令查看以上两种。

其中root.go文件中的init函数为

//root.go
func init(){
 rootCmd.PersistentFlags().StringVar(&cfgFile, "config""""config file (default is $HOME/.demo.yaml)")
 rootCmd.PersistentFlags().StringVarP(&rootfoo, "flag""f""xx""param")
 rootCmd.Flags().BoolP("toggle""t"false"Help message for toggle")
}

//./demo 
Available Commands:
  completion  generate the autocompletion script for the specified shell
  help        Help about any command
  test        A brief description of your command

Flags:
      --config string   config file (default is $HOME/.demo1.yaml)
  -f, --flag string     param (default "xx")
  -h, --help            help for demo
  -t, --toggle          Help message for toggle-h

test.go中init函数为

test.go
func init(){
 testCmd.Flags().String("testfoo""default""A help for foo")
 testCmd.Flags().StringP("testfoo2""t""defalut""A help for foo")
}

// ./demo test -h
Available Commands:
  test2       A brief description of your command

Flags:
  -h, --help              help for test
      --testfoo string    A help for foo (default "default")
  -t, --testfoo2 string   A help for foo (default "defalut")

Global Flags:
      --config string   config file (default is $HOME/.demo1.yaml)
  -f, --flag string     param (default "xx")

我们可以看出子命令./demo test 的帮助文档中存在两个全局标识,其中一个拥有shorthand。

5.命令执行体

这一部分比较简单,执行体就在cmd/xxx.go文件中xxxCmd结构体中的Run函数中。

var testCmd = &cobra.Command{
        Use:   "test",
        Short: "A brief description of your command",
        Long: `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.`
,
        Run: func(cmd *cobra.Command, args []string) {
                fmt.Println("test called", viper.GetString("hello"))
        },
}

总结

cobra库以树形结构的形式组织命令行,根据输入参数和配置项来组织对应的调用函数。使用步骤为:

  • cobra init 创建项目。
  • go init 创建module。
  • cobra add xxx 添加子命令。
  • 编写cmd/xxx.go中的init函数,组织树形命令结构。
  • 编写cmd/xxx.go文件的init函数,添加命令所需各类参数。
  • 编写cmd/xxx.go文件中的xxxCmd结构体,编辑命令说明信息及调用的Run函数。

参考资料


  • https://github.com/spf13/cobra

《酷Go推荐》招募:


各位Gopher同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到

新的库,并且知道怎么用。


大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名


扫码也可以加入 GoCN 的大家族哟~


浏览 25
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报