Go-Cobra-库的使用

Github Cobra 地址

下载和调用

安装 lib:

1
go get -u github.com/spf13/cobra@latest

调用:

1
import "github.com/spf13/cobra"

安装 cli 工具:

1
go install github.com/spf13/cobra-cli@latest

其会安装在 $GOPATH/bin 之下.

cobra-cli 使用(不作为 Go lib 使用)

Github 文档

配合创建一个 go module 使用 (不添加 flag 的基础使用):

1
2
3
4
5
mkdir myapp
cd myapp
go mod init myapp
cobra-cli init
go run main.go

可以添加 --author, --license, --viper 等 flag, 如:

1
cobra-cli init --author "Your Name" --license apache --viper

添加子命令 cobra-cli add

如当前 application 的命令是 app, 想要有:

  • app server
  • app config
  • app config create

注意这些命令需要遵循 “camelCase” 命名法.

这些子命令, 则可以:

1
2
3
cobra-cli add serve
cobra-cli add config
cobra-cli add create -p 'configCmd'

(cobra-cli add 也有同 init 的 flag)

-p 指定 “parent” command, 默认为 rootCmd.

此时的目录结构应为:

1
2
3
4
5
6
7
▾ app/
▾ cmd/
config.go
create.go
serve.go
root.go
main.go

配置 cobra generator

~/.cobra.yaml 文件的示例:

1
2
3
author: Steve Francia <spf@spf13.com>
license: MIT
useViper: true

Cobra Lib 使用

Github 文档

创建命令, 其实就是创建 xxxCmd 变量的过程. 一般需要设置

  • Use: string, 调用时的命令
  • Short: string
  • Long: string, 调用 xxx --help 时先出现的描述文本
  • Args: func(cmd *cobra.Command, args []string) error
  • Run: func(cmd *cobra.Command, args []string)
  • RunE: func(cmd *cobra.Command, args []string) error
    这几个键值对.

xxxCmd 变量可以通过自带的 Execute() 方法调用命令.

通过其 Flags() 方法可以添加 flags.

通过其 AddCommand() 方法可以添加子命令.

目录树为:

1
2
3
4
5
6
7
8
▾ appName/
▾ cmd/
add.go
your.go
commands.go
here.go
root.go
main.go

main.go 文件内容一般为:

1
2
3
4
5
6
7
8
9
package main

import (
"{pathToYourApp}/cmd"
)

func main() {
cmd.Execute()
}

{pathToYourApp} 其实就是指 go mod init name 中指定的名称.

cobra-cli add 添加的都会放在 cmd 目录下, 统一为 cmd package 名.

因此这个 main.go 文件就是运行 root.go 文件中定义的 Execute 函数.

可以用 cobra-cli 命令来创建 root.go 等, 也可以手动创建, 内容如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var rootCmd = &cobra.Command{
Use: "hugo",
Short: "Hugo is a very fast static site generator",
Long: `A Fast and Flexible Static Site Generator built with
love by spf13 and friends in Go.
Complete documentation is available at https://gohugo.io/documentation/`,
Run: func(cmd *cobra.Command, args []string) {
// Do Stuff Here
},
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

添加子命令

若添加 hello, 则创建 cmd/hello.go 文件, 并写入如;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(helloCmd)
}

var helloCmd = &cobra.Command{
Use: "hello",
Short: "hello short",
Long: `hello long`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("hello")
},
}

这是一个模板, 都需要有 init 这个函数(应该是会被自动调用), 以及 xxxxCmd 这个变量.

这里主要就是用 AddCommand 添加子命令.

错误处理

添加 RunE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

func init() {
rootCmd.AddCommand(tryCmd)
}

var tryCmd = &cobra.Command{
Use: "try",
Short: "Try and possibly fail at something",
RunE: func(cmd *cobra.Command, args []string) error {
if err := someFunc(); err != nil {
return err
}
return nil
},
}

添加 flags

Flags 分:

  • Persistent Flags, 子命令同样可以用
  • Local Flags, 当前命令使用

如给 rootCmd 添加 Persistent flag, 且为 Bool 类型, 如:

1
2
var Verbose bool
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

解释 BoolVarP 的几个参数:

  • &Verbose, 表明从命令行获取到的参数保存到这个变量中
  • verbose 为 long
  • v 为 short
  • false 为初始值
  • verbose output 为 help 打印的信息

localCmd 添加 Local flag, 且为 String 类型, 如:

1
2
var Source string
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")

Required flags

即必须附带上的 flag:

1
2
rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
rootCmd.MarkFlagRequired("region")

Flag Groups

即多个 flag 必须一起使用(或不能一起使用)才行.

需一起使用如:

1
2
3
rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
rootCmd.MarkFlagsRequiredTogether("username", "password")

不能一起使用如:

1
2
3
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")

其中一个 persistent:

1
2
3
4
rootCmd.Flags().BoolVar(&ofJson, "json", false, "Output in JSON")
rootCmd.Flags().BoolVar(&ofYaml, "yaml", false, "Output in YAML")
rootCmd.MarkFlagsOneRequired("json", "yaml")
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")

Positional and Custom Arguments

都在 Args 之下设置.

参数数量设置:

  • NoArgs
  • ArbitraryArgs
  • MinimumNArgs(int)
  • MaximumNArgs(int)
  • ExactArgs(int)
  • RangeArgs(min, max)

参数的内容:

  • OnlyValidArgs

如:

1
2
3
4
5
6
7
8
9
10
var cmdPrint = &cobra.Command{
Use: "print [string to print]",
Short: "Print anything to the screen",
Long: `print is for printing anything back to the screen.
For many years people have printed back to the screen.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Print: " + strings.Join(args, " "))
},
}

示例:

1
2
3
4
5
6
7
var cmd = &cobra.Command{
Short: "hello",
Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, World!")
},
}

另一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var cmd = &cobra.Command{
Short: "hello",
Args: func(cmd *cobra.Command, args []string) error {
// Optionally run one of the validators provided by cobra
if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {
return err
}
// Run the custom validation logic
if myapp.IsValidColor(args[0]) {
return nil
}
return fmt.Errorf("invalid color specified: %s", args[0])
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello, World!")
},
}

Help command

Cobra 会自动为 sub-command 添加 help (文本自己加, 即 Short 定义的部分).

如此时的命令为 test, 有一个 sub-command 为 hello, 则存在:

1
2
test --help
test hello --help

(也可以用 -h)

Usage Message

Cobra 自动提供有. 在使用未定义的 flag 时会触发.

也可以自定义.

1
2
cmd.SetUsageFunc(f func(*Command) error)
cmd.SetUsageTemplate(s string)

Version Flag

--version 的输出, 用:

1
cmd.SetVersionTemplate(s string)

来设置.

Error Message Prefix

报错时的前缀, 默认为:

1
Error:

可以用:

1
cmd.SetErrPrefix(s string)

修改.

PreRun and PostRun Hooks

即运行在 Run 之前或者之后. 顺序如下:

  • PersistentPreRun
  • PreRun
  • Run
  • PostRun
  • PersistentPostRun

Suggestions when “unknown command” happens

其默认提供, 如:

1
2
3
4
5
6
7
$ hugo srever
Error: unknown command "srever" for "hugo"

Did you mean this?
server

Run 'hugo --help' for usage.

也可以关闭:

1
command.DisableSuggestions = true

Go-Cobra-库的使用
http://example.com/2024/01/29/Go-Cobra-库的使用/
作者
Jie
发布于
2024年1月29日
许可协议