diff --git a/cli/clibase/option.go b/cli/clibase/option.go index 836517979db6c..f56e333ae4577 100644 --- a/cli/clibase/option.go +++ b/cli/clibase/option.go @@ -105,6 +105,8 @@ func (s *OptionSet) ParseEnv(vs []EnvVar) error { return nil } + stringArrayType := StringArray{}.Type() + var merr *multierror.Error // We parse environment variables first instead of using a nested loop to @@ -126,7 +128,7 @@ func (s *OptionSet) ParseEnv(vs []EnvVar) error { // way for a user to change a Default value to an empty string from // the environment. Unfortunately, we have old configuration files // that rely on the faulty behavior. - if !ok || envVal == "" { + if !ok || (envVal == "" && opt.Value.Type() != stringArrayType) { continue } diff --git a/cli/clibase/option_test.go b/cli/clibase/option_test.go index d9d38cc6c7bd9..b3d950b55cb65 100644 --- a/cli/clibase/option_test.go +++ b/cli/clibase/option_test.go @@ -118,4 +118,26 @@ func TestOptionSet_ParseEnv(t *testing.T) { require.NoError(t, err) require.EqualValues(t, "defname", workspaceName) }) + + t.Run("EmptyStringArrayValue", func(t *testing.T) { + t.Parallel() + + var workspaceNames clibase.StringArray + + os := clibase.OptionSet{ + clibase.Option{ + Name: "Workspace Names", + Value: &workspaceNames, + Default: "defname", + Env: "WORKSPACE_NAMES", + }, + } + + err := os.SetDefaults() + require.NoError(t, err) + + err = os.ParseEnv(clibase.ParseEnviron([]string{"CODER_WORKSPACE_NAMES="}, "CODER_")) + require.NoError(t, err) + require.EqualValues(t, []string{}, workspaceNames) + }) } diff --git a/cli/clibase/values.go b/cli/clibase/values.go index acb4cab5d50f7..ed8fb93d975b1 100644 --- a/cli/clibase/values.go +++ b/cli/clibase/values.go @@ -146,6 +146,11 @@ func writeAsCSV(vals []string) string { } func (s *StringArray) Set(v string) error { + if v == "" { + *s = []string{} + return nil + } + ss, err := readAsCSV(v) if err != nil { return err