你可以在Cobra中为标志指定可选参数吗?

huangapple go评论102阅读模式
英文:

Can you specify optional arguments to a flag in Cobra?

问题

假设我在程序中有一个只打印正数的标志:

c.PersistentFlags().IntVar(&SomeFlag, optionSomeFlag, 0, "do something (range: x-y)")

默认值是0,所以如果用户不切换该标志,就不会打印任何内容。
我该如何使该标志接受参数但仍有默认值?
也就是说,如果默认值是5

./program --someflag 的输出将是 5

但如果我执行

./program --someflag=1 的输出将是 1

我尝试按照 Cobra 的用户指南操作,并期望有一种命令类型,可以让我仅在用户触发标志时指定默认值,而不是完全指定。不过,我可能对此有误解或者遗漏了某些内容。

英文:

Let's say I have this flag in my program that only prints a positive number:

c.PersistentFlags().IntVar(&SomeFlag, optionSomeFlag, 0, "do something (range: x-y)")

The default is 0 so if the user doesn't toggle the flag, nothing is printed.
How can I make the flag accept arguments but have a default itself?
i.e. if the default was 5

./program --someflag output would be 5

but if I did

./program --someflag=1 output would be 1

I tried following the user guide for Cobra and was expecting a command type that would allow me to specify default values only if the user triggers the flag, not just altogether. I may have misinterpreted this or missed something though.

答案1

得分: 2

可以使用NoOptDefVal来实现。

rootCmd.PersistentFlags().Lookup("someflag").NoOptDefVal = "5"

在下面的代码中,你可以找到一个完整的使用cobra的命令行应用程序的示例,它具有你描述的行为。

package main

import (
	"fmt"
	"github.com/spf13/cobra"
)

func main() {
	var someFlag int
	var defaultSomeFlag = "5"

	// 创建根命令。
	rootCmd := &cobra.Command{
		Use:   "program",
		Short: "你的应用程序的简要描述",
		Long:  "你的应用程序的更长描述",
		Run: func(cmd *cobra.Command, args []string) {
			// 检查标志是否被显式设置。
			if cmd.Flags().Lookup("someflag").Changed {
				fmt.Printf("someflag: %d\n", someFlag)
			} else {
				// 如果标志没有被显式设置,则不打印值。
				fmt.Printf("someflag 未设置\n")
			}
		},
	}

	// 定义标志并设置其默认值。
	rootCmd.PersistentFlags().IntVar(&someFlag, "someflag", 0, "做某事(范围:x-y)")
	rootCmd.PersistentFlags().Lookup("someflag").NoOptDefVal = defaultSomeFlag

	// 执行根命令。
	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
	}
}

以下是使用不同标志值执行的结果。

$ ./test
someflag 未设置
$ ./test --someflag
someflag: 5
$ ./test --someflag=3
someflag: 3
英文:

It can be done using NoOptDefVal

rootCmd.PersistentFlags().Lookup("someflag").NoOptDefVal = "5"

In the following code, you can find a complete example of a command line application with cobra that have the behavior you describe

package main

import (
    "fmt"
    "github.com/spf13/cobra"
)

func main() {
    var someFlag int
    var defaultSomeFlag = "5"

    // Create the root command.
    rootCmd := &cobra.Command{
	    Use:   "program",
	    Short: "A brief description of your application",
	    Long:  "A longer description of your application",
	    Run: func(cmd *cobra.Command, args []string) {
		    // Check whether the flag was explicitly set.
		    if cmd.Flags().Lookup("someflag").Changed {
			    fmt.Printf("someflag: %d\n", someFlag)
		    } else {
			    // If the flag was not explicitly set don't print a value.
			    fmt.Printf("someflag is not set\n")
		    }
	    },
    }

    // Define the flag and set its default value.
    rootCmd.PersistentFlags().IntVar(&someFlag, "someflag", 0, "do something (range: x-y)")
    rootCmd.PersistentFlags().Lookup("someflag").NoOptDefVal = defaultSomeFlag

    // Execute the root command.
    if err := rootCmd.Execute(); err != nil {
	    fmt.Println(err)
    }
}

Below are the results of the execution with different flag values.

$ ./test
someflag is not set
$ ./test --someflag
someflag: 5
$ ./test --someflag=3
someflag: 3

答案2

得分: 0

我计划通过自己解析os.Args[1:]来解决这个限制,以查找没有参数的标志,并将默认值插入到修改后的参数副本中,然后将修改后的副本传递给rootCommand.SetArgs

这种方法感觉有点巧妙且难以维护,但我没有看到其他解决方案。

英文:

I was planning to work around this limitation by parsing os.Args[1:] myself to look for the flag without a parameter and insert the default value into a modified copy of the arguments and pass the modified copy to rootCommand.SetArgs.

It feels a bit hackish and hard to sustain but I don't see another solution.

huangapple
  • 本文由 发表于 2023年1月24日 03:04:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75213919.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定