package config import ( "path/filepath" "strings" "sync" "github.com/spf13/viper" ) type DirectoryValueType string func (s *DirectoryValueType) Set(value string) error { *s = DirectoryValueType(value) return nil } func (s *DirectoryValueType) String() string { return string(*s) } type Configuration interface { GetString(key string) string GetBool(key string) bool GetInt(key string) int GetStringSlice(key string) []string SetDefault(key string, value interface{}) } func LoadConfiguration(configFilePath string) error { dir := filepath.Dir(configFilePath) base := filepath.Base(configFilePath) ext := filepath.Ext(base) configName := strings.TrimSuffix(base, ext) viper.SetConfigName(configName) viper.AddConfigPath(dir) switch ext { case ".yaml", ".yml": viper.SetConfigType("yaml") case ".json": viper.SetConfigType("json") case ".toml": viper.SetConfigType("toml") } if err := viper.MergeInConfig(); err != nil { return err } return nil } type ViperProxy struct { *viper.Viper sync.Mutex } var ( vp = &ViperProxy{} ) func (vp *ViperProxy) SetDefault(key string, value interface{}) { vp.Lock() defer vp.Unlock() vp.Viper.SetDefault(key, value) } func (vp *ViperProxy) GetString(key string) string { vp.Lock() defer vp.Unlock() return vp.Viper.GetString(key) } func (vp *ViperProxy) GetBool(key string) bool { vp.Lock() defer vp.Unlock() return vp.Viper.GetBool(key) } func (vp *ViperProxy) GetInt(key string) int { vp.Lock() defer vp.Unlock() return vp.Viper.GetInt(key) } func (vp *ViperProxy) GetStringSlice(key string) []string { vp.Lock() defer vp.Unlock() return vp.Viper.GetStringSlice(key) } func getViper() *ViperProxy { vp.Lock() defer vp.Unlock() if vp.Viper == nil { vp.Viper = viper.GetViper() vp.AutomaticEnv() vp.SetEnvPrefix("robotfs") vp.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) } return vp }