Cobra

cobra/user_guide.md at master · spf13/cobra

Cobra Generator

Cobra Generator是用于生成Cobra命令行应用代码的脚手架,使用如下命令安装脚手架程序到$GOPATH/bin目录下。

go install github.com/spf13/cobra/cobra@latest

他提供了如下控制台命令用于生成命令行程序的代码:

cobra init

创建一个Cobra 命令行程序代码:

$ mkdir myapp && cd myapp
$ go mod init myapp
go: creating new go.mod: module myapp
$ cobra init --pkg-name myapp
Your Cobra application is ready at
/Users/yangsx/Project/temp/myapp
$ tree -N
.
├── LICENSE         # 默认使用 Apache License
├── cmd             # 此包下的每个源码文件代表一个命令
│   └── root.go # root.go 代表根命令
├── go.mod
└── main.go

指定许可证与作者创建:

$ cobra init --pkg-name myapp -a 'yangsx yangsx95@qq.com' -l MIT # 作者为yangsx,许可证为 MIT
Your Cobra application is ready at
/Users/yangsx/Project/temp/myapp

设置是否启用viper(是同一个作者写的应用程序完整配置的解决方案):

# 默认启用
cobra init --pkg-name myapp --viper=false

生成的代码文件如下:

main.go:

package main

import "myapp/cmd"

func main() {
    cmd.Execute() // 执行命令行程序
}

cmd/root.go

// 初始化根命令
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
    Use:   "myapp", // 根命令名称
    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) { },
}

// 给根命令添加flag参数
func init() {
    // Here you will define your flags and configuration settings.
    // Cobra supports persistent flags, which, if defined here,
    // will be global for your application.

    // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.myapp.yaml)")

    // Cobra also supports local flags, which will only run
    // when this action is called directly.
    rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
    cobra.CheckErr(rootCmd.Execute()) // 执行根命令
}

cobra add

给根命令添加子命令:

$ cobra add test                           
test created at /Users/yangsx/Project/temp/myapp

将会在cmd/包下创建test.go文件:

package cmd

import (
    "fmt"
  
    "github.com/spf13/cobra"
)

// test子命令定义
// 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) { // test 子命令执行的回调
        fmt.Println("test called")
    },
}

func init() {
    rootCmd.AddCommand(testCmd) // 将test子命令添加到根命令中

    // 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")
}

也可以指定父命令,并创建子命令,指定test命令,创建他的子命令 child:

cobra add create -p testCmd

Cobra Library

创建命令

cmd/下创建go文件:

package cmd

import (
  "fmt"

  "github.com/spf13/cobra"
)

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

var versionCmd = &cobra.Command{
  Use:   "version",
  Short: "Print the version number of Hugo",
  Long:  `All software has versions. This is Hugo's`,
  Run: func(cmd *cobra.Command, args []string) { // 命令处理方法,不返回error
    fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
  },
}

如果要返回error给调用方,可以使用RunE:

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
  },
}

Flag

Cobra将Flag的方法大致分成以下几类:

// 参数全写,默认值,使用提示 
fetchCmd.Flags().String("name", "张三", "您的姓名")
// 参数全写,参数缩写,默认值,使用提示
fetchCmd.Flags().StringP("name", "n", "张三", "您的姓名")
// 值存放的目标指针变量,默认值,使用提示 
name := ""
fetchCmd.Flags().StringVar(&name, "name", "张三", "您的姓名")
// 值存放的目标指针变量,参数缩写,默认值,使用提示
fetchCmd.Flags().StringVarP(&name, "name", "n", "张三", "您的姓名")

可根据情况选择不同的方法。

Required Flag

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

Local Flags

本地flag,代表该flag只适用当前的命令,他的父命令、子命令都不可以用:

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

Persistent Flags

持久命令是指,为命令设置的flag参数,也会应用到他的子命令上,与Local Flag 相对应:

rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

Local Flag on Parent Commands

默认情况下,本地flag不会被子命令接收到,我们可以通过TraverseChildren属性更改该默认行为,让其解析父命令中的本地标志:

command := cobra.Command{
  Use: "print [OPTIONS] [COMMANDS]",
  TraverseChildren: true,
}

最后更新于