diff --git a/helper/strutil/strutil.go b/helper/strutil/strutil.go index a77e60d15..0da186a7c 100644 --- a/helper/strutil/strutil.go +++ b/helper/strutil/strutil.go @@ -43,9 +43,9 @@ func StrListSubset(super, sub []string) bool { return true } -// Parses a comma separated list of strings into a slice of strings. -// The return slice will be sorted and will not contain duplicate or -// empty items. +// ParseDedupAndSortStrings parses a comma separated list of strings +// into a slice of strings. The return slice will be sorted and will +// not contain duplicate or empty items. func ParseDedupAndSortStrings(input string, sep string) []string { input = strings.TrimSpace(input) parsed := []string{} @@ -56,9 +56,10 @@ func ParseDedupAndSortStrings(input string, sep string) []string { return RemoveDuplicates(strings.Split(input, sep), false) } -// Parses a comma separated list of strings into a slice of strings. -// The return slice will be sorted and will not contain duplicate or -// empty items. The values will be converted to lower case. +// ParseDedupLowercaseAndSortStrings parses a comma separated list of +// strings into a slice of strings. The return slice will be sorted and +// will not contain duplicate or empty items. The values will be converted +// to lower case. func ParseDedupLowercaseAndSortStrings(input string, sep string) []string { input = strings.TrimSpace(input) parsed := []string{} @@ -69,8 +70,8 @@ func ParseDedupLowercaseAndSortStrings(input string, sep string) []string { return RemoveDuplicates(strings.Split(input, sep), true) } -// Parses a comma separated list of `=` tuples into a -// map[string]string. +// ParseKeyValues parses a comma separated list of `=` tuples +// into a map[string]string. func ParseKeyValues(input string, out map[string]string, sep string) error { if out == nil { return fmt.Errorf("'out is nil") @@ -97,8 +98,8 @@ func ParseKeyValues(input string, out map[string]string, sep string) error { return nil } -// Parses arbitrary tuples. The input can be one of -// the following: +// ParseArbitraryKeyValues parses arbitrary tuples. The input +// can be one of the following: // * JSON string // * Base64 encoded JSON string // * Comma separated list of `=` pairs @@ -144,8 +145,8 @@ func ParseArbitraryKeyValues(input string, out map[string]string, sep string) er return nil } -// Parses a `sep`-separated list of strings into a -// []string. +// ParseStringSlice parses a `sep`-separated list of strings into a +// []string with surrounding whitespace removed. // // The output will always be a valid slice but may be of length zero. func ParseStringSlice(input string, sep string) []string { @@ -157,14 +158,14 @@ func ParseStringSlice(input string, sep string) []string { splitStr := strings.Split(input, sep) ret := make([]string, len(splitStr)) for i, val := range splitStr { - ret[i] = val + ret[i] = strings.TrimSpace(val) } return ret } -// Parses arbitrary string slice. The input can be one of -// the following: +// ParseArbitraryStringSlice parses arbitrary string slice. The input +// can be one of the following: // * JSON string // * Base64 encoded JSON string // * `sep` separated list of values @@ -215,8 +216,9 @@ func TrimStrings(items []string) []string { return ret } -// Removes duplicate and empty elements from a slice of strings. This also may -// convert the items in the slice to lower case and returns a sorted slice. +// RemoveDuplicates removes duplicate and empty elements from a slice of +// strings. This also may convert the items in the slice to lower case and +// returns a sorted slice. func RemoveDuplicates(items []string, lowercase bool) []string { itemsMap := map[string]bool{} for _, item := range items { @@ -230,7 +232,7 @@ func RemoveDuplicates(items []string, lowercase bool) []string { itemsMap[item] = true } items = make([]string, 0, len(itemsMap)) - for item, _ := range itemsMap { + for item := range itemsMap { items = append(items, item) } sort.Strings(items) @@ -260,10 +262,10 @@ func EquivalentSlices(a, b []string) bool { // Now we'll build our checking slices var sortedA, sortedB []string - for keyA, _ := range mapA { + for keyA := range mapA { sortedA = append(sortedA, keyA) } - for keyB, _ := range mapB { + for keyB := range mapB { sortedB = append(sortedB, keyB) } sort.Strings(sortedA) @@ -299,6 +301,8 @@ func StrListDelete(s []string, d string) []string { return s } +// GlobbedStringsMatch compares item to val with support for a leading and/or +// trailing wildcard '*' in item. func GlobbedStringsMatch(item, val string) bool { if len(item) < 2 { return val == item diff --git a/helper/strutil/strutil_test.go b/helper/strutil/strutil_test.go index e0196a660..4efd03488 100644 --- a/helper/strutil/strutil_test.go +++ b/helper/strutil/strutil_test.go @@ -423,3 +423,29 @@ func TestStrUtil_RemoveDuplicates(t *testing.T) { } } } + +func TestStrUtil_ParseStringSlice(t *testing.T) { + type tCase struct { + input string + sep string + expect []string + } + + tCases := []tCase{ + tCase{"", "", []string{}}, + tCase{" ", ",", []string{}}, + tCase{", ", ",", []string{"", ""}}, + tCase{"a", ",", []string{"a"}}, + tCase{" a, b, c ", ",", []string{"a", "b", "c"}}, + tCase{" a; b; c ", ";", []string{"a", "b", "c"}}, + tCase{" a :: b :: c ", "::", []string{"a", "b", "c"}}, + } + + for _, tc := range tCases { + actual := ParseStringSlice(tc.input, tc.sep) + + if !reflect.DeepEqual(actual, tc.expect) { + t.Fatalf("Bad testcase %#v, expected %v, got %v", tc, tc.expect, actual) + } + } +}