mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 18:10:59 +00:00
smarter path splitter for replacements
This commit is contained in:
@@ -5,18 +5,50 @@ package utils
|
||||
|
||||
import "strings"
|
||||
|
||||
// PathSplitter splits a slash delimited string, permitting escaped slashes.
|
||||
func PathSplitter(path string) []string {
|
||||
ps := strings.Split(path, "/")
|
||||
// TODO: Move these to kyaml
|
||||
|
||||
// PathSplitter splits a delimited string, permitting escaped delimiters.
|
||||
func PathSplitter(path string, delimiter string) []string {
|
||||
ps := strings.Split(path, delimiter)
|
||||
var res []string
|
||||
res = append(res, ps[0])
|
||||
for i := 1; i < len(ps); i++ {
|
||||
last := len(res) - 1
|
||||
if strings.HasSuffix(res[last], `\`) {
|
||||
res[last] = strings.TrimSuffix(res[last], `\`) + "/" + ps[i]
|
||||
res[last] = strings.TrimSuffix(res[last], `\`) + delimiter + ps[i]
|
||||
} else {
|
||||
res = append(res, ps[i])
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// SmarterPathSplitter splits a path, retaining bracketed list entry identifiers.
|
||||
// E.g. [name=com.foo.someapp] survives as one thing after splitting
|
||||
// "spec.template.spec.containers.[name=com.foo.someapp].image"
|
||||
// See kyaml/yaml/match.go for use of list entry identifiers.
|
||||
// This function uses `PathSplitter`, so it respects list entry identifiers
|
||||
// and escaped delimiters.
|
||||
func SmarterPathSplitter(path string, delimiter string) []string {
|
||||
var result []string
|
||||
split := PathSplitter(path, delimiter)
|
||||
|
||||
for i := 0; i < len(split); i++ {
|
||||
elem := split[i]
|
||||
if strings.HasPrefix(elem, "[") && !strings.HasSuffix(elem, "]") {
|
||||
// continue until we find the matching "]"
|
||||
bracketed := []string{elem}
|
||||
for i < len(split)-1 {
|
||||
i++
|
||||
bracketed = append(bracketed, split[i])
|
||||
if strings.HasSuffix(split[i], "]") {
|
||||
break
|
||||
}
|
||||
}
|
||||
result = append(result, strings.Join(bracketed, delimiter))
|
||||
} else {
|
||||
result = append(result, elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -44,6 +44,47 @@ func TestPathSplitter(t *testing.T) {
|
||||
"nginx.ingress.kubernetes.io/auth-secret"},
|
||||
},
|
||||
} {
|
||||
assert.Equal(t, tc.exp, PathSplitter(tc.path))
|
||||
assert.Equal(t, tc.exp, PathSplitter(tc.path, "/"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmarterPathSplitter(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
input string
|
||||
expected []string
|
||||
}{
|
||||
"simple": {
|
||||
input: "spec.replicas",
|
||||
expected: []string{"spec", "replicas"},
|
||||
},
|
||||
"sequence": {
|
||||
input: "spec.data.[name=first].key",
|
||||
expected: []string{"spec", "data", "[name=first]", "key"},
|
||||
},
|
||||
"key, value with . prefix": {
|
||||
input: "spec.data.[.name=.first].key",
|
||||
expected: []string{"spec", "data", "[.name=.first]", "key"},
|
||||
},
|
||||
"key, value with . suffix": {
|
||||
input: "spec.data.[name.=first.].key",
|
||||
expected: []string{"spec", "data", "[name.=first.]", "key"},
|
||||
},
|
||||
"multiple '.' in value": {
|
||||
input: "spec.data.[name=f.i.r.s.t.].key",
|
||||
expected: []string{"spec", "data", "[name=f.i.r.s.t.]", "key"},
|
||||
},
|
||||
"with escaped delimiter": {
|
||||
input: `spec\.replicas`,
|
||||
expected: []string{`spec.replicas`},
|
||||
},
|
||||
"unmatched bracket": {
|
||||
input: "spec.data.[name=f.i.[r.s.t..key",
|
||||
expected: []string{"spec", "data", "[name=f.i.[r.s.t..key"},
|
||||
},
|
||||
}
|
||||
for tn, tc := range testCases {
|
||||
t.Run(tn, func(t *testing.T) {
|
||||
assert.Equal(t, tc.expected, SmarterPathSplitter(tc.input, "."))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user