「Go 推薦」​cobra 強大的 cli 命令工具

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 庫以樹形結構的形式組織命令行,根據輸入參數和配置項來組織對應的調用函數。使用步驟爲:

參考資料

《酷 Go 推薦》招募:

各位 Gopher 同學,最近我們社區打算推出一個類似 GoCN 每日新聞的新欄目《酷 Go 推薦》,主要是每週推薦一個庫或者好的項目,然後寫一點這個庫使用方法或者優點之類的,這樣可以真正的幫助到大家能夠學習到

新的庫,並且知道怎麼用。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/fW2XBXDA9t89oCjjDKaGwA