89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"os"
|
|
"reflect"
|
|
"strconv"
|
|
|
|
flag "github.com/spf13/pflag"
|
|
)
|
|
|
|
func loadFromEnv(env *Environment) {
|
|
v := reflect.ValueOf(env).Elem()
|
|
t := v.Type()
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
field := t.Field(i)
|
|
valueField := v.Field(i)
|
|
|
|
// It is of great importance we set these fields above
|
|
key := field.Tag.Get("env")
|
|
fallback := field.Tag.Get("default")
|
|
|
|
// If the variable is not found or is empty
|
|
raw, ok := os.LookupEnv(key)
|
|
if !ok || len(raw) == 0 {
|
|
raw = fallback
|
|
}
|
|
|
|
switch valueField.Kind() {
|
|
case reflect.String:
|
|
valueField.SetString(raw)
|
|
|
|
case reflect.Int:
|
|
if parsed, err := strconv.Atoi(raw); err == nil {
|
|
valueField.SetInt(int64(parsed))
|
|
}
|
|
|
|
case reflect.Bool:
|
|
if parsed, err := strconv.ParseBool(raw); err == nil {
|
|
valueField.SetBool(parsed)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func bindFlags(env *Environment) {
|
|
v := reflect.ValueOf(env).Elem()
|
|
t := v.Type()
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
field := t.Field(i)
|
|
valueField := v.Field(i)
|
|
|
|
flagName := field.Tag.Get("flag")
|
|
flagUsage := field.Tag.Get("usage")
|
|
if len(flagName) == 0 {
|
|
continue
|
|
}
|
|
|
|
switch valueField.Kind() {
|
|
case reflect.String:
|
|
flag.StringVar(
|
|
valueField.Addr().Interface().(*string), flagName,
|
|
valueField.String(), flagUsage,
|
|
)
|
|
case reflect.Int:
|
|
flag.IntVar(
|
|
valueField.Addr().Interface().(*int), flagName,
|
|
int(valueField.Int()), flagUsage,
|
|
)
|
|
case reflect.Bool:
|
|
flag.BoolVar(
|
|
valueField.Addr().Interface().(*bool), flagName,
|
|
valueField.Bool(), flagUsage,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
func LoadConfig() Environment {
|
|
var env Environment
|
|
|
|
loadFromEnv(&env)
|
|
bindFlags(&env)
|
|
flag.Parse()
|
|
|
|
return env
|
|
}
|