Skip to content

Commit

Permalink
Fixes #1648
Browse files Browse the repository at this point in the history
This adds a new field to the `FlagStringSlice` struct for controlling
the trimming of space when parsing arguments. The new field is called
`NoTrimSpace` and trims space by default. This is to not break existing
programs that depends on this behavior. See
#1649 (comment) for
further details.
  • Loading branch information
palsivertsen committed Jan 31, 2023
1 parent 2389448 commit 12b6187
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 5 deletions.
2 changes: 1 addition & 1 deletion app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ func ExampleApp_Run_sliceValues() {
// 0-float64Sclice cli.Float64Slice{slice:[]float64{13.3, 14.4, 15.5, 16.6}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
// 1-int64Sclice cli.Int64Slice{slice:[]int64{13, 14, 15, 16}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
// 2-intSclice cli.IntSlice{slice:[]int{13, 14, 15, 16}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true, noTrimSpace:false}
// error: <nil>
}

Expand Down
2 changes: 2 additions & 0 deletions flag-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ flag_types:
type: bool
- name: Action
type: "func(*Context, []string) error"
- name: NoTrimSpace
type: bool
time.Duration:
struct_fields:
- name: Action
Expand Down
12 changes: 9 additions & 3 deletions flag_string_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (

// StringSlice wraps a []string to satisfy flag.Value
type StringSlice struct {
slice []string
separator separatorSpec
hasBeenSet bool
slice []string
separator separatorSpec
hasBeenSet bool
noTrimSpace bool
}

// NewStringSlice creates a *StringSlice with default values
Expand Down Expand Up @@ -45,6 +46,9 @@ func (s *StringSlice) Set(value string) error {
}

for _, t := range s.separator.flagSplitMultiValues(value) {
if !s.noTrimSpace {
t = strings.TrimSpace(t)
}
s.slice = append(s.slice, t)
}

Expand Down Expand Up @@ -149,6 +153,8 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
setValue.WithSeparatorSpec(f.separator)
}

setValue.noTrimSpace = f.NoTrimSpace

if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
for _, s := range f.separator.flagSplitMultiValues(val) {
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
Expand Down
48 changes: 47 additions & 1 deletion flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ func TestStringSliceFlag_MatchStringFlagBehavior(t *testing.T) {
app := App{
Flags: []Flag{
&StringFlag{Name: "string"},
&StringSliceFlag{Name: "slice"},
&StringSliceFlag{Name: "slice", NoTrimSpace: true},
},
Action: func(ctx *Context) error {
f1, f2 := ctx.String("string"), ctx.StringSlice("slice")
Expand All @@ -797,6 +797,52 @@ func TestStringSliceFlag_MatchStringFlagBehavior(t *testing.T) {
}
}

func TestStringSliceFlag_TrimSpace(t *testing.T) {
t.Parallel()

tests := []struct {
in, out string
}{
{" asd", "asd"},
{"123 ", "123"},
{" asd ", "asd"},
}
for testNum, tt := range tests {
tt := tt
t.Run(fmt.Sprintf("%d", testNum), func(t *testing.T) {
t.Parallel()

app := App{
Flags: []Flag{
&StringSliceFlag{Name: "trim"},
&StringSliceFlag{Name: "no-trim", NoTrimSpace: true},
},
Action: func(ctx *Context) error {
flagTrim, flagNoTrim := ctx.StringSlice("trim"), ctx.StringSlice("no-trim")
if l := len(flagTrim); l != 1 {
t.Fatalf("slice flag 'trim' should result in exactly one value, got %d", l)
}
if l := len(flagNoTrim); l != 1 {
t.Fatalf("slice flag 'no-trim' should result in exactly one value, got %d", l)
}

if v := flagTrim[0]; v != tt.out {
t.Errorf("Expected trimmed value %q, got %q", tt.out, v)
}
if v := flagNoTrim[0]; v != tt.in {
t.Errorf("Expected no trimmed value%q, got %q", tt.out, v)
}
return nil
},
}

if err := app.Run([]string{"", "--trim", tt.in, "--no-trim", tt.in}); err != nil {
t.Errorf("app run error: %s", err)
}
})
}
}

var intFlagTests = []struct {
name string
expected string
Expand Down
2 changes: 2 additions & 0 deletions zz_generated.flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ type StringSliceFlag struct {
TakesFile bool

Action func(*Context, []string) error

NoTrimSpace bool
}

// IsSet returns whether or not the flag has been set through env or file
Expand Down

0 comments on commit 12b6187

Please sign in to comment.