我想知道是否有办法从 cli 中排除用户未设置的标志值。所以我的问题是,我的眼镜蛇cmd
中有一些具有默认值的可选标志。我想知道如果用户没有设置这些可选标志,是否有办法排除它们被处理?或者从另一个角度来看,有没有办法从标志集中提取用户从 cli 显式更改的标志cmd
?
这是一个更好地说明我的案例的示例:
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 中,用户不需要提交age
andaddress
标志,这些可选标志的默认值为 nil。但是,Int 和 String 标志是强类型的,因此它们需要默认值(例如:""
和-1
)。结果,当我将命令 pflags 绑定到 viper 并且用户不在 cli 中输入年龄和地址值时,viper 将接收""
地址和-1
年龄。使用上述方法,默认值将传播到 User 结构。
我想要的是排除用户未设置的标志值。有没有办法让我从接收用户未明确设置的标志值中排除用户结构?
我目前排除未设置标志在 User 结构中处理的解决方案目前是这样的:
- 有一个命令标志数组。初始化一个空
map[string]interface{}
- 遍历数组,并检查标志是否通过
flags.Changed("flag")
. 如果标志被更改,则将其添加到地图 - 将地图转换为 json
将 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
结构中的任何内容,因为它是从外部包导入的。
谢谢你。非常感谢您的帮助。