如何仅提取在cli中显式设置的标志集



我是眼镜蛇和毒蛇的新手。

我想知道是否有一种方法可以从cli中排除非用户设置的标志值。所以我的问题是,我的cobracmd中有一些具有默认值的可选标志。我想知道如果这些可选标志不是由用户设置的,是否有办法将其排除在处理之外?或者从另一个角度来看,是否有一种方法可以从cmd标志集中提取用户从cli中明确更改的标志?

这里有一个例子来更好地说明我的情况:

var cmd = &cobra.Command{
Use:   "command [operations]",
Short: "Perform some commands",
Run: func(cmd *cobra.Command, args []string) {
var user User
err := viper.Unmarshal(&user)
fmt.Println(err)
fmt.Println(user)
},
}
cmd.PersistentFlags().String("name", "", "Your Name (Required)")
cmd.PersistentFlags().String("description", "", "Description")
cmd.PersistentFlags().String("address", "", "Address")
cmd.PersistentFlags().Int("age", -1, "Age")
cmd.MarkPersistentFlagRequired("name")
viper.BindPFlags(cmd.PersistentFlags()) 

所以假设对于年龄和地址,我希望它们是可选的,并且在传递给struct时不进行传播。因此,这意味着,在cli中,用户不需要提交ageaddress标志,这些可选标志的默认值为零。然而,Int&字符串标志是强类型的,因此它们需要默认值(例如:""-1)。因此,当我将命令pflags绑定到viper并且用户不输入年龄时;cli中的地址值,viper将收到地址""和年龄-1。使用上面的方法,默认值将被传播到User结构。

我想要的是排除不是由用户设置的标志值。有没有一种方法可以将User结构从接收未由用户显式设置的标志值中排除?

我目前的解决方案是将未设置的标志排除在用户结构中进行处理,目前是这样的:

  1. 有一个命令标志数组。初始化空map[string]interface{}
  2. 遍历数组,并检查是否通过flags.Changed("flag")设置/更改了标志。若标志已更改,则将其添加到地图中
  3. 将映射转换为json
  4. 将json对象分解为结构

    // inside the Run function of a cobra command
    aMap := make(map[string]interface{})
    flags := cmd.Flags()
    for _, flag := range cmdFlags {
    if flags.Changed(flag) {
    aMap[flag] = viper.Get(flag)
    }
    }
    jsonStr, _ := json.Marshal(aMap)
    var user User
    json.Unmarshal(jsonStr, &user)
    fmt.Println(user)
    

但我想知道是否有比我上面的解决方案更好的替代方案。最好,我不想更改User结构中的任何内容,因为它是从外部包导入的。

谢谢。非常感谢你的帮助。

假设您的User结构如下所示:

type User struct {
...
age     int
address string
...
}

则默认情况下,User结构体的初始化将设置age => 0, address => 0。所以即使viper没有设置默认值。内部去吧。

我的建议是:
1。更改创建用户结构的方式

type User struct {
...
age     *int
address *string
...
}
  1. 将cobra中这两个字段的默认值设置为nil
    这样你就会知道Cobra的默认值是不设置值。无论何时设置该值,它都将是非nil值。希望能有所帮助

相关内容

  • 没有找到相关文章

最新更新