From 2d704e89528831ebe084c63f3873ac2c786c7351 Mon Sep 17 00:00:00 2001 From: fgy Date: Mon, 24 Oct 2022 11:51:59 +0800 Subject: [PATCH 1/3] feat: customized slice flag separator --- app.go | 6 ++++++ flag.go | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index 24704e8f7b..9bea11efde 100644 --- a/app.go +++ b/app.go @@ -103,6 +103,8 @@ type App struct { // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. CustomAppHelpTemplate string + // SliceFlagSeparator is used to customize the separator for SliceFlag, the default is "," + SliceFlagSeparator string // Boolean to enable short-option handling so user can combine several // single-character bool arguments into one // i.e. foobar -o -v -> foobar -ov @@ -241,6 +243,10 @@ func (a *App) Setup() { if a.Metadata == nil { a.Metadata = make(map[string]interface{}) } + + if len(a.SliceFlagSeparator) != 0 { + defaultSliceFlagSeparator = a.SliceFlagSeparator + } } func (a *App) newRootCommand() *Command { diff --git a/flag.go b/flag.go index 7535424c04..b66a75da5e 100644 --- a/flag.go +++ b/flag.go @@ -15,6 +15,8 @@ import ( const defaultPlaceholder = "value" +var defaultSliceFlagSeparator = "," + var ( slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano()) @@ -378,5 +380,5 @@ func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhe } func flagSplitMultiValues(val string) []string { - return strings.Split(val, ",") + return strings.Split(val, defaultSliceFlagSeparator) } From c5da5f61bc973745544c780f4589a09001904f64 Mon Sep 17 00:00:00 2001 From: fgy Date: Tue, 25 Oct 2022 14:27:22 +0800 Subject: [PATCH 2/3] feat: modify go doc --- flag_test.go | 27 +++++++++++++++++++++++++++ godoc-current.txt | 2 ++ testdata/godoc-v2.x.txt | 2 ++ 3 files changed, 31 insertions(+) diff --git a/flag_test.go b/flag_test.go index d46c1a70f7..832b81844a 100644 --- a/flag_test.go +++ b/flag_test.go @@ -3384,3 +3384,30 @@ func TestSliceShortOptionHandle(t *testing.T) { t.Fatal("Action callback was never called") } } + +// Test issue #1541 +func TestCustomizedSliceFlagSeparator(t *testing.T) { + opts := []string{"opt1", "opt2", "opt3,op", "opt4"} + // set args for examples sake + os.Args = []string{"multi_values", + "--stringSlice=" + strings.Join(opts, ";"), + } + app := NewApp() + app.Name = "multi_values" + app.Flags = []Flag{ + &StringSliceFlag{Name: "stringSlice"}, + } + app.SliceFlagSeparator = ";" + app.Action = func(ctx *Context) error { + ret := ctx.StringSlice("stringSlice") + for idx, r := range ret { + if r != opts[idx] { + t.Fatalf("get %dth failed, wanted: %s, but get: %s", idx, opts[idx], r) + } + } + return nil + } + + _ = app.Run(os.Args) + defaultSliceFlagSeparator = "," +} diff --git a/godoc-current.txt b/godoc-current.txt index e16d6ab738..fadb7f8629 100644 --- a/godoc-current.txt +++ b/godoc-current.txt @@ -316,6 +316,8 @@ type App struct { // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. CustomAppHelpTemplate string + // SliceFlagSeparator is used to customize the separator for SliceFlag, the default is "," + SliceFlagSeparator string // Boolean to enable short-option handling so user can combine several // single-character bool arguments into one // i.e. foobar -o -v -> foobar -ov diff --git a/testdata/godoc-v2.x.txt b/testdata/godoc-v2.x.txt index e16d6ab738..fadb7f8629 100644 --- a/testdata/godoc-v2.x.txt +++ b/testdata/godoc-v2.x.txt @@ -316,6 +316,8 @@ type App struct { // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. CustomAppHelpTemplate string + // SliceFlagSeparator is used to customize the separator for SliceFlag, the default is "," + SliceFlagSeparator string // Boolean to enable short-option handling so user can combine several // single-character bool arguments into one // i.e. foobar -o -v -> foobar -ov From 957957f34f92bda0345052d67cba5d2bb86f09f1 Mon Sep 17 00:00:00 2001 From: fgy Date: Thu, 27 Oct 2022 15:38:38 +0800 Subject: [PATCH 3/3] feat: update unit test --- flag_test.go | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/flag_test.go b/flag_test.go index 832b81844a..3a2bc2b67e 100644 --- a/flag_test.go +++ b/flag_test.go @@ -3387,27 +3387,18 @@ func TestSliceShortOptionHandle(t *testing.T) { // Test issue #1541 func TestCustomizedSliceFlagSeparator(t *testing.T) { + defaultSliceFlagSeparator = ";" + defer func() { + defaultSliceFlagSeparator = "," + }() opts := []string{"opt1", "opt2", "opt3,op", "opt4"} - // set args for examples sake - os.Args = []string{"multi_values", - "--stringSlice=" + strings.Join(opts, ";"), - } - app := NewApp() - app.Name = "multi_values" - app.Flags = []Flag{ - &StringSliceFlag{Name: "stringSlice"}, - } - app.SliceFlagSeparator = ";" - app.Action = func(ctx *Context) error { - ret := ctx.StringSlice("stringSlice") - for idx, r := range ret { - if r != opts[idx] { - t.Fatalf("get %dth failed, wanted: %s, but get: %s", idx, opts[idx], r) - } + ret := flagSplitMultiValues(strings.Join(opts, ";")) + if len(ret) != 4 { + t.Fatalf("split slice flag failed, want: 4, but get: %d", len(ret)) + } + for idx, r := range ret { + if r != opts[idx] { + t.Fatalf("get %dth failed, wanted: %s, but get: %s", idx, opts[idx], r) } - return nil } - - _ = app.Run(os.Args) - defaultSliceFlagSeparator = "," }