Skip to content

Commit

Permalink
Completed fix of issue kelseyhightower#148
Browse files Browse the repository at this point in the history
with respecting of env-prefix and partially saved backward compatibility by using new tag no_pfx
  • Loading branch information
pr0n1x committed Jul 16, 2024
1 parent 5da5812 commit b14df87
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
27 changes: 19 additions & 8 deletions envconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,28 @@ func gatherInfo(prefix string, spec interface{}) ([]varInfo, error) {
if prefix != "" {
info.Key = fmt.Sprintf("%s_%s", prefix, info.Key)
}
// If name is overridden, switch .Key and .Alt and don't forget about prefix.
// Now the overridden name is for the first attempt to find value in environment.
// The initial name is an alternative name used if the first attempt is not successful.

// override default env-variable name with an envconfig tag
if info.Alt != "" {
if prefix != "" {
info.Alt = fmt.Sprintf("%s_%s", prefix, info.Alt)
noPfxPlace := ftype.Tag.Get("no_pfx")
if noPfxPlace == "key" {
// now the key name is overridden and prefixed
// alt name is not used
info.Key = info.Alt
info.Alt = ""
} else if noPfxPlace == "alt" {
// now the key name is overridden and prefixed
// and alt name is overridden name without prefix
info.Key = fmt.Sprintf("%s_%s", prefix, info.Alt)
} else {
// now key name is overridden and prefixed
// but alt is the prev key name (source struct field name) with prefix
prefixedStructFieldName := info.Key
info.Key = fmt.Sprintf("%s_%s", prefix, info.Alt)
info.Alt = prefixedStructFieldName
}
}
info.Key, info.Alt = info.Alt, info.Key
}
info.Key = strings.ToUpper(info.Key)
info.Alt = strings.ToUpper(info.Alt)
Expand Down Expand Up @@ -211,9 +225,6 @@ func Process(prefix string, spec interface{}) error {
if !ok && def == "" {
if isTrue(req) {
key := info.Key
if info.Alt != "" {
key = info.Alt
}
return fmt.Errorf("required key %s missing value", key)
}
continue
Expand Down
23 changes: 20 additions & 3 deletions envconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ type Specification struct {
SomePointerWithDefault *string `default:"foo2baz" desc:"foorbar is the word"`
MultiWordVarWithAlt string `envconfig:"MULTI_WORD_VAR_WITH_ALT" desc:"what alt"`
MultiWordVarWithLowerCaseAlt string `envconfig:"multi_word_var_with_lower_case_alt"`
NoPrefixWithAlt string `envconfig:"SERVICE_HOST"`
NoPrefixWithAlt string `envconfig:"SERVICE_HOST" no_pfx:"alt"`
DefaultVar string `default:"foobar"`
RequiredVar string `required:"True"`
NoPrefixDefault string `envconfig:"BROKER" default:"127.0.0.1"`
NoPrefixDefault string `envconfig:"BROKER" default:"127.0.0.1" no_pfx:"alt"`
RequiredDefault string `required:"true" default:"foo2bar"`
Ignored string `ignored:"true"`
NestedSpecification struct {
Property string `envconfig:"inner"`
Property string `envconfig:"inner" no_pfx:"alt"`
PropertyWithDefault string `default:"fuzzybydefault"`
} `envconfig:"outer"`
AfterNested string
Expand Down Expand Up @@ -804,6 +804,23 @@ func TestErrorMessageForRequiredAltVar(t *testing.T) {
t.Error("no failure when missing required variable")
}

if !strings.Contains(err.Error(), " ENV_CONFIG_BAR ") {
t.Errorf("expected error message to contain BAR, got \"%v\"", err)
}
}

func TestErrorMessageForRequiredOverriddenKeyVar(t *testing.T) {
var s struct {
Foo string `envconfig:"BAR" required:"true" no_pfx:"key"`
}

os.Clearenv()
err := Process("env_config", &s)

if err == nil {
t.Error("no failure when missing required variable")
}

if !strings.Contains(err.Error(), " BAR ") {
t.Errorf("expected error message to contain BAR, got \"%v\"", err)
}
Expand Down

0 comments on commit b14df87

Please sign in to comment.