Skip to content

Commit 4559ae9

Browse files
authored
Merge pull request #1675 from palsivertsen/v2-maint
Make trim space optional
2 parents 2389448 + 30bb798 commit 4559ae9

7 files changed

+73
-3
lines changed

app_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ func ExampleApp_Run_sliceValues() {
428428
// 0-float64Sclice cli.Float64Slice{slice:[]float64{13.3, 14.4, 15.5, 16.6}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
429429
// 1-int64Sclice cli.Int64Slice{slice:[]int64{13, 14, 15, 16}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
430430
// 2-intSclice cli.IntSlice{slice:[]int{13, 14, 15, 16}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
431-
// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true}
431+
// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, separator:cli.separatorSpec{sep:"", disabled:false, customized:false}, hasBeenSet:true, keepSpace:false}
432432
// error: <nil>
433433
}
434434

flag-spec.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ flag_types:
101101
type: bool
102102
- name: Action
103103
type: "func(*Context, []string) error"
104+
- name: KeepSpace
105+
type: bool
104106
time.Duration:
105107
struct_fields:
106108
- name: Action

flag_string_slice.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type StringSlice struct {
1313
slice []string
1414
separator separatorSpec
1515
hasBeenSet bool
16+
keepSpace bool
1617
}
1718

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

4748
for _, t := range s.separator.flagSplitMultiValues(value) {
49+
if !s.keepSpace {
50+
t = strings.TrimSpace(t)
51+
}
4852
s.slice = append(s.slice, t)
4953
}
5054

@@ -149,9 +153,14 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
149153
setValue.WithSeparatorSpec(f.separator)
150154
}
151155

156+
setValue.keepSpace = f.KeepSpace
157+
152158
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
153159
for _, s := range f.separator.flagSplitMultiValues(val) {
154-
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
160+
if !f.KeepSpace {
161+
s = strings.TrimSpace(s)
162+
}
163+
if err := setValue.Set(s); err != nil {
155164
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
156165
}
157166
}

flag_test.go

+54-1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ func TestFlagsFromEnv(t *testing.T) {
144144
s.hasBeenSet = false
145145
return *s
146146
}
147+
newSetStringSliceKeepSpace := func(defaults ...string) StringSlice {
148+
s := newSetStringSlice(defaults...)
149+
s.keepSpace = true
150+
return s
151+
}
147152

148153
var flagTests = []struct {
149154
input string
@@ -198,6 +203,8 @@ func TestFlagsFromEnv(t *testing.T) {
198203
{"path", "path", &PathFlag{Name: "path", EnvVars: []string{"PATH"}}, ""},
199204

200205
{"foo,bar", newSetStringSlice("foo", "bar"), &StringSliceFlag{Name: "names", EnvVars: []string{"NAMES"}}, ""},
206+
{" space ", newSetStringSliceKeepSpace(" space "), &StringSliceFlag{Name: "names", KeepSpace: true, EnvVars: []string{"NAMES"}}, ""},
207+
{" no space ", newSetStringSlice("no space"), &StringSliceFlag{Name: "names", EnvVars: []string{"NAMES"}}, ""},
201208

202209
{"1", uint(1), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
203210
{"08", uint(8), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}, Base: 10}, ""},
@@ -774,7 +781,7 @@ func TestStringSliceFlag_MatchStringFlagBehavior(t *testing.T) {
774781
app := App{
775782
Flags: []Flag{
776783
&StringFlag{Name: "string"},
777-
&StringSliceFlag{Name: "slice"},
784+
&StringSliceFlag{Name: "slice", KeepSpace: true},
778785
},
779786
Action: func(ctx *Context) error {
780787
f1, f2 := ctx.String("string"), ctx.StringSlice("slice")
@@ -797,6 +804,52 @@ func TestStringSliceFlag_MatchStringFlagBehavior(t *testing.T) {
797804
}
798805
}
799806

807+
func TestStringSliceFlag_TrimSpace(t *testing.T) {
808+
t.Parallel()
809+
810+
tests := []struct {
811+
in, out string
812+
}{
813+
{" asd", "asd"},
814+
{"123 ", "123"},
815+
{" asd ", "asd"},
816+
}
817+
for testNum, tt := range tests {
818+
tt := tt
819+
t.Run(fmt.Sprintf("%d", testNum), func(t *testing.T) {
820+
t.Parallel()
821+
822+
app := App{
823+
Flags: []Flag{
824+
&StringSliceFlag{Name: "trim"},
825+
&StringSliceFlag{Name: "no-trim", KeepSpace: true},
826+
},
827+
Action: func(ctx *Context) error {
828+
flagTrim, flagNoTrim := ctx.StringSlice("trim"), ctx.StringSlice("no-trim")
829+
if l := len(flagTrim); l != 1 {
830+
t.Fatalf("slice flag 'trim' should result in exactly one value, got %d", l)
831+
}
832+
if l := len(flagNoTrim); l != 1 {
833+
t.Fatalf("slice flag 'no-trim' should result in exactly one value, got %d", l)
834+
}
835+
836+
if v := flagTrim[0]; v != tt.out {
837+
t.Errorf("Expected trimmed value %q, got %q", tt.out, v)
838+
}
839+
if v := flagNoTrim[0]; v != tt.in {
840+
t.Errorf("Expected no trimmed value%q, got %q", tt.out, v)
841+
}
842+
return nil
843+
},
844+
}
845+
846+
if err := app.Run([]string{"", "--trim", tt.in, "--no-trim", tt.in}); err != nil {
847+
t.Errorf("app run error: %s", err)
848+
}
849+
})
850+
}
851+
}
852+
800853
var intFlagTests = []struct {
801854
name string
802855
expected string

godoc-current.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,8 @@ type StringSliceFlag struct {
18271827
TakesFile bool
18281828

18291829
Action func(*Context, []string) error
1830+
1831+
KeepSpace bool
18301832
// Has unexported fields.
18311833
}
18321834
StringSliceFlag is a flag with type *StringSlice

testdata/godoc-v2.x.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,8 @@ type StringSliceFlag struct {
18271827
TakesFile bool
18281828

18291829
Action func(*Context, []string) error
1830+
1831+
KeepSpace bool
18301832
// Has unexported fields.
18311833
}
18321834
StringSliceFlag is a flag with type *StringSlice

zz_generated.flags.go

+2
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ type StringSliceFlag struct {
270270
TakesFile bool
271271

272272
Action func(*Context, []string) error
273+
274+
KeepSpace bool
273275
}
274276

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

0 commit comments

Comments
 (0)