英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论