1. 程式人生 > 其它 >[Cobra]Go語言的命令列編寫工具的快速入門

[Cobra]Go語言的命令列編寫工具的快速入門

1.什麼是Cobra

cobra是一個用於建立強大現代CLI應用程式的庫,也是一個生成應用程式和命令檔案的程式。他可以實現對於命令列的使用和編寫。cobra被用在很多go語言的專案中,比如 Kubernetes(K8S)、Docker、Istio、ETCD、Hugo、Github CLI等等。 cobra提供
  • 簡單的基於子命令的命令列:app server、app fetch 等等
  • 完全符合POSIX的標誌(包含短版本和長版本)
  • 巢狀子命令
  • 全域性、本地和級聯的標誌
  • 使用 cobra init appname和cobra add cmdname 可以很容易生成應用程式和命令
  • 智慧提示(app srver... did you mean app server?)
  • 自動生成命令和標誌
  • 自動識別 -h --help 等等為help標誌
  • 為應用程式自動shell補全(bash、zsh、fish、powershell)
  • 為應用程式自動生成手冊
  • 命令別名
  • 靈活定義幫助、用法等等
  • 可選的與viper的緊密整合

2.cobra的基本概念

Cobra 結構由三部分組成:命令 (commands)、引數 (arguments)、標誌 (flags)。commands代表命令動作,args是事物物件,flags是動作的修飾符。

如下的例子,server 是command,port是flag

hugo server --port=1313

  這個命令中,我們告訴git 克隆url

git clone URL --bare

  cobra認為,一個好的命令要如同一個句子一樣符合語法以及直觀。

3.cobra的安裝和配置

  我們只需要

go get -u github.com/spf13/cobra

  就可以安裝cobra這個庫。接下來新建一個專案clia,在main.go中引入這個庫。

import "github.com/spf13/cobra"

  使用go mod tidy同步mod。

  我們使用命令自動初始化cobra這個專案。後面的--pkg-name是必填項,為專案命名。

  初始化完畢後,專案自動生成如下結構,包括一個根命令和在init的時候自定義的許可資訊等。

這個結構符合cobra的標準結構規範。

4.cobra的基本使用

4.1 命令引數

4.1.1 根命令引數

  初始生成的根命令如上圖所示,命令會以一個變數的形式定義,如上圖的根命令的名字是rootCmd,他給我們定義了use(呼叫command),short(短幫助資訊),long(長幫助資訊)等引數。我們可以go build clia,然後輸入.\clia命令檢視效果。

會返回Long 長幫助資訊。

4.1.2 子命令引數

  我們給出一個子命令的情況。

var testCmd = &cobra.Command{
	Use:   "test",
	Short: "短幫助資訊",
	Long: `長幫助資訊`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("test called")
	},
}

func init() {
	versionCmd.AddCommand(testCmd)
}

  可以看到,比之根命令,子命令多了一個run函式,他接受2個引數,第一個是命令引數,第二個是一個字串陣列。第一個引數傳入的是這個變數的整體資訊,第二個傳入的是從命令列接受的資料。

  我們對第二個引數進行測試,我們使用test子命令,在run函式作如下定義:

var testCmd = &cobra.Command{
	Use:   "test",
	Short: "短幫助資訊",
	Long: `長幫助資訊`,
	Run: func(cmd *cobra.Command, args []string) {
		res:=0
		for _,v := range args{
			temp,err := strconv.Atoi(v)
			if err !=nil{
				fmt.Println(err)
			}else{
				res +=temp
			}
		}
		fmt.Println(res)
	},
}

  實際是把輸入的字串轉為整型,進行累加返回總和,呼叫測試

4.2 新增子命令

  我們可以通過指令cobra add [name]來讓cobra幫我們自動生成一個子命令

  比如我們生成一個檢視版本的子命令

cobra add version

  會在cmd資料夾下生成一個version.go,我們修改其配置

  重新build後,輸入.\clia

可以看到多了一個命令,version 短幫助資訊為"版本資訊"

  我們輸入命令 ./clia version

可以看到定義的上面run函式呼叫函式fmt.println()的結果。

4.3 將子命令繫結到父命令

  在上文建立子命令的時候,我們會看到cobra會幫我們實現繫結的功能,

  可以看見init函式中的AddCommand()函式幫我們實現了將versionCmd變數繫結到rootCmd變數的功能。

  我們可以為version子命令再繫結一個子命令 我們新增test子命令

修改test.go中的init函式,,為versionCmd變數新增子命令。

進行測試,可以發現實現了version的子命令。

4.4 使用Flags為命令新增一個選項

  標誌提供修飾符來控制操作命令的操作方式,我們為version定義一個flag。

  在version.go中我們在init函式中定義一個flag,新增一個獲取String型別的選項。也可以獲取布林,整型,ip地址等型別的資料。

versionCmd.Flags().StringP("author","a","測試一號","幫助資訊:作者名稱")

  第一個引數是flag的名字,第二個引數是其簡稱,可以通過-author使用,也可以通過-a使用,第三個是預設的選項資訊,第四個是幫助資訊

  我們修改verisionCmd的程式碼

var versionCmd = &cobra.Command{
	Use:   "version",
	Short: "版本資訊",
	Long: `這是關於版本的長的幫助資訊`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("version-0.0.1")
		author,err:=cmd.Flags().GetString("author")
		if err !=nil{
			fmt.Println("請輸入正確的作者資訊")
			return
		}
		fmt.Println("作者是:",author)
	},
}

  使得輸出版本資訊的時候會預設輸出一個作者的資訊,這個作者的資訊預設是測試一號,我們可以通過flag進行修改

  預設情況

  通過flag修改

  標誌可以使用持久化定義,讓他在全域性呼叫

  需要在外部var宣告這個變數,傳入這個變數的地址。

rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

  這裡就獲取了一個布林型的值,賦值給Verbose,名字是verbose,指令是v,預設false,幫助資訊是verbose output。

  可以把flag設定為必填項

rootCmd.MarkFlagRequired("verbose")

cobra官方文件參考:https://github.com/spf13/cobra