1// Package adaptenv configures registers configurables from environment variables.
2package adaptenv
3
4import "gopkg.in/hlandau/configurable.v1"
5import "os"
6
7// Loads values from environment variables into any configurables which expose
8// CfEnvVarName() string. Priorities are checked.
9func Adapt() {
10	configurable.Visit(func(c configurable.Configurable) error {
11		adaptRecursive(c)
12		return nil
13	})
14}
15
16func adaptRecursive(c configurable.Configurable) {
17	cc, ok := c.(interface {
18		CfChildren() []configurable.Configurable
19	})
20	if ok {
21		for _, ch := range cc.CfChildren() {
22			adaptRecursive(ch)
23		}
24	}
25
26	adapt(c)
27}
28
29func adapt(c configurable.Configurable) {
30	cenv, ok := c.(interface {
31		CfEnvVarName() string
32		CfSetValue(x interface{}) error
33	})
34	if !ok {
35		return
36	}
37
38	envVarName := cenv.CfEnvVarName()
39	if envVarName == "" {
40		return
41	}
42
43	v, ok := os.LookupEnv(envVarName)
44	if !ok {
45		return
46	}
47
48	cprio, ok := c.(interface {
49		CfGetPriority() configurable.Priority
50		CfSetPriority(priority configurable.Priority)
51	})
52	if ok {
53		if cprio.CfGetPriority() > configurable.EnvPriority {
54			return
55		}
56	}
57
58	err := cenv.CfSetValue(v)
59	if err != nil {
60		return
61	}
62
63	if ok {
64		cprio.CfSetPriority(configurable.EnvPriority)
65	}
66}
67