We have a binary we are starting which has several subcommands, all set up with cobra
. And we want to use viper
for configuration. So the initialization of this is setup according to the docs:
func init() {
cobra.OnInitialize(initConfig)
RootCmd.PersistentFlags().StringVarP(&loglevel, "loglevel", "l", "info", "Default log level")
//other persistent flags
viper.BindPFlags(RootCmd.PersistentFlags())
log.CreateLogger(loglevel)
//add all other subcommands
RootCmd.AddCommand(...)
}
My issue is with initConfig
:
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
handleError(err)
os.Exit(1)
}
confDir = filepath.Join(home, DefaultConfigDir)
viper.Set("configDir", configDir)
viper.SetConfigName("config")
viper.SetConfigType("json")
viper.AddConfigPath(configDir)
viper.AddConfigPath(".")
cfgFile = filepath.Join(configDir, "config.json")
}
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired l
err := os.Mkdir(cfgDir, os.ModePerm)
if err != nil {
handleError(err)
}
err = viper.WriteConfigAs(cfgFile)
if err != nil {
handleError(err)
}
} else {
handleError(err)
os.Exit(1)
}
}
}
This runs inside init
, and this is in my subcommands package - so my subcommands tests will run this init
as well.
Trouble is it looks for the home
folder, and of course may mess with existing configs. In other words, I don't want this for testing, I want a clean testing directory.
How can I achieve this? As it has to run inside init
because of the flags and the early initialization of configs, I have not been able to figure out an alternative.