概述
cobra
庫是 golang 的一個開源第三方庫,能夠快速便捷的建立命令行應用程序。
優勢:cobra
可以快速建立CLI程序,使我們更專注於命令需要處理的具體的業務邏輯。
舉兩個例子:
hugo server --port=1313
git clone URL --bare
都是命令行程序。
基本概念
cobra由三部分構成:commands
,arguments
和 flags
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/
目錄下創建一個名為 demo
的 cobra
命令行應用程序
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