From 9bf0cbdf852ed04ceddf7e7d2fffeeb3f4fb2788 Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Mon, 31 Oct 2022 15:37:50 +0100 Subject: [PATCH] feat: add custom StringSliceFlag type that allows escaping (#21) --- drone/types.go | 40 ++++++++++++++++++++++++++++++++++++++++ drone/types_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 drone/types.go create mode 100644 drone/types_test.go diff --git a/drone/types.go b/drone/types.go new file mode 100644 index 0000000..3b3741b --- /dev/null +++ b/drone/types.go @@ -0,0 +1,40 @@ +package drone + +import ( + "strings" +) + +// StringSliceFlag is a flag type which support comma separated values and escaping to not split at unwanted lines +type StringSliceFlag struct { + slice []string +} + +func (s *StringSliceFlag) String() string { + return strings.Join(s.slice, " ") +} + +func (s *StringSliceFlag) Set(value string) error { + s.slice = splitWithEscaping(value, ",", "\\") + return nil +} + +func (s *StringSliceFlag) Get() []string { + return s.slice +} + +func splitWithEscaping(s, separator, escapeString string) []string { + if len(s) == 0 { + return []string{} + } + + a := strings.Split(s, separator) + + for i := len(a) - 2; i >= 0; i-- { + if strings.HasSuffix(a[i], escapeString) { + a[i] = a[i][:len(a[i])-len(escapeString)] + separator + a[i+1] + a = append(a[:i+1], a[i+2:]...) + } + } + + return a +} diff --git a/drone/types_test.go b/drone/types_test.go new file mode 100644 index 0000000..f5279f3 --- /dev/null +++ b/drone/types_test.go @@ -0,0 +1,27 @@ +package drone + +import ( + "reflect" + "testing" +) + +func TestSplitWithEscaping(t *testing.T) { + tests := []struct { + Input string + Output []string + }{ + {"", []string{}}, + {"a,b", []string{"a", "b"}}, + {",,,", []string{"", "", "", ""}}, + {",a\\,", []string{"", "a,"}}, + {"a,b\\,c\\\\d,e", []string{"a", "b,c\\\\d", "e"}}, + } + + for _, test := range tests { + strings := splitWithEscaping(test.Input, ",", "\\") + got, want := strings, test.Output + if !reflect.DeepEqual(got, want) { + t.Errorf("Got tag %v, want %v", got, want) + } + } +}