Allow embedded structs in env_options
This commit is contained in:
parent
14d559939f
commit
2da89f8425
@ -15,14 +15,27 @@ type EnvOptions map[string]interface{}
|
|||||||
// Fields in the options struct must have an `env` and `cfg` tag to be read
|
// Fields in the options struct must have an `env` and `cfg` tag to be read
|
||||||
// from the environment
|
// from the environment
|
||||||
func (cfg EnvOptions) LoadEnvForStruct(options interface{}) {
|
func (cfg EnvOptions) LoadEnvForStruct(options interface{}) {
|
||||||
val := reflect.ValueOf(options).Elem()
|
val := reflect.ValueOf(options)
|
||||||
typ := val.Type()
|
var typ reflect.Type
|
||||||
|
if val.Kind() == reflect.Ptr {
|
||||||
|
typ = val.Elem().Type()
|
||||||
|
} else {
|
||||||
|
typ = val.Type()
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
// pull out the struct tags:
|
// pull out the struct tags:
|
||||||
// flag - the name of the command line flag
|
// flag - the name of the command line flag
|
||||||
// deprecated - (optional) the name of the deprecated command line flag
|
// deprecated - (optional) the name of the deprecated command line flag
|
||||||
// cfg - (optional, defaults to underscored flag) the name of the config file option
|
// cfg - (optional, defaults to underscored flag) the name of the config file option
|
||||||
field := typ.Field(i)
|
field := typ.Field(i)
|
||||||
|
fieldV := reflect.Indirect(val).Field(i)
|
||||||
|
|
||||||
|
if field.Type.Kind() == reflect.Struct && field.Anonymous {
|
||||||
|
cfg.LoadEnvForStruct(fieldV.Interface())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
flagName := field.Tag.Get("flag")
|
flagName := field.Tag.Get("flag")
|
||||||
envName := field.Tag.Get("env")
|
envName := field.Tag.Get("env")
|
||||||
cfgName := field.Tag.Get("cfg")
|
cfgName := field.Tag.Get("cfg")
|
||||||
|
@ -1,26 +1,46 @@
|
|||||||
package main
|
package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
proxy "github.com/pusher/oauth2_proxy"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type envTest struct {
|
type EnvTest struct {
|
||||||
testField string `cfg:"target_field" env:"TEST_ENV_FIELD"`
|
TestField string `cfg:"target_field" env:"TEST_ENV_FIELD"`
|
||||||
|
EnvTestEmbed
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnvTestEmbed struct {
|
||||||
|
TestFieldEmbed string `cfg:"target_field_embed" env:"TEST_ENV_FIELD_EMBED"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadEnvForStruct(t *testing.T) {
|
func TestLoadEnvForStruct(t *testing.T) {
|
||||||
|
|
||||||
cfg := make(EnvOptions)
|
cfg := make(proxy.EnvOptions)
|
||||||
cfg.LoadEnvForStruct(&envTest{})
|
cfg.LoadEnvForStruct(&EnvTest{})
|
||||||
|
|
||||||
_, ok := cfg["target_field"]
|
_, ok := cfg["target_field"]
|
||||||
assert.Equal(t, ok, false)
|
assert.Equal(t, ok, false)
|
||||||
|
|
||||||
os.Setenv("TEST_ENV_FIELD", "1234abcd")
|
os.Setenv("TEST_ENV_FIELD", "1234abcd")
|
||||||
cfg.LoadEnvForStruct(&envTest{})
|
cfg.LoadEnvForStruct(&EnvTest{})
|
||||||
v := cfg["target_field"]
|
v := cfg["target_field"]
|
||||||
assert.Equal(t, v, "1234abcd")
|
assert.Equal(t, v, "1234abcd")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadEnvForStructWithEmbeddedFields(t *testing.T) {
|
||||||
|
|
||||||
|
cfg := make(proxy.EnvOptions)
|
||||||
|
cfg.LoadEnvForStruct(&EnvTest{})
|
||||||
|
|
||||||
|
_, ok := cfg["target_field_embed"]
|
||||||
|
assert.Equal(t, ok, false)
|
||||||
|
|
||||||
|
os.Setenv("TEST_ENV_FIELD_EMBED", "1234abcd")
|
||||||
|
cfg.LoadEnvForStruct(&EnvTest{})
|
||||||
|
v := cfg["target_field_embed"]
|
||||||
|
assert.Equal(t, v, "1234abcd")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user