From 86dd74fd62ffc60e8765cdd09f8d4304a1ff64d8 Mon Sep 17 00:00:00 2001 From: monopole Date: Thu, 10 Jun 2021 13:32:34 -0700 Subject: [PATCH] Gather some string slice utils. --- api/filters/imagetag/legacy.go | 12 ++----- api/internal/utils/stringslice.go | 44 ++++++++++++++++++++++++++ api/internal/utils/stringslice_test.go | 37 ++++++++++++++++++++++ api/resource/resource.go | 19 ++--------- api/resource/resource_test.go | 3 +- 5 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 api/internal/utils/stringslice.go create mode 100644 api/internal/utils/stringslice_test.go diff --git a/api/filters/imagetag/legacy.go b/api/filters/imagetag/legacy.go index 5014e9c82..d07080b8e 100644 --- a/api/filters/imagetag/legacy.go +++ b/api/filters/imagetag/legacy.go @@ -4,6 +4,7 @@ package imagetag import ( + "sigs.k8s.io/kustomize/api/internal/utils" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -74,7 +75,7 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error { return err } key := n.Key.YNode().Value - if contains(f.fields, key) { + if utils.StringSliceContains(f.fields, key) { return f.fieldCallback(n.Value) } return nil @@ -87,15 +88,6 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error { return nil } -func contains(slice []string, str string) bool { - for _, s := range slice { - if s == str { - return true - } - } - return false -} - func checkImageTagsFn(imageTag types.Image) fieldCallback { return func(node *yaml.RNode) error { if node.YNode().Kind != yaml.SequenceNode { diff --git a/api/internal/utils/stringslice.go b/api/internal/utils/stringslice.go new file mode 100644 index 000000000..3dc422725 --- /dev/null +++ b/api/internal/utils/stringslice.go @@ -0,0 +1,44 @@ +// Copyright 2020 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package utils + +// StringSliceIndex returns the index of the str, else -1. +func StringSliceIndex(slice []string, str string) int { + for i := range slice { + if slice[i] == str { + return i + } + } + return -1 +} + +// StringSliceContains returns true if the slice has the string. +func StringSliceContains(slice []string, str string) bool { + for _, s := range slice { + if s == str { + return true + } + } + return false +} + +// SameEndingSubSlice returns true if the slices end the same way, e.g. +// {"a", "b", "c"}, {"b", "c"} => true +// {"a", "b", "c"}, {"a", "b"} => false +// If one slice is empty and the other is not, return false. +func SameEndingSubSlice(shortest, longest []string) bool { + if len(shortest) > len(longest) { + longest, shortest = shortest, longest + } + diff := len(longest) - len(shortest) + if len(shortest) == 0 { + return diff == 0 + } + for i := len(shortest) - 1; i >= 0; i-- { + if longest[i+diff] != shortest[i] { + return false + } + } + return true +} diff --git a/api/internal/utils/stringslice_test.go b/api/internal/utils/stringslice_test.go new file mode 100644 index 000000000..d80693490 --- /dev/null +++ b/api/internal/utils/stringslice_test.go @@ -0,0 +1,37 @@ +// Copyright 2020 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package utils_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + . "sigs.k8s.io/kustomize/api/internal/utils" +) + +func TestStringSliceIndex(t *testing.T) { + assert.Equal(t, 0, StringSliceIndex([]string{"a", "b"}, "a")) + assert.Equal(t, 1, StringSliceIndex([]string{"a", "b"}, "b")) + assert.Equal(t, -1, StringSliceIndex([]string{"a", "b"}, "c")) + assert.Equal(t, -1, StringSliceIndex([]string{}, "c")) +} + +func TestStringSliceContains(t *testing.T) { + assert.True(t, StringSliceContains([]string{"a", "b"}, "a")) + assert.True(t, StringSliceContains([]string{"a", "b"}, "b")) + assert.False(t, StringSliceContains([]string{"a", "b"}, "c")) + assert.False(t, StringSliceContains([]string{}, "c")) +} + +func TestSameEndingSubarray(t *testing.T) { + assert.True(t, SameEndingSubSlice([]string{"", "a", "b"}, []string{"a", "b"})) + assert.True(t, SameEndingSubSlice([]string{"a", "b", ""}, []string{"b", ""})) + assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"a", "b"})) + assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b"})) + assert.True(t, SameEndingSubSlice([]string{"b"}, []string{"a", "b"})) + assert.True(t, SameEndingSubSlice([]string{}, []string{})) + assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b", "a"})) + assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{})) + assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{""})) +} diff --git a/api/resource/resource.go b/api/resource/resource.go index e93f54890..c7065a385 100644 --- a/api/resource/resource.go +++ b/api/resource/resource.go @@ -199,22 +199,6 @@ func (r *Resource) appendCsvAnnotation(name, value string) { } } -func SameEndingSubarray(shortest, longest []string) bool { - if len(shortest) > len(longest) { - longest, shortest = shortest, longest - } - diff := len(longest) - len(shortest) - if len(shortest) == 0 { - return diff == 0 - } - for i := len(shortest) - 1; i >= 0; i-- { - if longest[i+diff] != shortest[i] { - return false - } - } - return true -} - // Implements ResCtx GetNamePrefixes func (r *Resource) GetNamePrefixes() []string { return r.getCsvAnnotation(utils.BuildAnnotationPrefixes) @@ -237,7 +221,8 @@ func (r *Resource) getCsvAnnotation(name string) []string { // as OutermostPrefixSuffix but performs a deeper comparison // of the suffix and prefix slices. func (r *Resource) PrefixesSuffixesEquals(o ResCtx) bool { - return SameEndingSubarray(r.GetNamePrefixes(), o.GetNamePrefixes()) && SameEndingSubarray(r.GetNameSuffixes(), o.GetNameSuffixes()) + return utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes()) && + utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes()) } // RemoveBuildAnnotations removes annotations created by the build process. diff --git a/api/resource/resource_test.go b/api/resource/resource_test.go index 05a483aca..ec462e75f 100644 --- a/api/resource/resource_test.go +++ b/api/resource/resource_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/internal/utils" "sigs.k8s.io/kustomize/api/provider" . "sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/types" @@ -1077,7 +1078,7 @@ func TestSameEndingSubarray(t *testing.T) { for n := range testCases { tc := testCases[n] t.Run(n, func(t *testing.T) { - assert.Equal(t, tc.expected, SameEndingSubarray(tc.a, tc.b)) + assert.Equal(t, tc.expected, utils.SameEndingSubSlice(tc.a, tc.b)) }) } }