package config import ( "errors" "fmt" "log" "os" "strings" "github.com/Masterminds/semver" "github.com/spf13/afero" "github.com/spf13/pflag" "github.com/spf13/viper" ) var ( Config = viper.GetViper() autoHelpAndVersion = true configFS = afero.NewOsFs() ) func init() { SetConfigFile("config", "yaml") } func SetConfigFile(name string, format string) { viper.SetDefault("Config.filename", name) viper.SetDefault("Config.format", format) } func AddHelpAndVersion(helpRequested *bool, versionRequested *bool) { if autoHelpAndVersion { if !viper.IsSet("help") { pflag.BoolVarP(helpRequested, "help", "h", false, "This message") } if !viper.IsSet("version") { pflag.BoolVarP(versionRequested, "version", "v", false, "Get Program Version") } } } func DefineConfigItem(key string, short string, def interface{}, helpString string) { switch t := def.(type) { case bool: viper.SetDefault(key, t) pflag.BoolP(key, short, viper.GetBool(key), helpString) case float64: viper.SetDefault(key, t) pflag.Float64P(key, short, viper.GetFloat64(key), helpString) case int: viper.SetDefault(key, t) pflag.IntP(key, short, viper.GetInt(key), helpString) case string: viper.SetDefault(key, t) pflag.StringP(key, short, viper.GetString(key), helpString) default: log.Fatalln("Config Type Unsupported") } } func SetAppName(appName, appPrefix string) { viper.SetDefault("app.name", appName) viper.SetDefault("app.prefix", appPrefix) } func SetAppVersion(verStr string) { var appVersion *semver.Version var err error appVersion, err = semver.NewVersion(verStr) if err != nil { log.Fatalln("Error setting app version") } viper.SetDefault("app.version", appVersion) } func GetConfigs() { var helpRequested bool var versionRequested bool viper.SetFs(configFS) viper.SetConfigName(viper.GetString("Config.filename")) viper.SetConfigType(viper.GetString("Config.format")) viper.AddConfigPath(fmt.Sprintf("/etc/%s/", viper.GetString("app.prefix"))) viper.AddConfigPath(fmt.Sprintf("$HOME/.%s/", viper.GetString("app.prefix"))) viper.AddConfigPath("./etc/") viper.WatchConfig() viper.SetEnvPrefix(viper.GetString("app.prefix")) viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) viper.AutomaticEnv() if autoHelpAndVersion { AddHelpAndVersion(&helpRequested, &versionRequested) autoHelpAndVersion = false // insure you do not add these twice, or you will experience a failure } if err := viper.ReadInConfig(); err != nil { var configFileNotFoundError viper.ConfigFileNotFoundError if errors.As(err, &configFileNotFoundError) { } else { log.Fatal("invalid Config file format", err) } } pflag.Parse() _ = viper.BindPFlags(pflag.CommandLine) if helpRequested { fmt.Printf("Usage: %s:\n", os.Args[0]) pflag.PrintDefaults() os.Exit(0) } if versionRequested { fmt.Printf("%s: %s\n", os.Args[0], viper.Get("app.version")) os.Exit(0) } }