-
Notifications
You must be signed in to change notification settings - Fork 0
/
interfaces.setenvfieldvalues.go
61 lines (53 loc) · 1.34 KB
/
interfaces.setenvfieldvalues.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package interfaces
import (
"errors"
"os"
"reflect"
"strings"
jsoniter "github.com/json-iterator/go"
)
// SetEnvFieldValues sets field values based on environment variables.
func SetEnvFieldValues(output interface{}) error {
// If the passed in output isn't a reflection value, unpack it.
var outputValue reflect.Value
var ok bool
if outputValue, ok = output.(reflect.Value); !ok {
outputValue = reflect.ValueOf(output)
if outputValue.Kind() != reflect.Ptr {
return errors.New("pointer required")
}
outputValue = outputValue.Elem()
}
outputType := outputValue.Type()
// Loop through each field.
fieldsLength := outputType.NumField()
fieldLoop:
for i := 0; i < fieldsLength; i++ {
field := outputType.Field(i)
outputField := outputValue.Field(i)
// Check for env tag.
envVarName, ok := field.Tag.Lookup("env")
if !ok {
continue fieldLoop
}
// Check for env variable.
envVar := os.Getenv(envVarName)
if envVar == "" {
continue fieldLoop
}
switch field.Type.Kind() {
case reflect.String:
if strings.Index(envVar, `"`) < 0 {
envVar = `"` + envVar + `"`
}
}
// Unmarshal value.
outputFieldValue := reflect.New(outputField.Type())
err := jsoniter.Unmarshal([]byte(envVar), outputFieldValue.Interface())
if err != nil {
return err
}
outputField.Set(outputFieldValue.Elem())
}
return nil
}