2

Cobra ライブラリに、フラグが複数の値の 1 つであることを要求し、フラグが許可された値の 1 つでない場合にエラーをスローする組み込みツールはありますか? Githubページでこれを見ませんでした。

4

2 に答える 2

0

pflag.(*FlagSet).Var()Cobra では、メソッドを介してフラグとして使用されるカスタム値タイプを定義できます( https://github.com/spf13/pflagパッケージから、Cobra で使用されます)。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{
        "foo\thelp text for foo",
        "bar\thelp text for bar",
        "moo\thelp 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)
于 2021-12-31T11:26:25.813 に答える
0

否定的であることを証明するのは難しいですが、これが現在機能しているようには見えません。

于 2018-06-12T21:22:42.847 に答える