cobra 快速教程

Cobra简介

  • 一个用于生成命令行工具的框架(本身也是个命令行工具)
  • 简单易用
  • Kubernetes、Etcd等等都是用它来做的。

Cobra安装

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

确保cobra被添加到PATH环境变量中。
get -u是updata的意思。
链接的最后如果没有加上cobra的话,是不会下载exe文件的也就是说用不了cobra这个exe软件。下载之后就会在go的path路径里面的bin文件生成一个exe文件。

cobra -h
在项目中引入Cobra的方式(不建议手动引入):
import “github.com/spf13/cobra”

Cobra项目创建

建议使用GO Module模式。首先,创建一个Go Module的项目。名称采用clid(下同)。
mkdir clid
go mod init clid
然后再clid目录中创建cobra项目。
cd clid
cobra init --pkg-name clid
即可生成。

修改作者信息

上面默认生成的Go文件中,作者信息位置为默认占位符。手动修改比较麻烦,所以建议一开始初始化的时候添加–author选项。
cobra init --pkg-name clid --athor kernelTea -l MIT
也可以指定License。

命令的基本结构

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{ //根命令。
	Use:   "cobra-demo",
	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) { }, //实现功能逻辑的函数。
    Alias: []string{}, // 别名,命令的别名。
}

命令编译与运行

go语言编译命令

cd clid 
go build

go语言运行命令

./clid

为命令添加一个子命令

cobra add test

添加一个名叫test的子命令。

说明:
go version ,其中version就是子命令。

package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

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

func init() {
	rootCmd.AddCommand(testCmd)

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

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

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

讲解:

  1. 命令的基本结构
  2. 如何将命令绑定到父级命令上去 (看子命令的init函数,ADDCommand是绑定关系的方法)

编译运行可看到test子命令。

为命令添加一个选项

func init(){
    rootCmd.AddCommand(testCmd)
    testCmd.Flags().Boolp("verbose","v",false,"是否显示测试详情")
}

实例中添加了一个verbose选项,用以控制是否显示测试详情。

在init初始化中,有一些注释关于这个选项的说明,其中,Flags()方法里面有很多选项类型,如字符串、ip地址等等。

  • 为子命令再添加子命令
func init(){
    cobra.OnInitialize(initConfig)
    ……省略其中代码
    cmd1.AddCommand(cmd11, cmd12)
    rootCmd.AddCommand(cmd1,cmd2)
}

编译运行效果。

选项的接收与处理

var testcmd = &cobra.Command{
    Use: "test",
    Short: "短的说明",
    Run: func(cmd *cobra.Command, args []string){
        verbose, err := cmd.Flags().GetBool("verbose")
        if err != nil {
            fmt.Println("获取命令选项出错")
            return
        }
        fmt.Printf("获取到命令选项值:%t\n",verbose)
    },
}

选项的常见类型

  • 布尔值
  • 数字(各类整数、浮点数等等)
  • 字符串
  • 其它高级类型 如IP地址,掩码等等

选项的帮助信息

// SetHelpFunc sets help function. Can be defined by Application.
func (c *Command) SetHelpFunc(f func(*Command, []string)){
    c.helpFunc = f
}

// SetHlpCommand sets help command.
func (c *Command) SetHelpCommand(cmd *Command) {
    c.helpCommand = cmd
}

// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
func(c *Command) SetHelpTemplate(s string) {
    c.helpTemplate = s
}

help命令的帮助信息:

func (c *Command) InitDefaultHelpCmd(){
    if !c.HasSubCommands(){
        return
    }
    if c.helpCommand == nil{
        c.helpCommand = &Command{
            Use: "help [command]",
            Short: "Help about any command",
            Long: `Help provides help for any command in the application.
            Simply type ` + c.Name() + `help [path to command] for full details.`,
            Run: func(c *Command, args []string){
                cmd, _, e := c.Root().Find(args)
                if cmd == nil || e !=nil {
                    c.Printf("Unknown help topic %#q\n", args)
                    c.Root().Usage()
                } else {
                    cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown
                    cmd.Help()
                }
            },
        }
    }
    c.RemoveCommand(c.helpCommand)
    c.AddCommand(c.helpCommand)
}
---
        Short: "Help about " + c.Name(),
---

课程总结

  • 简介
  • 安装、创建项目、修改作者信息
  • 命令、子命令、选项
  • 帮助信息

Cobra框架源码分析

命令行基础概念

go      Command 命令
go run main.go      Argument
go run main.go --config=app.conf    Flag? SubCommand?

cobra子命令

Root命令
cmd1子命令
cmd2子命令
cmd11子子命令
cmd12子子命令

cobra中command常用属性

var rootCmd = &cobra.Command{
    Use: "",
    Short: "",
    Long: "",
    Example: "",
    Version: "1.1.0",
    Aliases: []string{""},
    SuggestFor: []string{},
    Args: cobra.ExactArgs(2),
    // Uncomment the following line if your bare application
    // has an action associated with it:
    Run: func(cmd *cobra.Command, args []string){
        print()
    },
}

cobra的运行流程

PersistentPreRun
PreRun
Run
PostRun
PersisPostRun

Cobra源码实现

源代码中,几个文件重点关注。

  • 参数 (args.go args_test.go)
  • 通用设置 (cobra.go cobra_test.go)
  • command结构 (command.go command_notwin.go command_test.go command_win.go)

相关信息

框架源码官方github
https://github.com/spf13/cobra
源码分析视频
https://www.bilibili.com/video/BV1Uz4y1R7Xy
实战视频
https://www.bilibili.com/video/BV1ka4y177iK/?p=7&spm_id_from=pageDriver

最后实战

目录架构

各文件代码

Logo

开源、云原生的融合云平台

更多推荐