spf13 / viper

Go configuration with fangs
MIT License
27.2k stars 2.02k forks source link

Flags binding doesn't work when trying to bind a flag to a nested key #1072

Open eugene-manuilov opened 3 years ago

eugene-manuilov commented 3 years ago
flags.StringP("env-file", "e", "", "...")
if err := viper.BindPFlag("config.env-file", flags.Lookup("env-file")); err != nil {
    panic(err)
}

...

envfile := viper.GetString( "config.env-file" )
fmt.Println("Env file: ", envfile)

Expected behavior (what you expected to happen):

$ mycmd --env-file=env.ini
$ Env file: env.ini

Actual behavior (what actually happened):

$ mycmd --env-file=env.ini
$ Env file: 

Repl.it link:

Code reproducing the issue:

Environment:

Anything else we should know?:

github-actions[bot] commented 3 years ago

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

thspinto commented 3 years ago

I was trying the same thing in my integration with cobra. I used this workaround for my case:

func init() {
    rootCmd.AddCommand(serverCmd)
    serverCmd.Flags().StringP("port", "p", "", "server port")
    serverCmd.Flags().VisitAll(configureViper("server"))
}

func configureViper(prefix string) (fn func(*pflag.Flag)) {
    return func(flag *pflag.Flag) {
        prefixedName := strings.Join([]string{prefix, flag.Name}, ".")
        if err := viper.BindPFlag(prefixedName, flag); err != nil {
            panic(err)
        }
        env := strings.ReplaceAll(prefixedName, ".", "_")
        viper.BindEnv(prefixedName, strings.ToUpper(env))
    }
}

I basically iterate though all flags, manually configuring the viper and environment variable biding.