@@ -2,7 +2,6 @@ package patch
22
33import (
44 "fmt"
5-
65 "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
76 yaml "gopkg.in/yaml.v3"
87)
@@ -35,38 +34,63 @@ func (op *Operation) Perform(doc *yaml.Node) error {
3534 return err
3635 }
3736
38- if len (matches ) == 0 {
39- if op .Op == opAdd {
40- matches , err = getParents (doc , op .Path )
41- if err != nil {
42- return fmt .Errorf ("could not add using path: %s" , op .Path )
37+ if len (matches ) == 0 && op .Op != opAdd {
38+ return fmt .Errorf ("%s operation does not apply: doc is missing path: %s" , op .Op , op .Path )
39+ }
40+
41+ // function that will actually perform the patch operation
42+ var opFunc func (parent * yaml.Node , match * yaml.Node )
43+
44+ switch op .Op {
45+ case opAdd :
46+ opFunc = op .add
47+
48+ if len (matches ) > 0 {
49+ if matches [0 ].Kind == yaml .MappingNode || matches [0 ].Kind == yaml .SequenceNode {
50+ break
4351 }
52+ }
53+
54+ originalMatches := matches
4455
45- parentPath := op .Path .getParentPath ()
46- propertName := op .Path .getChildName ()
47- if op .Value != nil {
48- propertyValue := op .Value .Content [0 ]
49- op .Value = createMappingNode (propertName , propertyValue )
56+ matches , err = getParents (doc , op .Path )
57+ if err != nil {
58+ return fmt .Errorf ("could not add using path: %s" , op .Path )
59+ }
60+
61+ if len (matches ) > 0 && len (originalMatches ) > 0 {
62+ if matches [0 ].Kind == yaml .SequenceNode {
63+ matches = originalMatches
64+ break
5065 }
51- op .Path = OpPath (parentPath )
52- } else {
53- return fmt .Errorf ("%s operation does not apply: doc is missing path: %s" , op .Op , op .Path )
66+
67+ // we are trying to overwrite an existing key in a map, don't do that!
68+ return fmt .Errorf (
69+ "attempting add operation for non array/object path '%s' which already exists" ,
70+ op .Path ,
71+ )
5472 }
73+
74+ parentPath := op .Path .getParentPath ()
75+ propertyName := op .Path .getChildName ()
76+ if op .Value != nil {
77+ propertyValue := op .Value .Content [0 ]
78+ op .Value = createMappingNode (propertyName , propertyValue )
79+ }
80+ op .Path = OpPath (parentPath )
81+
82+ case opRemove :
83+ opFunc = op .remove
84+ case opReplace :
85+ opFunc = op .replace
86+ default :
87+ return fmt .Errorf ("unexpected op: %s" , op .Op )
5588 }
5689
5790 for _ , match := range matches {
5891 parent := find (doc , containsChild (match ))
5992
60- switch op .Op {
61- case opAdd :
62- op .add (parent , match )
63- case opRemove :
64- op .remove (parent , match )
65- case opReplace :
66- op .replace (parent , match )
67- default :
68- return fmt .Errorf ("unexpected op: %s" , op .Op )
69- }
93+ opFunc (parent , match )
7094 }
7195
7296 return nil
0 commit comments