mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-24 14:45:39 +00:00
Fixes delete issue #793
This commit is contained in:
parent
87df9b1ae6
commit
c8630fe4f3
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
type CandidateNode struct {
|
type CandidateNode struct {
|
||||||
Node *yaml.Node // the actual node
|
Node *yaml.Node // the actual node
|
||||||
|
Parent *CandidateNode // parent node
|
||||||
Path []interface{} /// the path we took to get to this node
|
Path []interface{} /// the path we took to get to this node
|
||||||
Document uint // the document index of this node
|
Document uint // the document index of this node
|
||||||
Filename string
|
Filename string
|
||||||
@ -31,6 +32,7 @@ func (n *CandidateNode) CreateChild(path interface{}, node *yaml.Node) *Candidat
|
|||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Node: node,
|
Node: node,
|
||||||
Path: n.createChildPath(path),
|
Path: n.createChildPath(path),
|
||||||
|
Parent: n,
|
||||||
Document: n.Document,
|
Document: n.Document,
|
||||||
Filename: n.Filename,
|
Filename: n.Filename,
|
||||||
FileIndex: n.FileIndex,
|
FileIndex: n.FileIndex,
|
||||||
|
@ -95,7 +95,6 @@ var recursiveDescentOpType = &operationType{Type: "RECURSIVE_DESCENT", NumArgs:
|
|||||||
var selectOpType = &operationType{Type: "SELECT", NumArgs: 1, Precedence: 50, Handler: selectOperator}
|
var selectOpType = &operationType{Type: "SELECT", NumArgs: 1, Precedence: 50, Handler: selectOperator}
|
||||||
var hasOpType = &operationType{Type: "HAS", NumArgs: 1, Precedence: 50, Handler: hasOperator}
|
var hasOpType = &operationType{Type: "HAS", NumArgs: 1, Precedence: 50, Handler: hasOperator}
|
||||||
var deleteChildOpType = &operationType{Type: "DELETE", NumArgs: 1, Precedence: 40, Handler: deleteChildOperator}
|
var deleteChildOpType = &operationType{Type: "DELETE", NumArgs: 1, Precedence: 40, Handler: deleteChildOperator}
|
||||||
var deleteImmediateChildOpType = &operationType{Type: "DELETE_IMMEDIATE_CHILD", NumArgs: 1, Precedence: 40, Handler: deleteImmediateChildOperator}
|
|
||||||
|
|
||||||
type Operation struct {
|
type Operation struct {
|
||||||
OperationType *operationType
|
OperationType *operationType
|
||||||
|
@ -18,48 +18,23 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
|
|||||||
for el := nodesToDelete.MatchingNodes.Back(); el != nil; el = el.Prev() {
|
for el := nodesToDelete.MatchingNodes.Back(); el != nil; el = el.Prev() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
|
|
||||||
if len(candidate.Path) > 0 {
|
//problem: context may already be '.a' and then I pass in '.a.a2'.
|
||||||
deleteImmediateChildOp := &Operation{
|
// should pass in .a2.
|
||||||
OperationType: deleteImmediateChildOpType,
|
if candidate.Parent == nil {
|
||||||
Value: candidate.Path[len(candidate.Path)-1],
|
log.Info("Could not find parent of %v", candidate.GetKey())
|
||||||
}
|
|
||||||
|
|
||||||
deleteImmediateChildOpNode := &ExpressionNode{
|
|
||||||
Operation: deleteImmediateChildOp,
|
|
||||||
Rhs: createTraversalTree(candidate.Path[0:len(candidate.Path)-1], traversePreferences{}, false),
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := d.GetMatchingNodes(contextToUse, deleteImmediateChildOpNode)
|
|
||||||
if err != nil {
|
|
||||||
return Context{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return context, nil
|
return context, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteImmediateChildOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
parentNode := candidate.Parent.Node
|
||||||
parents, err := d.GetMatchingNodes(context, expressionNode.Rhs)
|
childPath := candidate.Path[len(candidate.Path)-1]
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return Context{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
childPath := expressionNode.Operation.Value
|
|
||||||
|
|
||||||
log.Debug("childPath to remove %v", childPath)
|
|
||||||
|
|
||||||
for el := parents.MatchingNodes.Front(); el != nil; el = el.Next() {
|
|
||||||
parent := el.Value.(*CandidateNode)
|
|
||||||
parentNode := unwrapDoc(parent.Node)
|
|
||||||
if parentNode.Kind == yaml.MappingNode {
|
if parentNode.Kind == yaml.MappingNode {
|
||||||
deleteFromMap(parent, childPath)
|
deleteFromMap(candidate.Parent, childPath)
|
||||||
} else if parentNode.Kind == yaml.SequenceNode {
|
} else if parentNode.Kind == yaml.SequenceNode {
|
||||||
deleteFromArray(parent, childPath)
|
deleteFromArray(candidate.Parent, childPath)
|
||||||
} else {
|
} else {
|
||||||
return Context{}, fmt.Errorf("Cannot delete nodes from parent of tag %v", parentNode.Tag)
|
return Context{}, fmt.Errorf("Cannot delete nodes from parent of tag %v", parentNode.Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return context, nil
|
return context, nil
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,70 @@ var deleteOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (doc)::{a: {a2: frood}}\n",
|
"D0, P[], (doc)::{a: {a2: frood}}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{a: {a1: fred, a2: frood}}`,
|
||||||
|
expression: `.a | del(.a1)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!map)::{a2: frood}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `a: [1,2,3]`,
|
||||||
|
expression: `.a | del(.[1])`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!seq)::[1, 3]\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `[0, {a: cat, b: dog}]`,
|
||||||
|
expression: `.[1] | del(.a)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[1], (!!map)::{b: dog}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `[{a: cat, b: dog}]`,
|
||||||
|
expression: `.[0] | del(.a)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[0], (!!map)::{b: dog}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `[{a: {b: thing, c: frog}}]`,
|
||||||
|
expression: `.[0].a | del(.b)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[0 a], (!!map)::{c: frog}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `[{a: {b: thing, c: frog}}]`,
|
||||||
|
expression: `.[0] | del(.a.b)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[0], (!!map)::{a: {c: frog}}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{a: [0, {b: thing, c: frog}]}`,
|
||||||
|
expression: `.a[1] | del(.b)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a 1], (!!map)::{c: frog}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
document: `{a: [0, {b: thing, c: frog}]}`,
|
||||||
|
expression: `.a | del(.[1].b)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[a], (!!seq)::[0, {c: frog}]\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
document: `{a: {a1: fred, a2: frood}}`,
|
document: `{a: {a1: fred, a2: frood}}`,
|
||||||
|
Loading…
Reference in New Issue
Block a user