cobra 基本概念 cobra由三部分构成:
commands,arguments和flags
commands:表示要执行的动作。每一个 command 表示应用程序的一个动作。每个命令可以包含子命令。
arguments:给动作传入的参数。
flags:表示动作的行为。可以设置执行动作的行为。flags 包括两种:对某个命令生效和对所有命令生效
安装与使用cobra
- 不使用cobra-cli工具
# 先下载依赖包
go get -u github.com/spf13/cobra@latest
import "github.com/spf13/cobra"
- 使用客户端工具
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!")
},
}