diff --git a/changes/202205121612.feature b/changes/202205121612.feature new file mode 100644 index 0000000000..5dfbbb29ae --- /dev/null +++ b/changes/202205121612.feature @@ -0,0 +1 @@ +Add option to run parseListWithCleanup to keep empty lines diff --git a/utils/collection/parseLists.go b/utils/collection/parseLists.go index 6a23262a29..2e72395490 100644 --- a/utils/collection/parseLists.go +++ b/utils/collection/parseLists.go @@ -4,12 +4,21 @@ */ package collection -import "strings" +import ( + "strings" + "unicode" +) -// ParseListWithCleanup splits a string into a list like strings.Split but also removes any whitespace surrounding the different items -// for example, -// ParseListWithCleanup("a, b , c", ",") returns []{"a","b","c"} -func ParseListWithCleanup(input string, sep string) (newS []string) { +func lineIsOnlyWhitespace(line string) bool { + for _, c := range line { + if !unicode.IsSpace(c) { + return false + } + } + return true +} + +func parseListWithCleanup(input string, sep string, keepBlankLines bool) (newS []string) { if len(input) == 0 { newS = []string{} // initialisation of empty arrays in function returns []string(nil) instead of []string{} return @@ -17,13 +26,28 @@ func ParseListWithCleanup(input string, sep string) (newS []string) { split := strings.Split(input, sep) for _, s := range split { tempString := strings.TrimSpace(s) - if tempString != "" { + if tempString != "" || (keepBlankLines && lineIsOnlyWhitespace(s)) { newS = append(newS, tempString) } } return } +// ParseListWithCleanup splits a string into a list like strings.Split but also removes any whitespace surrounding the different items +// for example, +// ParseListWithCleanup("a, b , c", ",") returns []{"a","b","c"} +func ParseListWithCleanup(input string, sep string) (newS []string) { + return parseListWithCleanup(input, sep, false) +} + +// ParseListWithCleanupKeepBlankLines splits a string into a list like strings.Split but also removes any whitespace surrounding the different items +// unless the entire item is whitespace in which case it is converted to an empty string. For example, +// ParseListWithCleanupKeepBlankLines("a, b , c", ",") returns []{"a","b","c"} +// ParseListWithCleanupKeepBlankLines("a, b , , c", ",") returns []{"a","b", "", "c"} +func ParseListWithCleanupKeepBlankLines(input string, sep string) (newS []string) { + return parseListWithCleanup(input, sep, true) +} + // ParseCommaSeparatedList returns the list of string separated by a comma func ParseCommaSeparatedList(input string) []string { return ParseListWithCleanup(input, ",") diff --git a/utils/collection/parseLists_test.go b/utils/collection/parseLists_test.go index 7f852c7f81..fc9b8bf147 100644 --- a/utils/collection/parseLists_test.go +++ b/utils/collection/parseLists_test.go @@ -50,3 +50,35 @@ func TestParseCommaSeparatedListWithSpacesBetweenWords(t *testing.T) { finalList := ParseCommaSeparatedList(stringList) require.Equal(t, stringArray, finalList) } + +func TestParseCommaSeparatedListWithSpacesBetweenWordsKeepBlanks(t *testing.T) { + stringList := "" + stringArray := []string{} + // we don't need cryptographically secure random numbers for generating a number of elements in a list + lengthOfList := rand.Intn(10) + 8 //nolint:gosec + for i := 0; i < lengthOfList; i++ { + word := faker.Sentence() + stringList += word + stringArray = append(stringArray, word) + numSpacesToAdd := rand.Intn(5) //nolint:gosec + for j := 0; j < numSpacesToAdd; j++ { + stringList += " " + } + stringList += "," + if i%3 == 2 { + numSpacesToAdd := rand.Intn(5) //nolint:gosec + for j := 0; j < numSpacesToAdd; j++ { + stringList += " " + } + stringArray = append(stringArray, "") + stringList += "," + } + } + stringArray = append(stringArray, "") // account for final , + + finalList1 := ParseCommaSeparatedList(stringList) + require.NotEqual(t, stringArray, finalList1) + + finalList2 := ParseListWithCleanupKeepBlankLines(stringList, ",") + require.Equal(t, stringArray, finalList2) +}