眼镜蛇允许的标志值



是否有内置工具(如果有,我如何使用它?(要求标志是几个值之一,如果标志不是Cobra库中允许的值之一,则引发错误?我没有在Github页面上看到这个。

Cobra 允许您通过pflag.(*FlagSet).Var()方法(来自 Cobra 使用的 https://github.com/spf13/pflag 包(定义要用作标志的自定义值类型。您必须创建一个实现pflag.Value接口的新类型:

type Value interface {
String() string
Set(string) error
Type() string
}

示例类型定义:

type myEnum string
const (
myEnumFoo myEnum = "foo"
myEnumBar myEnum = "bar"
myEnumMoo myEnum = "moo"
)
// String is used both by fmt.Print and by Cobra in help text
func (e *myEnum) String() string {
return string(*e)
}
// Set must have pointer receiver so it doesn't change the value of a copy
func (e *myEnum) Set(v string) error {
switch v {
case "foo", "bar", "moo":
*e = myEnum(v)
return nil
default:
return errors.New(`must be one of "foo", "bar", or "moo"`)
}
}
// Type is only used in help text
func (e *myEnum) Type() string {
return "myEnum"
}

注册示例:

func init() {
var flagMyEnum = myEnumFoo
var myCmd = &cobra.Command{
Use:   "mycmd",
Short: "A brief description of your command",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("myenum value:", flagMyEnum)
},
}
rootCmd.AddCommand(myCmd)
myCmd.Flags().Var(&flagMyEnum, "myenum", `my custom enum. allowed: "foo", "bar", "moo"`)
}

示例用法:(请注意下面控制台输出中的第一行(

$ go run . mycmd --myenum raz
Error: invalid argument "raz" for "--myenum" flag: must be one of "foo", "bar", or "moo"
Usage:
main mycmd [flags]
Flags:
-h, --help            help for mycmd
--myenum myEnum   my custom enum. allowed: "foo", "bar", "moo" (default foo)
exit status 1
$ go run . mycmd --myenum bar
myenum value: bar

完成

为了添加自动完成功能,有点隐藏的文档页面cobra/shell_completions.md#completions-for-flags提供了很大的帮助。对于我们的示例,您将添加如下内容:

func init() {
// ...
myCmd.Flags().Var(&flagMyEnum, "myenum", `my custom enum. allowed: "foo", "bar", "moo"`)
myCmd.RegisterFlagCompletionFunc("myenum", myEnumCompletion)
}
// myEnumCompletion should probably live next to the myEnum definition
func myEnumCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{
"foothelp text for foo",
"barthelp text for bar",
"moothelp text for moo",
}, cobra.ShellCompDirectiveDefault
}

用法示例:

$ go build -o main .
$ source <(main completion bash)
$ main mycmd --myenum <TAB><TAB>
bar  (help text for bar)
foo  (help text for foo)
moo  (help text for moo)

看起来enumflag包被发布为附加组件以满足此用例: https://pkg.go.dev/github.com/thediveo/enumflag

package main
import (
"fmt"
"github.com/spf13/cobra"
"github.com/thediveo/enumflag"
)
// ① Define your new enum flag type. It can be derived from enumflag.Flag, but
// it doesn't need to be as long as it is compatible with enumflag.Flag, so
// either an int or uint.
type FooMode enumflag.Flag
// ② Define the enumeration values for FooMode.
const (
Foo FooMode = iota
Bar
)
// ③ Map enumeration values to their textual representations (value
// identifiers).
var FooModeIds = map[FooMode][]string{
Foo: {"foo"},
Bar: {"bar"},
}
// User-defined enum flag types should be derived from "enumflag.Flag"; however
// this is not strictly necessary as long as they can be converted into the
// "enumflag.Flag" type. Actually, "enumflag.Flag" is just a fancy name for an
// "uint". In order to use such user-defined enum flags, simply wrap them using
// enumflag.New.
func main() {
// ④ Define your enum flag value.
var foomode FooMode
rootCmd := &cobra.Command{
Run: func(cmd *cobra.Command, _ []string) {
fmt.Printf("mode is: %d=%qn",
foomode,
cmd.PersistentFlags().Lookup("mode").Value.String())
},
}
// ⑤ Define the CLI flag parameters for your wrapped enum flag.
rootCmd.PersistentFlags().VarP(
enumflag.New(&foomode, "mode", FooModeIds, enumflag.EnumCaseInsensitive),
"mode", "m",
"foos the output; can be 'foo' or 'bar'")
rootCmd.SetArgs([]string{"--mode", "bAr"})
_ = rootCmd.Execute()
}

注意:它似乎不包括完成逻辑。

虽然很难证明是负面的,但看起来这不是目前的一项功能。

相关内容

  • 没有找到相关文章

最新更新