multiply merge anchors

This commit is contained in:
Mike Farah 2020-10-30 12:40:44 +11:00
parent 461c3e719c
commit b63b9644aa
5 changed files with 52 additions and 15 deletions

View File

@ -49,9 +49,9 @@ func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode) {
if n.Node.Style == 0 { if n.Node.Style == 0 {
n.Node.Style = other.Node.Style n.Node.Style = other.Node.Style
} }
n.Node.FootComment = other.Node.FootComment n.Node.FootComment = n.Node.FootComment + other.Node.FootComment
n.Node.HeadComment = other.Node.HeadComment n.Node.HeadComment = n.Node.HeadComment + other.Node.HeadComment
n.Node.LineComment = other.Node.LineComment n.Node.LineComment = n.Node.LineComment + other.Node.LineComment
} }
func (n *CandidateNode) PathStackToString() string { func (n *CandidateNode) PathStackToString() string {

View File

@ -18,6 +18,17 @@ type OperationType struct {
Handler OperatorHandler Handler OperatorHandler
} }
// operators TODO:
// - stripComments (recursive)
// - mergeAppend (merges and appends arrays)
// - mergeIfEmpty (sets only if the document is empty, do I do that now?)
// - updateStyle
// - updateTag
// - explodeAnchors
// - compare ??
// - validate ??
// - exists ??
var Or = &OperationType{Type: "OR", NumArgs: 2, Precedence: 20, Handler: OrOperator} var Or = &OperationType{Type: "OR", NumArgs: 2, Precedence: 20, Handler: OrOperator}
var And = &OperationType{Type: "AND", NumArgs: 2, Precedence: 20, Handler: AndOperator} var And = &OperationType{Type: "AND", NumArgs: 2, Precedence: 20, Handler: AndOperator}

View File

@ -95,6 +95,13 @@ b:
"D0, P[c], (!!map)::{g: thongs, c: frog}\n", "D0, P[c], (!!map)::{g: thongs, c: frog}\n",
}, },
}, },
{
document: mergeDocSample,
expression: `.foobar * .foobarList`,
expected: []string{
"D0, P[foobar], (!!map)::c: foobarList_c\n<<: [*foo, *bar]\nthing: foobar_thing\nb: foobarList_b\n",
},
},
} }
func TestMultiplyOperatorScenarios(t *testing.T) { func TestMultiplyOperatorScenarios(t *testing.T) {

View File

@ -60,6 +60,28 @@ var recursiveDescentOperatorScenarios = []expressionScenario{
"D0, P[b], (alias)::*cat\n", "D0, P[b], (alias)::*cat\n",
}, },
}, },
{
document: mergeDocSample,
expression: `.foobar | ..`,
expected: []string{
"D0, P[foobar], (!!map)::c: foobar_c\n!!merge <<: *foo\nthing: foobar_thing\n",
"D0, P[foobar c], (!!str)::foobar_c\n",
"D0, P[foobar <<], (alias)::*foo\n",
"D0, P[foobar thing], (!!str)::foobar_thing\n",
},
},
{
document: mergeDocSample,
expression: `.foobarList | ..`,
expected: []string{
"D0, P[foobarList], (!!map)::b: foobarList_b\n!!merge <<: [*foo, *bar]\nc: foobarList_c\n",
"D0, P[foobarList b], (!!str)::foobarList_b\n",
"D0, P[foobarList <<], (!!seq)::[*foo, *bar]\n",
"D0, P[foobarList << 0], (alias)::*foo\n",
"D0, P[foobarList << 1], (alias)::*bar\n",
"D0, P[foobarList c], (!!str)::foobarList_c\n",
},
},
} }
func TestRecursiveDescentOperatorScenarios(t *testing.T) { func TestRecursiveDescentOperatorScenarios(t *testing.T) {

View File

@ -44,12 +44,6 @@ func traverse(d *dataTreeNavigator, matchingNode *CandidateNode, operation *Oper
log.Debug("Traversing %v", NodeToString(matchingNode)) log.Debug("Traversing %v", NodeToString(matchingNode))
value := matchingNode.Node value := matchingNode.Node
followAlias := true
// if operation.Preferences != nil {
// followAlias = !operation.Preferences.(*TraversePreferences).DontFollowAlias
// }
if value.Tag == "!!null" && operation.Value != "[]" { if value.Tag == "!!null" && operation.Value != "[]" {
log.Debugf("Guessing kind") log.Debugf("Guessing kind")
// we must ahve added this automatically, lets guess what it should be now // we must ahve added this automatically, lets guess what it should be now
@ -102,11 +96,8 @@ func traverse(d *dataTreeNavigator, matchingNode *CandidateNode, operation *Oper
case yaml.AliasNode: case yaml.AliasNode:
log.Debug("its an alias!") log.Debug("its an alias!")
if followAlias {
matchingNode.Node = matchingNode.Node.Alias matchingNode.Node = matchingNode.Node.Alias
return traverse(d, matchingNode, operation) return traverse(d, matchingNode, operation)
}
return []*CandidateNode{matchingNode}, nil
case yaml.DocumentNode: case yaml.DocumentNode:
log.Debug("digging into doc node") log.Debug("digging into doc node")
return traverse(d, &CandidateNode{ return traverse(d, &CandidateNode{
@ -130,6 +121,12 @@ func traverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode, op
node := candidate.Node node := candidate.Node
followAlias := true
if operation.Preferences != nil {
followAlias = !operation.Preferences.(*TraversePreferences).DontFollowAlias
}
var contents = node.Content var contents = node.Content
for index := 0; index < len(contents); index = index + 2 { for index := 0; index < len(contents); index = index + 2 {
key := contents[index] key := contents[index]
@ -137,7 +134,7 @@ func traverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode, op
log.Debug("checking %v (%v)", key.Value, key.Tag) log.Debug("checking %v (%v)", key.Value, key.Tag)
//skip the 'merge' tag, find a direct match first //skip the 'merge' tag, find a direct match first
if key.Tag == "!!merge" { if key.Tag == "!!merge" && followAlias {
log.Debug("Merge anchor") log.Debug("Merge anchor")
traverseMergeAnchor(newMatches, candidate, value, operation) traverseMergeAnchor(newMatches, candidate, value, operation)
} else if keyMatches(key, operation) { } else if keyMatches(key, operation) {