Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,13 @@ func doParseSlice(ref reflect.Value, processField processFieldFn, opts Options)
}

func setField(refField reflect.Value, refTypeField reflect.StructField, opts Options, fieldParams FieldParams) error {
value, err := get(fieldParams, opts)
result, err := get(fieldParams, opts)
if err != nil {
return err
}

if value != "" && (!opts.SetDefaultsForZeroValuesOnly || refField.IsZero()) {
return set(refField, refTypeField, value, opts.FuncMap)
if result.value != "" && (!opts.SetDefaultsForZeroValuesOnly || !result.isDefault || refField.IsZero()) {
return set(refField, refTypeField, result.value, opts.FuncMap)
}

return nil
Expand Down Expand Up @@ -593,48 +593,57 @@ func parseFieldParams(field reflect.StructField, opts Options) (FieldParams, err
return result, nil
}

func get(fieldParams FieldParams, opts Options) (val string, err error) {
var exists, isDefault bool
type gotValue struct {
value string
isDefault bool
}

func get(fieldParams FieldParams, opts Options) (gotValue, error) {
var (
err error
result gotValue
exists bool
)

val, exists, isDefault = getOr(
result.value, exists, result.isDefault = getOr(
fieldParams.Key,
fieldParams.DefaultValue,
fieldParams.HasDefaultValue,
opts.Environment,
)
Comment on lines 599 to 613

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe exists could be a field in the struct and getOr would simply return a gotValue.

Note: I'm not a maintainer, just a random reviewer. Maybe it's worth for someone else feedback


if fieldParams.Expand {
val = os.Expand(val, opts.getRawEnv)
result.value = os.Expand(result.value, opts.getRawEnv)
}

opts.rawEnvVars[fieldParams.OwnKey] = val
opts.rawEnvVars[fieldParams.OwnKey] = result.value

if fieldParams.Unset {
defer os.Unsetenv(fieldParams.Key)
}

if fieldParams.Required && !exists && fieldParams.OwnKey != "" {
return "", newVarIsNotSetError(fieldParams.Key)
return result, newVarIsNotSetError(fieldParams.Key)
}

if fieldParams.NotEmpty && val == "" {
return "", newEmptyVarError(fieldParams.Key)
if fieldParams.NotEmpty && result.value == "" {
return result, newEmptyVarError(fieldParams.Key)
}

if fieldParams.LoadFile && val != "" {
filename := val
val, err = getFromFile(filename)
if fieldParams.LoadFile && result.value != "" {
filename := result.value
result.value, err = getFromFile(filename)
if err != nil {
return "", newLoadFileContentError(filename, fieldParams.Key, err)
return result, newLoadFileContentError(filename, fieldParams.Key, err)
}
}

if opts.OnSet != nil {
if fieldParams.OwnKey != "" {
opts.OnSet(fieldParams.Key, val, isDefault)
opts.OnSet(fieldParams.Key, result.value, result.isDefault)
}
}
return val, err
return result, err
}

// split the env tag's key into the expected key and desired option, if any.
Expand Down
21 changes: 21 additions & 0 deletions env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2208,6 +2208,9 @@ func TestSetDefaultsForZeroValuesOnly(t *testing.T) {
u, err := url.Parse("https://localhost/foo")
isNoErr(t, err)

uByEnv, err := url.Parse("https://localhost/byEnv")
isNoErr(t, err)

for _, tc := range []struct {
Name string
Options Options
Expand All @@ -2231,6 +2234,24 @@ func TestSetDefaultsForZeroValuesOnly(t *testing.T) {
Url: *defUrl,
},
},
{
Name: "true with env",
Options: Options{SetDefaultsForZeroValuesOnly: true, Environment: ToMap(append(os.Environ(), "URL=https://localhost/byEnv"))},
Expected: config{
Str: "isSet",
Int: 1,
Url: *uByEnv,
},
},
{
Name: "false wtih env",
Options: Options{SetDefaultsForZeroValuesOnly: false, Environment: ToMap(append(os.Environ(), "URL=https://localhost/byEnv"))},
Expected: config{
Str: "foo",
Int: 42,
Url: *uByEnv,
},
},
{
Name: "default",
Options: Options{},
Expand Down