Skip to content

Commit 1645281

Browse files
authored
fix(clibase): allow empty values to unset defaults (#6832)
1 parent 773580c commit 1645281

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

cli/clibase/cmd.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,19 @@ func (i *Invocation) run(state *runState) error {
293293
return
294294
}
295295

296+
// If flag was changed, we need to remove the default values.
296297
sv, ok := f.Value.(pflag.SliceValue)
297298
if !ok {
298299
panic("defaulted array option is not a slice value")
299300
}
300-
err := sv.Replace(sv.GetSlice()[i:])
301+
ss := sv.GetSlice()
302+
if len(ss) == 0 {
303+
// Slice likely zeroed by a flag.
304+
// E.g. "--fruit" may default to "apples,oranges" but the user
305+
// provided "--fruit=""".
306+
return
307+
}
308+
err := sv.Replace(ss[i:])
301309
if err != nil {
302310
panic(err)
303311
}

cli/clibase/cmd_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,35 @@ func TestCommand_SliceFlags(t *testing.T) {
503503
err = cmd("bad", "bad", "bad").Invoke().Run()
504504
require.NoError(t, err)
505505
}
506+
507+
func TestCommand_EmptySlice(t *testing.T) {
508+
t.Parallel()
509+
510+
cmd := func(want ...string) *clibase.Cmd {
511+
var got []string
512+
return &clibase.Cmd{
513+
Use: "root",
514+
Options: clibase.OptionSet{
515+
{
516+
Name: "arr",
517+
Flag: "arr",
518+
Default: "bad,bad,bad",
519+
Env: "ARR",
520+
Value: clibase.StringArrayOf(&got),
521+
},
522+
},
523+
Handler: (func(i *clibase.Invocation) error {
524+
require.Equal(t, want, got)
525+
return nil
526+
}),
527+
}
528+
}
529+
530+
// Base-case
531+
err := cmd("bad", "bad", "bad").Invoke().Run()
532+
require.NoError(t, err)
533+
534+
inv := cmd().Invoke("--arr", "")
535+
err = inv.Run()
536+
require.NoError(t, err)
537+
}

cli/clibase/option.go

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ func (s *OptionSet) ParseEnv(vs []EnvVar) error {
126126
// way for a user to change a Default value to an empty string from
127127
// the environment. Unfortunately, we have old configuration files
128128
// that rely on the faulty behavior.
129+
//
130+
// TODO: We should remove this hack in May 2023, when deployments
131+
// have had months to migrate to the new behavior.
129132
if !ok || envVal == "" {
130133
continue
131134
}

cli/clibase/values.go

+4
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ func writeAsCSV(vals []string) string {
146146
}
147147

148148
func (s *StringArray) Set(v string) error {
149+
if v == "" {
150+
*s = nil
151+
return nil
152+
}
149153
ss, err := readAsCSV(v)
150154
if err != nil {
151155
return err

0 commit comments

Comments
 (0)