Documentation
¶
Index ¶
- func NewConfigProvider(target interface{}, configName, envPrefix string, options ...ProviderOption) (interfaces.Provider, error)
- func NewProvider(configEntries []Entry, configName, envPrefix string, options ...ProviderOption) (interfaces.Provider, error)
- type Entry
- type EntryOption
- type ProviderOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewConfigProvider ¶
func NewConfigProvider(target interface{}, configName, envPrefix string, options ...ProviderOption) (interfaces.Provider, error)
NewConfigProvider creates a new config provider that is able to parse the command line, env vars and config file based on the given entries. This config provider automatically generates the needed config entries and fills the given config target based on the annotations on this struct. In case custom config entries should be used beside the annotations on the struct one can define them via
CustomConfigEntries(customEntries)`
e.g.
customEntries:=[]Entry{ // fill entries here } provider,err := NewConfigProvider(&myConfig,"my-config","MY_APP",CustomConfigEntries(customEntries))
Example (MappingFunc) ¶
type logLevel int8 const ( llTrace logLevel = 0 llDebug logLevel = 1 llInfo logLevel = 2 llWarn logLevel = 3 llError logLevel = 4 ) // The configuration with the annotations needed in order to define how the config should be filled type myCfg struct { Field1 string `cfg:"{'name':'field-1','mapfun':'strToUpper','default':'HeLlO wOrLd'}"` Field2 logLevel `cfg:"{'name':'field-2','mapfun':'strToLogLevel'}"` } cfg := myCfg{} // Create a provider based on the given config struct provider, err := NewConfigProvider(&cfg, "MyConfig", "MY_APP") if err != nil { panic(err) } // Register function to convert each string to upper case err = provider.RegisterMappingFunc("strToUpper", func(rawUntypedValue interface{}, targetType reflect.Type) (interface{}, error) { asStr, ok := rawUntypedValue.(string) if !ok { return nil, fmt.Errorf("Value must be a string") } return strings.ToUpper(asStr), nil }) if err != nil { panic(err) } // Register function to convert the given loglevel as string to the actual loglevel err = provider.RegisterMappingFunc("strToLogLevel", func(rawUntypedValue interface{}, targetType reflect.Type) (interface{}, error) { asStr, ok := rawUntypedValue.(string) if !ok { return nil, fmt.Errorf("Value must be a string") } switch asStr { case "trace": return llTrace, nil case "debug": return llDebug, nil case "info": return llInfo, nil case "warn": return llWarn, nil case "error": return llError, nil default: return nil, fmt.Errorf("loglevel %s unknown/ not supported", asStr) } }) if err != nil { panic(err) } // As commandline arguments the parameter 'field-1' is missing, hence its default value will be used (see above) args := []string{ "--field-2=warn", } // Read the parameters given via commandline into the config struct err = provider.ReadConfig(args) if err != nil { panic(err) } fmt.Printf("field-1='%v', field-2='%v'\n", cfg.Field1, cfg.Field2)
Output: field-1='HELLO WORLD', field-2='3'
Example (PrimitiveTypes) ¶
// The configuration with the annotations needed in order to define how the config should be filled type myCfg struct { Field1 string `cfg:"{'name':'field-1','desc':'This is field 1','default':'default value for field 1'}"` Field2 int `cfg:"{'name':'field-2','desc':'This is field 2','default':11}"` Field3 bool `cfg:"{'name':'field-3','desc':'This is field 3','default':false}"` Field4 time.Duration `cfg:"{'name':'field-4','desc':'This is field 4','default':'5m'}"` } cfg := myCfg{} // Create a provider based on the given config struct provider, err := NewConfigProvider(&cfg, "MyConfig", "MY_APP") if err != nil { panic(err) } // As commandline arguments the parameter 'field-1' is missing, hence its default value will be used (see above) args := []string{"--field-2=22", "--field-3", "--field-4=10m"} // Read the parameters given via commandline into the config struct err = provider.ReadConfig(args) if err != nil { panic(err) } fmt.Printf("field-1='%s', field-2=%d, field-3=%t, field-4=%s\n", cfg.Field1, cfg.Field2, cfg.Field3, cfg.Field4)
Output: field-1='default value for field 1', field-2=22, field-3=true, field-4=10m0s
Example (Slices) ¶
// The configuration with the annotations needed in order to define how the config should be filled type myCfg struct { Field1 []string `cfg:"{'name':'field-1','desc':'This is field 1','default':['a','b','c']}"` Field2 []int `cfg:"{'name':'field-2','desc':'This is field 2','default':[1,2,3]}"` Field3 []bool `cfg:"{'name':'field-3','desc':'This is field 3','default':[true,false,true]}"` Field4 []float64 `cfg:"{'name':'field-4','desc':'This is field 4','default':[1.1,2.2,3.3]}"` } cfg := myCfg{} // Create a provider based on the given config struct provider, err := NewConfigProvider(&cfg, "MyConfig", "MY_APP") if err != nil { panic(err) } // As commandline arguments the parameter 'field-1' is missing, hence its default value will be used (see above) args := []string{ "--field-2=4,5,6", "--field-3=false,true", "--field-4=4.4,5.5,6.6", } // Read the parameters given via commandline into the config struct err = provider.ReadConfig(args) if err != nil { panic(err) } fmt.Printf("field-1='%v', field-2=%v, field-3=%v\n", cfg.Field1, cfg.Field2, cfg.Field3)
Output: field-1='[a b c]', field-2=[4 5 6], field-3=[false true]
Example (Structs) ¶
type myNestedStruct struct { FieldA string `cfg:"{'name':'field-a','desc':'This is field a','default':'default of field a'}"` FieldB int `cfg:"{'name':'field-b','desc':'This is field b','default':22}"` } // The configuration with the annotations needed in order to define how the config should be filled type myCfg struct { Field1 myNestedStruct `cfg:"{'name':'field-1','desc':'This is field 1','default':{'field-a':'default','field-b':33}}"` Field2 []myNestedStruct `cfg:"{'name':'field-2','desc':'This is field 2','default':[{'field-a':'value','field-b':33},{}]}"` } cfg := myCfg{} // Create a provider based on the given config struct provider, err := NewConfigProvider(&cfg, "MyConfig", "MY_APP") if err != nil { panic(err) } // As commandline arguments the parameter 'field-1' is missing, hence its default value will be used (see above) args := []string{ "--field-1.field-a=the value", } // Read the parameters given via commandline into the config struct err = provider.ReadConfig(args) if err != nil { panic(err) } fmt.Printf("field-1='%v', field-2=%v\n", cfg.Field1, cfg.Field2)
Output: field-1='{the value 22}', field-2=[{value 33} {default of field a 22}]
Example (Usage) ¶
// The configuration with the annotations needed in order to define how the config should be filled type myCfg struct { //Field1 string `cfg:"{'name':'field-1','desc':'This is field 1','default':'default value for field 1'}"` Field2 int `cfg:"{'name':'field-2','desc':'This is field 2. It is a required field since no default values is defined.'}"` } cfg := myCfg{} // Create a provider based on the given config struct provider, err := NewConfigProvider(&cfg, "MyConfig", "MY_APP") if err != nil { panic(err) } args := []string{"--field-2=22"} // Read the parameters given via commandline into the config struct err = provider.ReadConfig(args) if err != nil { panic(err) } fmt.Print(provider.Usage())
Output: --field-2 (-) [required] env var: MY_APP_FIELD_2 default: n/a desc: This is field 2. It is a required field since no default values is defined.
func NewProvider ¶
func NewProvider(configEntries []Entry, configName, envPrefix string, options ...ProviderOption) (interfaces.Provider, error)
NewProvider creates a new config provider that is able to parse the command line, env vars and config file based on the given entries.
DEPRECATED: Please use NewConfigProvider instead.
Example ¶
var configEntries []Entry configEntries = append(configEntries, NewEntry("port", "the port to listen to", Default(8080), ShortName("p"))) // no default value for this parameter --> thus it can be treated as a required one // to check if it was set by the user one can just call provider.IsSet("db-url") configEntries = append(configEntries, NewEntry("db-url", "the address of the data base")) configEntries = append(configEntries, NewEntry("db-reconnect", "enable automatic reconnect to the data base", Default(false))) provider, err := NewProvider(configEntries, "my-config", "MY_APP") if err != nil { panic(err) } args := []string{"--db-url=http://localhost"} err = provider.ReadConfig(args) if err != nil { panic(err) } port := provider.GetInt("port") // check for mandatory parameter if !provider.IsSet("db-url") { panic(fmt.Errorf("Parameter '--db-url' is missing")) } dbURL := provider.GetString("db-url") dbReconnect := provider.GetBool("db-reconnect") fmt.Printf("port=%d, dbURL=%s, dbReconnect=%t", port, dbURL, dbReconnect)
Output: port=8080, dbURL=http://localhost, dbReconnect=false
Example (WithConfigFile) ¶
var configEntries []Entry configEntries = append(configEntries, NewEntry("port", "the port to listen to", Default(8080), ShortName("p"))) provider, err := NewProvider(configEntries, "my-config", "MY_APP") if err != nil { panic(err) } args := []string{"--config-file=test/data/config.yaml"} err = provider.ReadConfig(args) if err != nil { panic(err) } port := provider.GetInt("port") cfgFile := provider.GetString("config-file") fmt.Printf("port=%d was read from cfgFile=%s", port, cfgFile)
Output: port=12345 was read from cfgFile=test/data/config.yaml
Types ¶
type Entry ¶
type Entry struct {
// contains filtered or unexported fields
}
Entry is one item to define a configuration
func CreateEntriesFromStruct ¶
func CreateEntriesFromStruct(target interface{}, logger interfaces.LoggerFunc) ([]Entry, error)
CreateEntriesFromStruct creates Entries based on the annotations provided at the given target struct.
Only fields with annotations of the form
`cfg:"{'name':<name>,'desc':<description>,'default':<default value>}"`
will be regarded.
For example for the struct below
type Cfg struct { Name string `cfg:"{'name':'name','desc':'the name of the config','default':'the name'}"` }
A config entry
e := NewEntry("name","the name of the config",Default("the name"))
will be created.
func NewEntry ¶
func NewEntry(name, usage string, options ...EntryOption) Entry
NewEntry creates a new Entry that is available as flag, config file entry and environment variable
Example ¶
entry := NewEntry("port", "The port of the service", Default(8080), ShortName("p")) fmt.Printf("%s", entry)
Output: --port (-p) [default:8080 (int)] - The port of the service
func (Entry) EnvVarName ¶ added in v0.1.0
EnvVarName returns the name of the environment variable for this entry.
func (Entry) IsRequired ¶
IsRequired returns true in case no default value is given
type EntryOption ¶
type EntryOption func(e *Entry)
EntryOption represents an option for the Entry
func Bind ¶
func Bind(flag, env bool) EntryOption
Bind enables/ disables binding of flag and env var
func DesiredType ¶
func DesiredType(t reflect.Type) EntryOption
DesiredType sets the desired type of this entry
func ShortName ¶
func ShortName(fShort string) EntryOption
ShortName specifies the shorthand (one-letter) flag name
type ProviderOption ¶
type ProviderOption func(p *providerImpl)
ProviderOption represents an option for the Provider
func CfgFile ¶
func CfgFile(parameterName, shortParameterName string) ProviderOption
CfgFile specifies a default value
func CustomConfigEntries ¶
func CustomConfigEntries(customConfigEntries []Entry) ProviderOption
CustomConfigEntries allows to add config entries that are created manually via NewEntry(..)
func Logger ¶
func Logger(logger interfaces.LoggerFunc) ProviderOption
Logger exchanges the logger function. This provides the possibility to integrate your own logger. Per default the NoLogging function is used (disables logging completely). Other predefined logger functions (based on fmt.Printf) are DebugLogger, InfoLogger, WarnLogger and ErrorLogger.