From 9864afc4e7ca6ae6d40dcbac401e3d167b91b8e5 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Thu, 13 Feb 2020 18:08:13 +1100 Subject: [PATCH] Fixed empty merge problem --- cmd/commands_test.go | 21 ++++++++++++++++++++- pkg/yqlib/data_navigator.go | 4 ++-- pkg/yqlib/lib.go | 27 +++++++++++++++++++++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/cmd/commands_test.go b/cmd/commands_test.go index 4230e6da..d66ef87b 100644 --- a/cmd/commands_test.go +++ b/cmd/commands_test.go @@ -1581,7 +1581,7 @@ func TestWriteCmd_SplatMapEmpty(t *testing.T) { t.Error(result.Error) } expectedOutput := `b: - c: thing + c: {} d: another thing ` test.AssertResult(t, expectedOutput, result.Output) @@ -2009,6 +2009,25 @@ apples: red test.AssertResult(t, expectedOutput, result.Output) } +func TestMergeYamlNullMapCmd(t *testing.T) { + content := `b:` + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) + + mergeContent := `b: + thing: a frog +` + mergeFilename := test.WriteTempYamlFile(mergeContent) + defer test.RemoveTempYamlFile(mergeFilename) + + cmd := getRootCommand() + result := test.RunCmd(cmd, fmt.Sprintf("merge %s %s", filename, mergeFilename)) + if result.Error != nil { + t.Error(result.Error) + } + test.AssertResult(t, mergeContent, result.Output) +} + func TestMergeCmd_Error(t *testing.T) { cmd := getRootCommand() result := test.RunCmd(cmd, "merge") diff --git a/pkg/yqlib/data_navigator.go b/pkg/yqlib/data_navigator.go index a05d10ba..b0e0a28a 100644 --- a/pkg/yqlib/data_navigator.go +++ b/pkg/yqlib/data_navigator.go @@ -60,7 +60,7 @@ func (n *navigator) doTraverse(value *yaml.Node, head interface{}, tail []interf func (n *navigator) getOrReplace(original *yaml.Node, expectedKind yaml.Kind) *yaml.Node { if original.Kind != expectedKind { - log.Debug("wanted %v but it was %v, overriding", expectedKind, original.Kind) + log.Debug("wanted %v but it was %v, overriding", KindString(expectedKind), KindString(original.Kind)) return &yaml.Node{Kind: expectedKind} } return original @@ -113,7 +113,7 @@ func (n *navigator) recurseMap(value *yaml.Node, head string, tail []interface{} if n.navigationStrategy.ShouldTraverse(NewNodeContext(contents[indexInMap+1], head, tail, newPathStack), contents[indexInMap].Value) { log.Debug("recurseMap: Going to traverse") traversedEntry = true - // contents[indexInMap+1] = n.getOrReplace(contents[indexInMap+1], guessKind(head, tail, contents[indexInMap+1].Kind)) + contents[indexInMap+1] = n.getOrReplace(contents[indexInMap+1], guessKind(head, tail, contents[indexInMap+1].Kind)) errorTraversing := n.doTraverse(contents[indexInMap+1], head, tail, newPathStack) log.Debug("recurseMap: Finished traversing") n.navigationStrategy.DebugVisitedNodes() diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go index 667371a6..0cba90df 100644 --- a/pkg/yqlib/lib.go +++ b/pkg/yqlib/lib.go @@ -19,6 +19,23 @@ type UpdateCommand struct { Overwrite bool } +func KindString(kind yaml.Kind) string { + switch kind { + case yaml.ScalarNode: + return "ScalarNode" + case yaml.SequenceNode: + return "SequenceNode" + case yaml.MappingNode: + return "MappingNode" + case yaml.DocumentNode: + return "DocumentNode" + case yaml.AliasNode: + return "AliasNode" + default: + return "unknown!" + } +} + func DebugNode(value *yaml.Node) { if value == nil { log.Debug("-- node is nil --") @@ -30,7 +47,7 @@ func DebugNode(value *yaml.Node) { log.Error("Error debugging node, %v", errorEncoding.Error()) } encoder.Close() - log.Debug("Tag: %v", value.Tag) + log.Debug("Tag: %v, Kind: %v", value.Tag, KindString(value.Kind)) log.Debug("%v", buf.String()) } } @@ -91,12 +108,14 @@ func guessKind(head interface{}, tail []interface{}, guess yaml.Kind) yaml.Kind return yaml.SequenceNode } pathParser := NewPathParser() - if (pathParser.IsPathExpression(nextString) || head == "**") && (guess == yaml.SequenceNode || guess == yaml.MappingNode) { + if pathParser.IsPathExpression(nextString) && (guess == yaml.SequenceNode || guess == yaml.MappingNode) { return guess - } - if guess == yaml.AliasNode { + } else if guess == yaml.AliasNode { log.Debug("guess was an alias, okey doke.") return guess + } else if head == "**" { + log.Debug("deep wildcard, go with the guess") + return guess } log.Debug("forcing a mapping node") log.Debug("yaml.SequenceNode %v", guess == yaml.SequenceNode)