I am trying to write an app which only has one command, hence, I was thinking I might skip Cobra.
The app should be able to support all types of config:
I am using viper but I can't get it to read my cli params.
v := viper.New()
viper.SetConfigName("config")
viper.AddConfigPath(".")
v.SetDefault(pathKey, defaultPath)
fs := pflag.NewFlagSet("app", pflag.ExitOnError)
fs.String(pathKey, defaultPath, "Default path")
fs.StringSlice(wordsKey, []string{""}, "Words")
fs.String(loglevelKey, "info", "Log level")
if err := v.BindPFlags(fs); err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := fs.Parse(os.Args[1:]); err != nil {
fmt.Println(err)
os.Exit(1)
}
v.AutomaticEnv()
if err := v.ReadInConfig(); err != nil {
fmt.Println("no conf file") //ignore, it can be either cli params, or conf file
}
var c conf
if err := v.Unmarshal(&c); err != nil {
fmt.Println(err)
os.Exit(1)
}
But I never get the cli params into the conf struct. Printing v
before the Unmarshal
doesn't show any of the cli params I provide.
What am I missing? Do I need to use cobra for this? Or do I have to assign each flagset flag, eg fs.String(pathKey, defaultPath, "Default path")
, manually to the config struct?
For posterity, I think I found the issue:
My conf
struct didn't have the correspondent key names as the flags do. Setting the json:"logLevel"
for example while the field is called DisplayLogLevel is not enough, it must be:
const (
pathKey = "path"
wordsKey = "words"
logLevelKey = "logLevel"
)
type struct conf {
Path string `json:"path"`
Words []string `json:"words"`
LogLevel string `json:"logLevel"`
}
maybe you have to set config type. From https://github.com/spf13/viper :
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.