cobra 使用

822 阅读5分钟

cobra 基本概念 cobra由三部分构成:commandsarguments 和 flags

commands:表示要执行的动作。每一个 command 表示应用程序的一个动作。每个命令可以包含子命令。

arguments:给动作传入的参数。

flags:表示动作的行为。可以设置执行动作的行为。flags 包括两种:对某个命令生效和对所有命令生效

安装与使用cobra

  1. 不使用cobra-cli工具
# 先下载依赖包
go get -u github.com/spf13/cobra@latest

import "github.com/spf13/cobra"
  1. 使用客户端工具
go install github.com/spf13/cobra-cli@latest
有道无术,术尚可求:“有目的,没有实现目的的方法,可以学方法或者创造方法。 ” 
有术无道,则止于术:“学习过或掌握方法,但是没有能创造方法的目的,你所掌握的方法就是你 (在这个领域里)能力的极限。

cobra仅仅是术,实操案例,使用cobra-cli生成项目,减少代码的开发复杂度

# 在mod模式下,先创建go.mod文件
go mod init demo
# 执行下面的文件会自动生成项目结构
cobra-cli init

初始的目录结构

├── LICENSE
├── cmd
│   └── root.go 
├── go.mod
├── go.sum
└── main.go
// main.go
package main
 
import "demo/cmd"
 
func main() {  
    // 执行cmd包下的Execute()
    cmd.Execute()
}

// cmd/root.go
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
   "os"

   "github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
   Use:   "3day",
   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) {
   //},
}

// 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() {
   err := rootCmd.Execute()
   if err != nil {
      os.Exit(1)
   }
}

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

2.添加命令

2.1.基本用法:添加command和flag

cobra-cli add version

cmd 文件夹下生成一个新的文件 version.go,定义这个新的命令的动作。

文件内容如下:


/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
   "fmt"

   "github.com/spf13/cobra"
)

var cfgPath string
// 这个变量如果在flag中有默认值,其他文件引用的时候直接输出的就是flag的默认值,并不是变量类型的默认值,这一点需要注意
var sunshine string

// versionCmd represents the version command
var versionCmd = &cobra.Command{
   Use:   "version",
   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("version called")
      // 下面这部分是我自己测试添加的,
     /* test, err := cmd.Flags().GetBool("test")
      if err != nil {
         fmt.Println("err : ", err)
         return
      }
      fmt.Println(test)

      fmt.Println(sunshine)*/
   },
}

// 给command设置flag,通常在init函数中
func init() {
    // 这个是确定versionCmd在哪个命令下,可以手动修改,但是我们一般使用命令添加更方便
   rootCmd.AddCommand(versionCmd)
   versionCmd.Flags().BoolP("test", "t", false, "test")
   // 重要的事情说三遍
   // 重要的事情说三遍
   // 重要的事情说三遍
   // 全局绑定flag使用PersistentFlags()方法,如果想让每个command都是用就挂在rootCmd下,
   rootCmd.PersistentFlags().StringVar(&cfgPath, "cfg", "", "command config")
   // 局部绑定flag使用Flags()方法,使用特定的command调用,
   versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "shine", "you are my sunshine")
   // 强制使用command的时候必须有的flag
   versionCmd.MarkFlagRequired("sunshine")
   // Here you will define your flags and configuration settings.

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

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

每个command只能使用自己声明的flag

// sunshine flag 只能在version command下使用
versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "shine", "you are my 

给父command生成子command,例如给version 下生成一个show command

// 这个versionCmd 就是 cobra-cli add version生成的命令,command + Cmd 是固定的模式
// go build 
// 生成 demo version show
cobra-cli add show -p "versionCmd"


// show.go
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
   "fmt"

   "github.com/spf13/cobra"
)

// showCmd represents the show command
var showCmd = &cobra.Command{
   Use:   "show",
   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("show called")
      // demo version show time ,time 是args[0]
      fmt.Println("show args:",args[0])
   },
}

func init() {
    // 这个就是把show 添加到version 命令下的动作
   versionCmd.AddCommand(showCmd)

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

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

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

下列验证器是内置的:

  • NoArgs - 如果没有任何参数,command会报错
  • ArbitraryArgs - command接受任何参数
  • OnlyValidArgs - 如果有任何位置参数不在 validArgs的范围里面, command会报错
  • MinimumNArgs(int) - 当位置参数的个数少于n时,command 会报错
  • MaximumNArgs(int) - 当位置参数的个数大于n时,,command会报错
  • ExactArgs(int) - 当位置参数的个数不正好是n个时,command会报错
  • ExactValidArgs(int) - 当不是正好有n个位置参数或者有任何位置参数不属于ValidArgs,command会报错.
  • RangeArgs(min, max) - 如果参数的个数不是在min和max之间,command会报错

关于自定义验证器的一个例子:

var cmd = &cobra.Command{
  Short: "hello",
  Args: func(cmd *cobra.Command, args []string) error {
    if len(args) < 1 {
      return errors.New("requires a color argument")
    }
    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!")
  },
}

参阅