Pflag 通过创建 Flag 和 FlagSet 来使用,使用 Pflag 的开源项目:Kubernetes、Istio、Helm、Docker、Etcd
Flag
一个命令行参数会被解析成一个 Flag 类型的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// A Flag represents the state of a flag. type Flag struct { Name string// name as it appears on command line Shorthand string// one-letter abbreviated flag Usage string// help message Value Value // value as set DefValue string// default value (as text); for usage message Changed bool// If the user set the value (or if left to default) NoOptDefVal string// default value (as text); if the flag is on the command line without any options Deprecated string// If this flag is deprecated, this string is the new or now thing to use Hidden bool// used by cobra.Command to allow flags to be hidden from help/usage text ShorthandDeprecated string// If the shorthand of this flag is deprecated, this string is the new or now thing to use Annotations map[string][]string// used by cobra.Command bash autocomple code }
将 Flag 的值抽象成一个接口,可以自定义 Flag 类型
1 2 3 4 5 6 7
// Value is the interface to the dynamic value stored in a flag. // (The default value is represented as a string.) type Value interface { String() string// 将flag类型的值转换为string类型的值,并返回string的内容 Set(string) error// 将string类型的值转换为flag类型的值,转换失败报错 Type() string// 返回flag的类型,例如:string、int、ip等 }
FlagSet
FlagSet 是一些预先定义好的 Flag 集合,几乎所有的 Pflag 操作都可以借助 FlagSet 提供的方法来完成
获取 FlagSet
调用 NewFlagSet 创建一个 FlagSet
使用 Pflag 包定义的全局 FlagSet:CommandLine
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
自定义 FlagSet:通过定义一个新的 FlagSet 来定义命令及其子命令的 Flag
1 2 3
var version bool flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError) flagSet.BoolVar(&version, "version", true, "Print version information and quit.")
全局 FlagSet,适用于不需要定义子命令的命令行工具
1 2 3 4 5
import ( "github.com/spf13/pflag" )
pflag.BoolVarP(&version, "version", "v", true, "Print version information and quit.")
CommandLine 是一个包级别的变量
1 2 3 4 5 6
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
Flags: -c, --config string config file (default is $HOME/.cobra.yaml) -h, --help help for git -l, --license string Name of license for the project -p, --path string base project directory $ ./main 2022/05/03 18:34:00 Run in cmd: git
AddCommand
cmd/version.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
package cmd
import ( "github.com/spf13/cobra" "log" )
var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number", Long: "Print the version code", Run: func(cmd *cobra.Command, args []string) { log.Println("git version 2.36.0") }, }
Available Commands: completion Generate the autocompletion script for the specified shell help Help about any command version Print the version number
Flags: -c, --config string config file (default is $HOME/.cobra.yaml) -h, --help help for git -l, --license string Name of license for the project -p, --path string base project directory
Use "git [command] --help" for more information about a command.
$ ./main version 2022/05/03 18:36:00 git version 2.36.0
核心特性
pflag
Cobra 可以与 Pflag 集成,使用强大的标志功能
持久化
持久化:该标志可用于它所分配的命令以及该命令下的每个子命令
1
rootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
本地
本地:只能用在它所绑定的命令上
1
rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
--source 只能在 rootCmd 上引用,而不能在 rootCmd 的子命令上引用,例如 version
标志绑定到 Viper
将标志绑定到 Viper 上,后续可以通过 viper.Get() 来获取标志的值
1 2 3 4 5 6
var author string
funcinit() { rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution") viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author")) }
必选标志
默认情况下,标志为可选的
1 2
rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)") rootCmd.MarkFlagRequired("region")
非选项参数验证
可以使用 Command 的 Args 字段来验证非选项参数,或者通过 Cobra 的内置验证函数
Cobra 内置验证函数
描述
NoArgs
如果存在任何非选项参数,报错
ArbitraryArgs
接受任意非选项参数
OnlyValidArgs
任何非选项参数不在 Command 的 ValidArgs 字段中,报错
MinimumNArgs(int)
少于 N 个非选项参数,报错
MaximumNArgs(int)
多于 N 个非选项参数,报错
ExactArgs(int)
不等于 N 个非选项参数,报错
ExactValidArgs(int)
不等于 N 个非选项参数 或者 非选项参数不在 Command 的 ValidArgs 字段中,报错