fix case where an environment variable containing an empty string is parsed into a slice or map

This commit is contained in:
Alex Flint 2021-04-20 19:09:47 -07:00
parent 9d937ba6c9
commit 2e81334206
2 changed files with 29 additions and 7 deletions

View File

@ -441,13 +441,17 @@ func (p *Parser) captureEnvVars(specs []*spec, wasPresent map[*spec]bool) error
if spec.cardinality == multiple {
// expect a CSV string in an environment
// variable in the case of multiple values
values, err := csv.NewReader(strings.NewReader(value)).Read()
if err != nil {
return fmt.Errorf(
"error reading a CSV string from environment variable %s with multiple values: %v",
spec.env,
err,
)
var values []string
var err error
if len(strings.TrimSpace(value)) > 0 {
values, err = csv.NewReader(strings.NewReader(value)).Read()
if err != nil {
return fmt.Errorf(
"error reading a CSV string from environment variable %s with multiple values: %v",
spec.env,
err,
)
}
}
if err = setSliceOrMap(p.val(spec.dest), values, !spec.separate); err != nil {
return fmt.Errorf(

View File

@ -721,6 +721,15 @@ func TestEnvironmentVariableSliceArgumentString(t *testing.T) {
assert.Equal(t, []string{"bar", "baz, qux"}, args.Foo)
}
func TestEnvironmentVariableSliceEmpty(t *testing.T) {
var args struct {
Foo []string `arg:"env"`
}
_, err := parseWithEnv("", []string{`FOO=`}, &args)
require.NoError(t, err)
assert.Len(t, args.Foo, 0)
}
func TestEnvironmentVariableSliceArgumentInteger(t *testing.T) {
var args struct {
Foo []int `arg:"env"`
@ -775,6 +784,15 @@ func TestEnvironmentVariableMap(t *testing.T) {
assert.Equal(t, "ninetynine", args.Foo[99])
}
func TestEnvironmentVariableEmptyMap(t *testing.T) {
var args struct {
Foo map[int]string `arg:"env"`
}
_, err := parseWithEnv("", []string{`FOO=`}, &args)
require.NoError(t, err)
assert.Len(t, args.Foo, 0)
}
func TestEnvironmentVariableIgnored(t *testing.T) {
var args struct {
Foo string `arg:"env"`