Closed leolara closed 3 years ago
If you look at Hugo, which I believe was the origin of both Cobra and Viper, these are used together. But the interaction does look kind of funky:
https://github.com/spf13/hugo/blob/master/commands/hugo.go#L173
@bep Would it make sense a way implement a way to pass a pflags from Cobra to Viper?
It would make totally sense -- and would get rid of the hack linked to above.
But I think you would have some rule(s) of what do do when the flag is defined in both collections. I guess checking the Changed flag in Cobra makes sense as an override-indicator.
I ended up writing this helper type to copy flags from Viper back to pflags. Why not use Viper directly, you might ask? pflags are somewhat more convenient to work with, as you can define custom datatypes and bind flags to variables (e.g.StringVar
vs String
).
type viperPFlagBinding struct {
configName string
flagValue pflag.Value
}
type viperPFlagHelper struct {
bindings []viperPFlagBinding
}
func (vch *viperPFlagHelper) BindPFlag(configName string, flag *pflag.Flag) (err error) {
err = viper.BindPFlag(configName, flag)
if err == nil {
vch.bindings = append(vch.bindings, viperPFlagBinding{configName, flag.Value})
}
return
}
func (vch *viperPFlagHelper) setPFlagsFromViper() {
for _, v := range vch.bindings {
v.flagValue.Set(viper.GetString(v.configName))
}
}
func main() {
var rootCmd = &cobra.Command{}
var viperPFlagHelper viperPFlagHelper
rootCmd.PersistentFlags().StringVar(&config.Password, "password", "", "API server password (remote HTTPS mode only)")
viperPFlagHelper.BindPFlag("password", rootCmd.Flag("password"))
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
err := viper.ReadInConfig()
if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return err
}
}
viperPFlagHelper.setPFlagsFromViper()
return nil
}
}
@WGH- May I use a derivative of that snippet in a repo licensed CC0-1.0 please? I will give you credit in a code comment.
Sure.
On August 11, 2018 11:06:23 AM GMT+03:00, Amy notifications@github.com wrote:
@WGH- May I use a derivative of that snippet in a repo licensed CC0-1.0 please? I will give you credit in a code comment.
-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/spf13/viper/issues/82#issuecomment-412259423
If for any reason someone needs it I have created an example that shows how coba and viper works together with 4 simple tests. Default values, default values overwritten by cmd line, config file and config file options overwritten by command line. Hope it helps someone:
https://github.com/desdic/playground/tree/master/go/cobraviper
I also created a small utility at https://github.com/cpliakas/cliutil#flagger that made it easier for me to add flags using Cobra and Viper. I am sharing here in case it is helpful to anyone else.
Closing in favor of #1061
From the documentation it is clear that both Viper and Cobra use pflags, but is it possible to use Cobra and get all te power of Viper inside the Cobra commands?