golang Cobra 包简单使用

Cobra 是一个 Golang 包,提供了简单的接口来创建命令行程序。同时也很容易的生成应用程序和命令,cobra create appnamecobra add cmdname 等。

一、概念

cobra 中几个个重要的概念,分别是 commands、arguments 和 flags:

  • commands 代表行为
  • arguments 就是命令行参数(或者称为位置参数)
  • flags 代表对行为的改变(命令行选项)

二、初步使用

1. 安装

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

2. 创建应用

$ cobra init --pkg-name appname

image-20210428154327426

3. 增加命令

$ cobra add eula
$ cobra add kazuha

image-20210428155039659

这两条命令生成了两个相关文件。

4. 尝试使用

首先确定包名,我姑且设置为

kelu.org/apptest

对 import 做个修改。

image-20210429112413943

初始化 go mod:

go mod init kelu.org/apptest
go mod tidy

image-20210429112607233

编译

go build

在本目录下生成了 apptest 可执行文件,运行:

./apptest
./apptest eula
./apptest kazuha

image-20210429112731078

image-20210429113707028

5. 代码结构

对着几个子命令文件 var kazuhaCmd = &cobra.Command{ 以下的代码看下就能知道大致的开发套路了。

image-20210429113106610

每个命令的内容都相对简单:

image-20210429113254806

三、编码开发

命令行中选项(flags)和参数(arguments)的区别,以 ls 命令为例:

ls -alh kelu*
  • alh对应的是选项(flags),以 - 或 – 开头
  • kelu* 对应的是参数(arguments),一般参数在所有选项

0. 具体功能

Run: func(cmd *cobra.Command, args []string) {
    fmt.Println("cobra demo program") // 在这里实现
},

1. 添加选项(flags)

根据选项的作用范围,可以把选项分为两类:

  • persistent,对于一些全局性的选项,比较适合设置为 persistent 类型,比如控制输出的 verbose 选项:既可以设置给该 Command,又可以设置给该 Command 的子 Command。

    var Verbose bool
    rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
    
  • local,只能设置给指定的 Command。

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

2. 添加参数(arguments)

cobra 默认提供了一些验证方法:

  • NoArgs - 如果存在任何位置参数,该命令将报错
  • ArbitraryArgs - 该命令会接受任何位置参数
  • OnlyValidArgs - 如果有任何位置参数不在命令的 ValidArgs 字段中,该命令将报错
  • MinimumNArgs(int) - 至少要有 N 个位置参数,否则报错
  • MaximumNArgs(int) - 如果位置参数超过 N 个将报错
  • ExactArgs(int) - 必须有 N 个位置参数,否则报错
  • ExactValidArgs(int) 必须有 N 个位置参数,且都在命令的 ValidArgs 字段中,否则报错
  • RangeArgs(min, max) - 如果位置参数的个数不在区间 min 和 max 之中,报错
var cmdTimes = &cobra.Command{
    Use: …
    Short: …
    Long: …
    Args: cobra.MinimumNArgs(1),
    Run: …
}

3. 帮助信息

cmd.SetHelpCommand(cmd *Command)
cmd.SetHelpFunc(f func(*Command, []string))
cmd.SetHelpTemplate(s string)

4. 提示信息

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

5. prerun/postrun

var rootCmd = &cobra.Command{
    Use:   "cobrademo",
    Short: "sparkdev's cobra demo",
    Long: "the demo show how to use cobra package",
    PersistentPreRun: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
    },
    PreRun: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
    },
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Printf("cobra demo program, with args: %v\n", args)
    },
    PostRun: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
    },
    PersistentPostRun: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
    },
}

四、demo

package cmd

import (
	"fmt"
	"strings"

	"github.com/spf13/cobra"
)

// kazuhaCmd represents the kazuha command
var kazuhaCmd = &cobra.Command{
	Use:   "kazuha",
	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("kazuha args:" + strings.Join(args, " "))
	},
}

var times int
var kaedeharaCmd = &cobra.Command{
	Use:   "kaedehara",
	Short: "kaedehara 楓原",
	Long:  `kaedehara 楓原万叶`,
	Args:  cobra.MinimumNArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		for i := 0; i < times; i++ {
			fmt.Println("kaedehara args:" + strings.Join(args, " "))
		}
	},
}

func init() {
	rootCmd.AddCommand(kazuhaCmd)
	kaedeharaCmd.Flags().IntVarP(&times, "times", "t", 1, "times loop for input")
	kazuhaCmd.AddCommand(kaedeharaCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// kazuhaCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// kazuhaCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

image-20210429145243364

参考资料


使用 dnspod 设置自定义解析 golang 编译备忘