I'm having trouble using Cobra and Viper together. This is what I'm doing:
var options util.Config = util.Config{}
var rootCmd = &cobra.Command{
Use: "test [command] [subcommands]",
Run: func(cmd *cobra.Command, args []string) {
if err := server.Run(); err != nil {
l.Fatal(err)
}
},
}
// initConfig helps initialise configuration with a stated path
func initConfig() {
if options.Path != "" {
viper.SetConfigFile(options.Path)
}
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
fmt.Println("Could not use config file: ", viper.ConfigFileUsed())
}
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVarP(&options.Path, "config", "n", "", "Path of a configuration file")
rootCmd.PersistentFlags().StringVarP(&options.Password, "password", "d", "", "Password to access the server")
viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup("password"))
rootCmd.AddCommand(log.Cmd(&options))
}
func main() {
rootCmd.Execute()
}
I'm trying to retrieve the value options.Password within my subcommand (an added command within log.Cmd(&options)
) however the field isn't being populated. I'm pretty sure I'm following the Cobra docs properly: https://github.com/spf13/cobra#create-rootcmd
Binding cobra flags to viper options only binds cobra flags to viper options, not vice versa. So you can access the password via
pass := viper.GetString("password")
if the password is set either via viper or cobra, but not via the variables defined in your flag definitions.
Basically, you have two options here: Either you use cobra without pointing your flags to variables, and then set your globals via various calls to viper.Get*
(you can even sanitize them while being at it), or you use viper as sort of a „parameter registry“ and call viper.Get*
where needed. I tend to go with the former solution.