127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
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)
|
|
}
|
|
}
|