我有一个如下所示的配置格式:
type config struct {
FooBar string `mapstructure:"foo_bar"`
BazBot string `mapstructure:"baz_bot"`
}我的基于眼镜蛇的命令行界面有带破折号的标志(例如--foo-bar=value1 --baz-bot=value2)。
在CLI中设置这些值以覆盖配置文件值时,Viper不知道如何将它们正确映射到配置中。这里有什么解决方案吗?Viper配置设置如下所示:
func loadConfig(cmd *cobra.Command) (*config, error) {
res := &config{}
if err := viper.BindPFlags(cmd.Flags()); err != nil {
return nil, err
}
viper.SetEnvPrefix("K")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
viper.AutomaticEnv()
var useConfigFile bool
if configFile, _ := cmd.Flags().GetString("config"); configFile != "" {
useConfigFile = true
viper.SetConfigFile(configFile)
}
if useConfigFile {
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
if err := viper.Unmarshal(res); err != nil {
return nil, err
}
}
return res, nil
}如果viper不能做到这一点,也可以接受对支持它的库的建议。
发布于 2020-05-21 15:43:32
首先,您应该定义标志。我不知道,根据你的例子,你做了还是没有做,但你应该做一些类似的事情(based on this):
cfg := &config{}
val := reflect.ValueOf(cfg).Elem()
for i := 0; i < val.NumField(); i++ {
fieldType := val.Type().Field(i)
name := fieldType.Tag.Get("mapstructure")
rootCmd.PersistentFlags().String(strings.ReplaceAll(name, "_", "-"), "default", "usage")
}这样,--help命令将向您显示可用的标志(--foo-bar和--baz-bot)。
然后,您应该在loadConfig方法中绑定标志:
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
if err := viper.BindPFlag(strings.ReplaceAll(flag.Name, "-", "_"), flag); err != nil {
return
}
})这对我很有效。
https://stackoverflow.com/questions/61920435
复制相似问题