【转载】使用Cobra开发自己的命令行工具

Cobra 项目地址:https://github.com/spf13/cobra

0 装载自

  • 使用Cobra开发自己的命令行工具

1 新建cobra项目

# 安装cobra-cli工具
go install github.com/spf13/cobra-cli@latest
# 新建项目目录
mkdir -p newApp
# 进入项目文件夹
cd myApp
# 初始化
go mod init && cobra-cli init

现在我们看到的目录结构应该是这样:

【转载】使用Cobra开发自己的命令行工具_第1张图片

root.go文件中有如下代码:

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
    Use:   "newApp",
    Short: "A brief description of your application",
    Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. 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.`,
    // Uncomment the following line if your bare application
    // has an action associated with it:
    // Run: func(cmd *cobra.Command, args []string) { },
}

解释一下上述代码中rootCmd各个成员的含义:

Use: 命令的名称
Short: 对命令的简短描述
Long: 对命令的详细描述,输入[appName] -h的时候会显示出来
Run: 命令的具体逻辑,这就是我们要去实现的了

让我们直接运行一下这个程序,看看输出是怎样的。

# 编译
go build
# 执行
./newApp

【转载】使用Cobra开发自己的命令行工具_第2张图片

可以看到,由于我们还没有实现Run,所以只打印出了详细的描述信息。

2 添加COMMAND

cobra官方建议的指令格式是APPNAME COMMAND ARG --FLAG ,譬如git clone URL --bare 这样的。

# 添加新的COMMAND
cobra-cli add hello

现在cmd文件夹下应该多出了一个hello.go文件,有如下代码:

// helloCmd represents the hello command
var helloCmd = &cobra.Command{
    Use:   "hello",
    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("hello called")
    },
}

现在可以看到,helloCmd有了一个默认的Run成员,我们重新编译执行,输出如下:

【转载】使用Cobra开发自己的命令行工具_第3张图片

输入./newApp hello查看输出:

img

3 定制FLAG

如果我们想为hello定制flag,应该怎么做呢?

修改hello.go中的init()函数:

// 定义了两个全局变量
var Name *string
var Time *bool

func init() {
    rootCmd.AddCommand(helloCmd)
    // 这样的flag无法通过if判断是否要输出
    // 且对于所有子命令都有效
    helloCmd.PersistentFlags().String("name", "", "Say hello to someone")
    // 这种flag就可以通过if来判断是否输出了,默认是false
    // 在调用command的时候加上 --time 或 -t 就可以变为true
    // 这样的flag仅对当前命令有效
    helloCmd.Flags().BoolP("time", "t", false, "Add time info to hello")
}

修改Run函数的实现:

Run: func(cmd *cobra.Command, args []string) {
    str, _ := cmd.Flags().GetString("name")
    fmt.Printf("Hello, %s!\n", str)
    t, _ := cmd.Flags().GetBool("time")
    if t {
        fmt.Println("Time:", time.Now().Format("2006-01-02 15:04:05"))
    }
}

编译、查看输出:

【转载】使用Cobra开发自己的命令行工具_第4张图片

cobra的flag默认情况下都是可选的,但如果我们想强制要求用户使用命令行工具的时候携带某些flag,也是可行的。我们可以在init()函数中加入如下代码:

// 设置使用hello的时候后面必须加上name
    err := helloCmd.MarkPersistentFlagRequired("name")
    if err != nil {
        log.Fatal("Set flag required fail!")
    }

编译、运行:

【转载】使用Cobra开发自己的命令行工具_第5张图片

可以看到,不带—-name的命令自动报错了。

4 子命令

# 为hello命令添加子命令
cobra-cli add test -p helloCmd

这时候cmd文件夹下多了一个test.go,我们去修改一下它的实现:

Run: func(cmd *cobra.Command, args []string) {
    str, _ := cmd.Flags().GetString("name")
    fmt.Printf("Test calling %s ...\n", str)
    t, _ := cmd.Flags().GetBool("time")
    if t {
        fmt.Println("Time:", time.Now().Format("2006-01-02 15:04:05"))
    }
}

编译、运行:

【转载】使用Cobra开发自己的命令行工具_第6张图片

可以看到,test子命令对于—-name是可以接收的,但是无法解析-t,这是因为我们前面为helloCmd声明flag的方式不同(详见代码注释)。

5 ARG

如果想在命令中加入参数,应该怎么做呢?为了不那么混乱,我们新建一个args命令:

cobra-cli add args

修改args.go文件中的代码:

// 设置最少需要一个参数
    Args: cobra.MinimumNArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("args called, args: ", args)
    }

编译、运行:

【转载】使用Cobra开发自己的命令行工具_第7张图片

以上就是cobra的简单使用。

参考文章

Go语言cobra库学习笔记–从入门到精通_random_w的博客-CSDN博客_cobra库

Go命令行库Cobra的使用_朱小厮的博客-CSDN博客_cobra 子命令

你可能感兴趣的:(Go学习笔记,linux,bash,go)