diff --git a/internal/conf/env/env.go b/internal/conf/env/env.go index 393370b2..068731ce 100644 --- a/internal/conf/env/env.go +++ b/internal/conf/env/env.go @@ -150,7 +150,7 @@ func loadEnvInternal(env map[string]string, prefix string, rv reflect.Value) err if rt.Elem() == reflect.TypeOf("") { if ev, ok := env[prefix]; ok { if ev == "" { - rv.Set(reflect.ValueOf([]string{})) + rv.Set(reflect.MakeSlice(rv.Type(), 0, 0)) } else { rv.Set(reflect.ValueOf(strings.Split(ev, ","))) } @@ -159,19 +159,23 @@ func loadEnvInternal(env map[string]string, prefix string, rv reflect.Value) err } if rt.Elem().Kind() == reflect.Struct { - for i := 0; ; i++ { - itemPrefix := prefix + "_" + strconv.FormatInt(int64(i), 10) - if !envHasAtLeastAKeyWithPrefix(env, itemPrefix) { - break - } + if ev, ok := env[prefix]; ok && ev == "" { // special case: empty list + rv.Set(reflect.MakeSlice(rv.Type(), 0, 0)) + } else { + for i := 0; ; i++ { + itemPrefix := prefix + "_" + strconv.FormatInt(int64(i), 10) + if !envHasAtLeastAKeyWithPrefix(env, itemPrefix) { + break + } - elem := reflect.New(rt.Elem()) - err := loadEnvInternal(env, itemPrefix, elem.Elem()) - if err != nil { - return err - } + elem := reflect.New(rt.Elem()) + err := loadEnvInternal(env, itemPrefix, elem.Elem()) + if err != nil { + return err + } - rv.Set(reflect.Append(rv, elem.Elem())) + rv.Set(reflect.Append(rv, elem.Elem())) + } } return nil } diff --git a/internal/conf/env/env_test.go b/internal/conf/env/env_test.go index 0f2338f7..b1f64fc6 100644 --- a/internal/conf/env/env_test.go +++ b/internal/conf/env/env_test.go @@ -47,15 +47,16 @@ type mySubStruct struct { } type testStruct struct { - MyString string - MyInt int - MyFloat float64 - MyBool bool - MyDuration myDuration - MyMap map[string]*mapEntry - MySlice []string - MySliceEmpty []string - MySliceSubStruct []mySubStruct + MyString string + MyInt int + MyFloat float64 + MyBool bool + MyDuration myDuration + MyMap map[string]*mapEntry + MySlice []string + MySliceEmpty []string + MySliceSubStruct []mySubStruct + MySliceSubStructEmpty []mySubStruct } func TestLoad(t *testing.T) { @@ -104,6 +105,9 @@ func TestLoad(t *testing.T) { os.Setenv("MYPREFIX_MYSLICESUBSTRUCT_1_PASSWORD", "pass2") defer os.Unsetenv("MYPREFIX_MYSLICESUBSTRUCT_1_PASSWORD") + os.Setenv("MYPREFIX_MYSLICESUBSTRUCTEMPTY", "") + defer os.Unsetenv("MYPREFIX_MYSLICESUBSTRUCTEMPTY") + var s testStruct err := Load("MYPREFIX", &s) require.NoError(t, err) @@ -136,4 +140,6 @@ func TestLoad(t *testing.T) { Password: "pass2", }, }, s.MySliceSubStruct) + + require.Equal(t, []mySubStruct{}, s.MySliceSubStructEmpty) }