Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make trim space optional #1675

Merged
merged 4 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, keepSpace: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: KeepSpace
type: bool
time.Duration:
struct_fields:
- name: Action
Expand Down
11 changes: 10 additions & 1 deletion flag_string_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type StringSlice struct {
slice []string
separator separatorSpec
hasBeenSet bool
keepSpace 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.keepSpace {
t = strings.TrimSpace(t)
}
s.slice = append(s.slice, t)
}

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

setValue.keepSpace = f.KeepSpace

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 {
if !f.KeepSpace {
s = strings.TrimSpace(s)
}
if err := setValue.Set(s); err != nil {
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
}
}
Expand Down
55 changes: 54 additions & 1 deletion flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func TestFlagsFromEnv(t *testing.T) {
s.hasBeenSet = false
return *s
}
newSetStringSliceKeepSpace := func(defaults ...string) StringSlice {
s := newSetStringSlice(defaults...)
s.keepSpace = true
return s
}

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

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

{"1", uint(1), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
{"08", uint(8), &UintFlag{Name: "seconds", EnvVars: []string{"SECONDS"}, Base: 10}, ""},
Expand Down Expand Up @@ -774,7 +781,7 @@ func TestStringSliceFlag_MatchStringFlagBehavior(t *testing.T) {
app := App{
Flags: []Flag{
&StringFlag{Name: "string"},
&StringSliceFlag{Name: "slice"},
&StringSliceFlag{Name: "slice", KeepSpace: true},
},
Action: func(ctx *Context) error {
f1, f2 := ctx.String("string"), ctx.StringSlice("slice")
Expand All @@ -797,6 +804,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", KeepSpace: 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 godoc-current.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,8 @@ type StringSliceFlag struct {
TakesFile bool

Action func(*Context, []string) error

KeepSpace bool
// Has unexported fields.
}
StringSliceFlag is a flag with type *StringSlice
Expand Down
2 changes: 2 additions & 0 deletions testdata/godoc-v2.x.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,8 @@ type StringSliceFlag struct {
TakesFile bool

Action func(*Context, []string) error

KeepSpace bool
// Has unexported fields.
}
StringSliceFlag is a flag with type *StringSlice
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

KeepSpace bool
}

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