Skip to content

Commit

Permalink
Merge a6269ef into 9c5cfb5
Browse files Browse the repository at this point in the history
  • Loading branch information
akamensky committed Jan 29, 2023
2 parents 9c5cfb5 + a6269ef commit 0c3aa1e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 31 deletions.
11 changes: 8 additions & 3 deletions envparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func parseStruct(structType reflect.Type, env envMap, depth int, errorList *Erro
continue
}

tag, err := parseTag(tagString)
tag, err := parseTag(tagString, fieldType.Name)
if err != nil {
errorList.Append(err)
continue
Expand All @@ -77,7 +77,7 @@ func parseStruct(structType reflect.Type, env envMap, depth int, errorList *Erro
}

if tag.required {
if fieldValue.Type().Kind() == reflect.Struct {
if fieldValue.Type().Kind() == reflect.Struct || fieldValue.Type().Kind() == reflect.Slice {
if !env.PrefixExists(tag.name) {
// if field marked as required, but relevant environment variable is not provided,
// that is parsing error and can skip further processing of this field.
Expand Down Expand Up @@ -144,7 +144,12 @@ func parseSlice(sliceType reflect.Type, env envMap, depth int, errorList *ErrorL
assignableItem = item
}

err := switchFunc(assignableItem, env.GetPrefix(slicePrefix), slicePrefix, depth, errorList)
valueString := ""
if env.Exists(slicePrefix) {
valueString = env.Get(slicePrefix)
}

err := switchFunc(assignableItem, env.GetPrefix(slicePrefix), valueString, depth, errorList)
if err != nil {
errorList.Append(fmt.Errorf("error parsing slice: %w", err))
break
Expand Down
34 changes: 34 additions & 0 deletions envparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,37 @@ func TestParse_9(t *testing.T) {
t.Errorf("expected APP_TEST == '', but got APP_TEST == '%s'", os.Getenv("APP_TEST"))
}
}

func TestRequiredSliceOfStrings(t *testing.T) {
env := []string{
"APP_STRINGS_0=1",
}
type conf struct {
Strings []string `env:"name=strings,required"`
}
c := &conf{}
err := Parse(c, env)
if err != nil {
t.Errorf("unexpected error: %s", err)
}
if len(c.Strings) != 1 || c.Strings[0] != "1" {
t.Errorf("expected c.Strings[0] == '1', but got: %v", c.Strings)
}
}

func TestRequiredSliceOfInts(t *testing.T) {
env := []string{
"APP_INTS_0=1",
}
type conf struct {
Ints []int `env:"required"`
}
c := &conf{}
err := Parse(c, env)
if err != nil {
t.Errorf("unexpected error: %s", err)
}
if len(c.Ints) != 1 || c.Ints[0] != 1 {
t.Errorf("expected c.Ints[0] == 1, but got: %v", c.Ints)
}
}
5 changes: 2 additions & 3 deletions tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ type tagType struct {
}

var (
tagErrNameField = errors.New("field tag must provide a name for field")
tagErrIncompatibleFields = errors.New("field tag cannot be required and have default value at the same time")
)

func parseTag(t string) (*tagType, error) {
func parseTag(t string, fieldName string) (*tagType, error) {
name := ""
required := false
defaultValue := ""
Expand All @@ -34,7 +33,7 @@ func parseTag(t string) (*tagType, error) {
}

if name == "" {
return nil, tagErrNameField
name = strings.ToUpper(regexp.MustCompile(`[^A-Za-z0-9]`).ReplaceAllString(fieldName, ""))
}
if required && defaultValue != "" {
return nil, tagErrIncompatibleFields
Expand Down
32 changes: 7 additions & 25 deletions tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,12 @@ import (
func TestParseTag(t *testing.T) {
var in string
var expectedOut *tagType
expectedErr := tagErrNameField
tag, err := parseTag(in)
if tag != expectedOut {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
if expectedErr != err {
t.Errorf("expected error to be '%s', but got '%s'", expectedErr, err)
}

in = "name="
expectedOut = nil
expectedErr = tagErrNameField
tag, err = parseTag(in)
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
if expectedErr != err {
t.Errorf("expected error to be '%s', but got '%s'", expectedErr, err)
}
var expectedErr error

in = "name=HELLO1234_*\n/"
expectedOut = &tagType{name: "HELLO1234", required: false, defaultValue: ""}
expectedErr = nil
tag, err = parseTag(in)
tag, err := parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand All @@ -42,7 +24,7 @@ func TestParseTag(t *testing.T) {
in = "name=HELLO1234_*\n/,required"
expectedOut = &tagType{name: "HELLO1234", required: true, defaultValue: ""}
expectedErr = nil
tag, err = parseTag(in)
tag, err = parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand All @@ -53,7 +35,7 @@ func TestParseTag(t *testing.T) {
in = "name=HELLO1234_*\n/,default"
expectedOut = &tagType{name: "HELLO1234", required: false, defaultValue: ""}
expectedErr = nil
tag, err = parseTag(in)
tag, err = parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand All @@ -64,7 +46,7 @@ func TestParseTag(t *testing.T) {
in = "name=HELLO1234_*\n/,default=12"
expectedOut = &tagType{name: "HELLO1234", required: false, defaultValue: "12"}
expectedErr = nil
tag, err = parseTag(in)
tag, err = parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand All @@ -75,7 +57,7 @@ func TestParseTag(t *testing.T) {
in = "name=HELLO1234_*\n/,default=,required"
expectedOut = &tagType{name: "HELLO1234", required: true, defaultValue: ""}
expectedErr = nil
tag, err = parseTag(in)
tag, err = parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand All @@ -86,7 +68,7 @@ func TestParseTag(t *testing.T) {
in = "name=HELLO1234_*\n/,default=12,required"
expectedOut = nil
expectedErr = tagErrIncompatibleFields
tag, err = parseTag(in)
tag, err = parseTag(in, "")
if !reflect.DeepEqual(tag, expectedOut) {
t.Errorf("expected tag to be %v, but got %v", expectedOut, tag)
}
Expand Down

0 comments on commit 0c3aa1e

Please sign in to comment.