package main import ( "fmt" "github.com/nate-johnston/viper" ) // ViperConfig holds information per config item. If an Default // is not set then it is assumed that the value is Required. // NOTE: You can not set a default on a nested value. i.e. a value // within a has in a json or yaml file. (nested.value) you can // set nested values as required. type ViperConfig struct { Key string // The config key that is required. Default interface{} // Default Value to set. Alias []string // Any key Aliases that should be registered Description string // Description of the config. } // InitViper with the passed path and config. func InitViper(path string, viperConfigs []ViperConfig) error { viper.SetConfigFile(path) if err := viper.ReadInConfig(); err != nil { return err } if err := ValidateConfig(viperConfigs); err != nil { return err } return nil } // ValidateConfig will check the defined var ViperConfigs []ViperConfig and validate // the existances of the required keys, and set defaults for all keys where defaults are // defined. func ValidateConfig(viperConfigs []ViperConfig) error { var errs []error for _, rc := range viperConfigs { if rc.Default == nil && viper.Get(rc.Key) == nil { errs = append(errs, fmt.Errorf("Key: %s, Description: %s", rc.Key, rc.Description)) } else { viper.SetDefault(rc.Key, rc.Default) } if len(rc.Alias) > 0 { for _, a := range rc.Alias { viper.RegisterAlias(a, rc.Key) } } } if len(errs) > 0 { return fmt.Errorf("Required Configuration Missing: %v", errs) } return nil }