go cobra實例講解


概述

cobra 庫是 golang 的一個開源第三方庫,能夠快速便捷的建立命令行應用程序。

優勢:cobra 可以快速建立CLI程序,使我們更專注於命令需要處理的具體的業務邏輯。

舉兩個例子:

hugo server --port=1313
git clone URL --bare

都是命令行程序。

基本概念

cobra由三部分構成:commandsargumentsflags

commands:表示要執行的動作。每一個 command 表示應用程序的一個動作。每個命令可以包含子命令。

arguments:給動作傳入的參數。

flags:表示動作的行為。可以設置執行動作的行為。flags 包括兩種:對某個命令生效和對所有命令生效。

安裝方法

go get -u github.com/spf13/cobra/cobra

github地址:https://github.com/spf13/cobra

使用方法

1.創建cobra命令行應用程序

cobra init code.byted.org/dfic/demo

$GOPATH/src/code.byted.org.dfic/ 目錄下創建一個名為 democobra 命令行應用程序

main.go 文件,完成初始化 cobra 功能。

第一次初始化可能會出現這個問題 Error: required flag(s) "pkg-name" not set 解決辦法

package main
 
import "code.byted.org/dfic/demo/cmd"
 
func main() {  
    cmd.Execute()
}

2.添加命令

2.1.基本用法

cobra add version

cmd 文件夾下生成一個新的文件 version.go,定義這個新的命令的動作。

文件內容如下:

import (  
    "fmt"
 
    "github.com/spf13/cobra"
)
 
// versionCmd represents the version command
var versionCmd = &cobra.Command{  
    Use:   "version",
    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("version called")
    },
}
 
func init() {  
    rootCmd.AddCommand(versionCmd)
 
    // Here you will define your flags and configuration settings.
 
    // Cobra supports Persistent Flags which will work for this command
    // and all subcommands, e.g.:
    // versionCmd.PersistentFlags().String("foo", "", "A help for foo")
 
    // Cobra supports local flags which will only run when this command
    // is called directly, e.g.:
    // versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

編譯運行

> go build -o demo
 
> ./demo -h
 
Usage:  
  demo [command]
 
Available Commands:  
  help        Help about any command
  version     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
 
執行新添加的命令
> ./demo version
輸出:version called

2.2.修改命令行為

將命令的行為添加到命令結構Run參數對應的方法中

var versionCmd = &cobra.Command{  
    Use:   "version",
    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("version called")
    },
}

3.添加flag

3.1.添加局部flag

在 version.go 文件的 init 函數中添加 局部flag

func init() {  
    rootCmd.AddCommand(versionCmd)
    versionCmd.Flags().BoolP("test", "t", false, "test")
}

執行命令

> ./demo version -h
 
Usage:  
  demo version [flags]
 
Flags:  
  -h, --help   help for version
  -t, --test   test
 
Global Flags:  
      --config string   config file (default is $HOME/.demo.yaml)

4. flag賦值

如果需要使用 全局flag 或者 局部flag,需要在合適的作用域內定義變量存儲 flag 值,以便 flag 可在特定作用域內生效。

4.1.使用全局flag

讓一個 flag 對所有命令生效,需要在 root.go 文件中創建一個變量存儲 flag 值。

如需要定義一個全局flag name:

1.在root.go 文件中添加一個變量name
 
var name string
 
2.在init函數中添加全局flag,將flag值存儲到變量name中
 
rootCmd.PersistentFlags().StringVar(&name, "name", "", "set name")
 
 
3.在子命令version的Run方法中輸出name  
Run: func(cmd *cobra.Command, args []string) {  
    fmt.Println("name is: ", name)
}
 
 
4.執行命令  
./demo version --name wfl
輸出:
name is:  wfl  

4.2.使用局部flag

讓一個 flag 對某個命令生效,需要在該命令文件中創建一個變量存儲 flag 值。

如需要給version命令定義一個局部flag name:

1.定義變量sunsine  
var sunshine string
 
 
2.在version.go的init函數中添加flag  
versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "false", "you are my sunshine")
 
 
3.在子命令version.go的Run方法中輸出  
Run: func(cmd *cobra.Command, args []string) {  
    fmt.Println("name is: ", name)
    fmt.Println("sunshine is: ", sunshine)
}
 
 
4.執行命令  
./demo version --name wfl --sunshine wfl
輸出:
name is:  wfl  
sunshine is:  wfl  

問題:

flags 存儲到本地變量當中,那么其他命令是不是也可以用某個命令的 局部flag 呢?

答:不可以。局部flag雖然是定義在某個命令文件中作為局部變量,cmd 文件夾下的其他文件可以訪問這個變量,但是其他命令如果沒有定義自己的 局部flag 獲取相同 flag 值的話,獲取到的值是該局部變量的零值。

1.添加一個新命令helloworld  
> cobra add helloworld
 
 
2.輸出sunshine值  
Run: func(cmd *cobra.Command, args []string) {  
    fmt.Println("sunshine is: ", sunshine)
}
 
 
3.執行命令  
> ./demo helloworld --sunshine wfl
Error: unknown flag: --sunshine  
輸出錯誤未知flag。
原因就是該命令並未定義局部flagsunshine

4.3.必填flag

默認情況下,flag是optional(選填),若flag為必填,則需要做如下設置

如將version命令下的sunshine flag設置為必填

1.init文件中增加flag定義  
versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "", "you are my sunshine")  
versionCmd.MarkFlagRequired("sunshine")
 
2.執行  
> ./demo version
 
3.輸出  
Error: required flag(s) "sunshine" not set  
說明必須要設置flag sunshine
 
4.傳入sunshineflag  
> ./demo version --sunshine wfl
輸出: sunshine is:  wfl

5. 嵌套子命令

cobra 的命令行工具可以創建嵌套子命令。使用 cobra add -p "父命令Cmd"。

比如

1.給version命令添加一個子命令show  
> cobra add show -p "versionCmd"
 
 
2.在cobra生成的show.go文件的init方法中,自動將showCmd添加到versionCmd下作為子命令  
func init() {  
    versionCmd.AddCommand(showCmd)
}
 
 
3.執行嵌套子命令  
> ./demo version show
show called  

6. 獲取命令行參數值

cobra 常用的參數配置校驗器如下:

MinimumNArgs(int) 當參數數目低於配置的最小參數個數時報錯  
MaximumNArgs(int) 當參數數目大於配置的最大參數個數時報錯  
ExactArgs(int)    如果參數數目不是配置的參數個數時報錯  
NoArgs            沒有參數則報錯  

類似 git clone URL 這種類型的命令行,URL 為傳給 clone 命令的參數

獲取URL的值,可以從 args 參數中直接取出

舉例:

1.添加一個命令path  
> cobra add path
 
2.設置該命令需要且僅需要一個參數,並在Run方法中取出參數  
var pathCmd = &cobra.Command{  
    Use:   "path [path]",
    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.`,  
    Args: cobra.ExactArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("path called")
        fmt.Println("path:", args[0])
    },
}
 
3. 執行命令並輸出  
> ./demo path /home
path: /home  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM