Skip to content

Commit a60515f

Browse files
authored
Revert "fix: Differenciate between new segments and map keys (#3056)" (#3167)
This reverts commit 2b10464.
1 parent 56ef81f commit a60515f

File tree

3 files changed

+50
-155
lines changed

3 files changed

+50
-155
lines changed

pkg/util/patch/patch.go

Lines changed: 31 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
jsonpatch "github.com/evanphx/json-patch/v5"
1010
"github.com/samber/lo"
11-
"k8s.io/klog/v2"
1211
"sigs.k8s.io/controller-runtime/pkg/client"
1312
)
1413

@@ -57,23 +56,20 @@ func (p Patch) Clear() {
5756
}
5857
}
5958

60-
type translateFn func(path string, val interface{}, exists bool) (interface{}, error)
61-
62-
func (p Patch) MustTranslate(path string, translate translateFn) {
59+
func (p Patch) MustTranslate(path string, translate func(path string, val interface{}) (interface{}, error)) {
6360
err := p.Translate(path, translate)
6461
if err != nil {
6562
panic(err)
6663
}
6764
}
6865

69-
// Translate changes values on the given path.
70-
func (p Patch) Translate(path string, translate translateFn) error {
71-
parsedPath, err := parsePathWithIndexing(path, true)
66+
// Translate changes existing (!) values on the given path. If you want to set a value, use the set function instead.
67+
func (p Patch) Translate(path string, translate func(path string, val interface{}) (interface{}, error)) error {
68+
parsedPath, err := parsePath(path)
7269
if err != nil {
7370
panic(err)
74-
}
75-
if len(parsedPath) == 0 {
76-
retVal, err := translate("", map[string]interface{}(p), true)
71+
} else if len(parsedPath) == 0 {
72+
retVal, err := translate("", map[string]interface{}(p))
7773
if err != nil {
7874
return err
7975
}
@@ -88,8 +84,8 @@ func (p Patch) Translate(path string, translate translateFn) error {
8884

8985
// get last map / array
9086
curs, ok := p.getValue(parsedPath, 1)
87+
9188
if !ok {
92-
klog.V(0).ErrorS(fmt.Errorf("could not find path %q in patch", path), "not found", "path", path)
9389
return nil
9490
}
9591

@@ -99,10 +95,9 @@ func (p Patch) Translate(path string, translate translateFn) error {
9995

10096
switch t := cur.Value.(type) {
10197
case []interface{}:
102-
segment = trimBracketsPair(segment)
10398
if segment == "*" {
10499
for k := range t {
105-
t[k], err = translate(addPathElement(cur.Path, strconv.Itoa(k)), t[k], true)
100+
t[k], err = translate(addPathElement(cur.Path, strconv.Itoa(k)), t[k])
106101
if err != nil {
107102
return err
108103
}
@@ -119,44 +114,30 @@ func (p Patch) Translate(path string, translate translateFn) error {
119114
return nil
120115
}
121116

122-
ret, err := translate(addPathElement(cur.Path, segment), t[index], true)
117+
ret, err := translate(addPathElement(cur.Path, segment), t[index])
123118
if err != nil {
124119
return err
125120
}
126121

127122
t[index] = ret
128123

129124
case map[string]interface{}:
130-
switch {
131-
case segment == "[*]":
125+
if segment == "*" {
132126
for k := range t {
133-
t[k], err = translate(addPathElement(cur.Path, k), t[k], true)
127+
t[k], err = translate(addPathElement(cur.Path, k), t[k])
134128
if err != nil {
135129
return err
136130
}
137131
}
138-
case isBracketEnclosed(segment): // a.path.to.some["segment"] case
139-
key := trimBracketsPair(segment)
140-
if key == "" {
141-
return fmt.Errorf("empty key in bracket notation in path %q", segment)
142-
}
143-
v, ok := t[key]
144-
valueFromExpression, err := translate(cur.Path, v, ok)
145-
if err != nil {
146-
return fmt.Errorf("translate value for key %q in path %q: %w", key, cur.Path, err)
147-
}
148-
if valueFromExpression == nil {
149-
p.Delete(JoinPath(cur.Path, key))
150-
continue
151-
}
152-
t[key] = valueFromExpression
153132

154-
default: // a.path.to.some.segment case
155-
if val, ok := t[segment]; ok {
156-
t[segment], err = translate(JoinPath(cur.Path, segment), val, ok)
157-
if err != nil {
158-
return err
159-
}
133+
continue
134+
}
135+
136+
val, ok := t[segment]
137+
if ok {
138+
t[segment], err = translate(JoinPath(cur.Path, segment), val)
139+
if err != nil {
140+
return err
160141
}
161142
}
162143
}
@@ -209,8 +190,7 @@ func (p Patch) Delete(path string) {
209190

210191
// delete last element, we only support maps here for now.
211192
for _, cur := range curs {
212-
segment := parsedPath[len(parsedPath)-1]
213-
if segment == "*" {
193+
if parsedPath[len(parsedPath)-1] == "*" {
214194
if t, ok := cur.Value.(map[string]interface{}); ok {
215195
for k := range t {
216196
delete(t, k)
@@ -220,7 +200,7 @@ func (p Patch) Delete(path string) {
220200
}
221201

222202
if t, ok := cur.Value.(map[string]interface{}); ok {
223-
delete(t, segment)
203+
delete(t, parsedPath[len(parsedPath)-1])
224204
}
225205
}
226206

@@ -389,10 +369,9 @@ func nextValue(parsedPath []string, index int, cur *PathValue, create bool) ([]P
389369
return []PathValue{*cur}, true
390370
}
391371

392-
firstPath := trimBracketsPair(parsedPath[0])
393372
switch val := cur.Value.(type) {
394373
case map[string]interface{}:
395-
if firstPath == "*" {
374+
if parsedPath[0] == "*" {
396375
retVals := make([]PathValue, 0, len(val))
397376
for k := range val {
398377
retVal, ok := nextValue(parsedPath[1:], index, &PathValue{
@@ -412,23 +391,23 @@ func nextValue(parsedPath []string, index int, cur *PathValue, create bool) ([]P
412391
return retVals, true
413392
}
414393

415-
mapValue, ok := val[firstPath]
394+
mapValue, ok := val[parsedPath[0]]
416395
if !ok && !create {
417396
return nil, false
418397
} else if create && (!ok || mapValue == nil) {
419-
val[firstPath] = createValue(parsedPath[1:])
420-
mapValue = val[firstPath]
398+
val[parsedPath[0]] = createValue(parsedPath[1:])
399+
mapValue = val[parsedPath[0]]
421400
}
422401

423402
return nextValue(parsedPath[1:], index, &PathValue{
424403
Parent: cur,
425404
Value: mapValue,
426-
Key: firstPath,
427-
Path: addPathElement(cur.Path, firstPath),
405+
Key: parsedPath[0],
406+
Path: addPathElement(cur.Path, parsedPath[0]),
428407
}, create)
429408
case []interface{}:
430409
// try to match all
431-
if firstPath == "*" {
410+
if parsedPath[0] == "*" {
432411
retVals := make([]PathValue, 0, len(val))
433412
for i := range val {
434413
retVal, ok := nextValue(parsedPath[1:], index, &PathValue{
@@ -449,7 +428,7 @@ func nextValue(parsedPath []string, index int, cur *PathValue, create bool) ([]P
449428
}
450429

451430
// try to get index
452-
indexSegment, err := strconv.Atoi(firstPath)
431+
indexSegment, err := strconv.Atoi(parsedPath[0])
453432
if err != nil {
454433
return nil, false
455434
}
@@ -475,7 +454,7 @@ func nextValue(parsedPath []string, index int, cur *PathValue, create bool) ([]P
475454
Parent: cur,
476455
Value: arrVal,
477456
Index: indexSegment,
478-
Path: addPathElement(cur.Path, firstPath),
457+
Path: addPathElement(cur.Path, parsedPath[0]),
479458
}, create)
480459
}
481460

@@ -487,8 +466,7 @@ func createValue(pathSegment []string) interface{} {
487466
return map[string]interface{}{}
488467
}
489468

490-
segment := trimBracketsPair(pathSegment[0])
491-
intVal, err := strconv.Atoi(segment)
469+
intVal, err := strconv.Atoi(pathSegment[0])
492470
if err == nil {
493471
newVal := make([]interface{}, 0, intVal+1)
494472
for i := 0; i <= intVal; i++ {
@@ -519,17 +497,3 @@ func JoinPath(root, next string) string {
519497
}
520498
return root + "." + next
521499
}
522-
523-
func trimBracketsPair(segment string) string {
524-
if isBracketEnclosed(segment) {
525-
return segment[1 : len(segment)-1]
526-
}
527-
return segment
528-
}
529-
530-
func isBracketEnclosed(segment string) bool {
531-
if len(segment) < 2 {
532-
return false
533-
}
534-
return segment[0] == '[' && segment[len(segment)-1] == ']'
535-
}

0 commit comments

Comments
 (0)