https://github.com/spf13/cobra
Kubernetes、Docker、etcd 等很多著名的項目使用 Cobra 構建其命令行接口。
概述
Cobra 庫提供簡單的接口來創建類似 git 和 go tools 的強大的現代命令行接口。
主要功能:
- 基於子命令的 CLI,如
app server
、app fetch
- 完全符合 POSIX 標準的參數標誌(長短標誌都支持)
- 嵌套的子命令
- 全局、本地和級聯的參數標誌
- 通過
cobra init appname
和cobra add cmdname
生成應用程序和命令 - 智能提示(app srver… did you mean app server?)
- 自動生成命令行和參數標誌
- 自動識別
-h
,--help
等 - 爲程序自動生成 bash 自動補全
- 爲應用程序自動生成 man 手冊
- 命令別名,便於無破壞地修改內容
- 靈活定義你的 help 、usage等
- 可選與viper緊密集成
命令行結構
一個好的命令行應該是類人言的。人們通過閱讀命令行就可以理解如何使用應用程序。
命令行主要由四部分組成:
- APPNAME 應用名,主語
- Commands 命令,謂語
- Args 命令參數,賓語
- Flags 標誌參數,設置命令的動作如何執行,定語/狀語/補語
如:
git(主語) clone(謂語) URL(參數,賓語) --bear(參數,定語/狀語/補語)
使用Cobra
建議的代碼結構
▾ appName/
▾ cmd/
add.go
your.go
commands.go
here.go
main.go
安裝包
go get -u github.com/spf13/cobra/cobra
使用標誌參數(flags)
定義兩個標誌參數
var Verbose bool
var Source string
flags(標誌參數)分爲兩類:
- 持久(全局)標誌參數,對於一個命令的子命令也有效
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
- 局部標誌參數,只對當前命令有效
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
建議從 main 函數執行 root 命令。
簡單示例
文件結構
$ tree demo_cobra/
demo_cobra/
├── cmd
│ └── root.go
├── demo_cobra
└── main.go
main.go
package main
import (
"fmt"
"github.com/yourrepo/cmd"
"os"
)
func main() {
if err := cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
cmd/root.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"strings"
)
var (
verbose bool
rootCmd = &cobra.Command{
Use: "demo_cobra",
Short: "print flag parameters to screen",
Long: `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.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(strings.Join(args, " "))
},
}
cloneCmd = &cobra.Command{
Use: "clone [remote repo's url]",
Short: "clone remote repo",
Long: `clone copy a remote repository to your local storage`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Print("you are cloning ", args[0])
if verbose == true {
fmt.Println(" with verbose")
}
},
}
)
func Execute() error {
return rootCmd.Execute()
}
func init() {
cloneCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "whether output the detail information")
rootCmd.AddCommand(cloneCmd)
}
運行結果
$ go run main.go help clone
clone copy a remote repository to your local storage
Usage:
demo_cobra clone [remote repo's url] [flags]
Flags:
-h, --help help for clone
-v, --verbose whether output the detail information
$ go run main.go abc 123 haha
abc 123 haha
Cobra 還有可以爲 Run 函數定義幾個鉤子函數
- PersistentPreRun
- PreRun
- Run
- PostRun
- PersistentPostRun
還可以與 Viper 集成綁定配置文件的設置值等,功能強大。