mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Can overwrite arrays when merging
This commit is contained in:
parent
ee07edbd88
commit
2fc39b3865
@ -27,6 +27,7 @@ var indent = 2
|
|||||||
var overwriteFlag = false
|
var overwriteFlag = false
|
||||||
var autoCreateFlag = true
|
var autoCreateFlag = true
|
||||||
var appendFlag = false
|
var appendFlag = false
|
||||||
|
var overwriteArrays = false
|
||||||
var verbose = false
|
var verbose = false
|
||||||
var version = false
|
var version = false
|
||||||
var docIndex = "0"
|
var docIndex = "0"
|
||||||
|
@ -34,6 +34,7 @@ If append flag is set then existing arrays will be merged with the arrays from e
|
|||||||
cmdMerge.PersistentFlags().BoolVarP(&autoCreateFlag, "autocreate", "c", true, "automatically create any missing entries")
|
cmdMerge.PersistentFlags().BoolVarP(&autoCreateFlag, "autocreate", "c", true, "automatically create any missing entries")
|
||||||
cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
cmdMerge.PersistentFlags().BoolVarP(&appendFlag, "append", "a", false, "update the yaml file by appending array values")
|
||||||
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
|
cmdMerge.PersistentFlags().BoolVarP(&overwriteArrays, "overwriteArrays", "", false, "overwrite arrays rather than update recursively")
|
||||||
return cmdMerge
|
return cmdMerge
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ If append flag is set then existing arrays will be merged with the arrays from e
|
|||||||
*/
|
*/
|
||||||
func createReadFunctionForMerge() func(*yaml.Node) ([]*yqlib.NodeContext, error) {
|
func createReadFunctionForMerge() func(*yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||||
return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
|
return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||||
return lib.GetForMerge(dataBucket, "**", !appendFlag)
|
return lib.GetForMerge(dataBucket, "**", !appendFlag, overwriteArrays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ func mergeProperties(cmd *cobra.Command, args []string) error {
|
|||||||
Value: matchingNode.Node,
|
Value: matchingNode.Node,
|
||||||
Overwrite: overwriteFlag,
|
Overwrite: overwriteFlag,
|
||||||
// dont update the content for nodes midway, only leaf nodes
|
// dont update the content for nodes midway, only leaf nodes
|
||||||
DontUpdateNodeContent: matchingNode.IsMiddleNode,
|
DontUpdateNodeContent: matchingNode.IsMiddleNode && (!overwriteArrays || matchingNode.Node.Kind != yaml.SequenceNode),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,33 @@ c:
|
|||||||
test.AssertResult(t, expectedOutput, result.Output)
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeOverwriteDeepExampleCmd(t *testing.T) {
|
||||||
|
content := `c:
|
||||||
|
test: 1
|
||||||
|
thing: whatever
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `c:
|
||||||
|
test: 5
|
||||||
|
`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge --autocreate=false --overwrite %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `c:
|
||||||
|
test: 5
|
||||||
|
thing: whatever
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeAppendCmd(t *testing.T) {
|
func TestMergeAppendCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "merge --autocreate=false --append ../examples/data1.yaml ../examples/data2.yaml")
|
result := test.RunCmd(cmd, "merge --autocreate=false --append ../examples/data1.yaml ../examples/data2.yaml")
|
||||||
@ -166,7 +193,35 @@ c:
|
|||||||
test.AssertResult(t, expectedOutput, result.Output)
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeArraysCmd(t *testing.T) {
|
func TestMergeOverwriteArraysTooCmd(t *testing.T) {
|
||||||
|
content := `a: simple # just the best
|
||||||
|
b: [1, 2]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
mergeContent := `a: things
|
||||||
|
b: [6]`
|
||||||
|
mergeFilename := test.WriteTempYamlFile(mergeContent)
|
||||||
|
defer test.RemoveTempYamlFile(mergeFilename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("merge --autocreate=false --overwriteArrays --overwrite %s %s", filename, mergeFilename))
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := `a: things
|
||||||
|
b: [6]
|
||||||
|
c:
|
||||||
|
test: 1
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMergeRootArraysCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "merge --append ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
|
result := test.RunCmd(cmd, "merge --append ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
@ -181,6 +236,18 @@ func TestMergeArraysCmd(t *testing.T) {
|
|||||||
test.AssertResult(t, expectedOutput, result.Output)
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMergeOverwriteArraysCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "merge --overwriteArrays ../examples/sample_array.yaml ../examples/sample_array_2.yaml")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := `- 4
|
||||||
|
- 5
|
||||||
|
`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeCmd_Multi(t *testing.T) {
|
func TestMergeCmd_Multi(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "merge -d1 ../examples/multiple_docs_small.yaml ../examples/data1.yaml")
|
result := test.RunCmd(cmd, "merge -d1 ../examples/multiple_docs_small.yaml ../examples/data1.yaml")
|
||||||
|
@ -136,7 +136,7 @@ func guessKind(head interface{}, tail []interface{}, guess yaml.Kind) yaml.Kind
|
|||||||
|
|
||||||
type YqLib interface {
|
type YqLib interface {
|
||||||
Get(rootNode *yaml.Node, path string) ([]*NodeContext, error)
|
Get(rootNode *yaml.Node, path string) ([]*NodeContext, error)
|
||||||
GetForMerge(rootNode *yaml.Node, path string, deeplyTraverseArrays bool) ([]*NodeContext, error)
|
GetForMerge(rootNode *yaml.Node, path string, deeplyTraverseArrays bool, overwriteArray bool) ([]*NodeContext, error)
|
||||||
Update(rootNode *yaml.Node, updateCommand UpdateCommand, autoCreate bool) error
|
Update(rootNode *yaml.Node, updateCommand UpdateCommand, autoCreate bool) error
|
||||||
New(path string) yaml.Node
|
New(path string) yaml.Node
|
||||||
|
|
||||||
@ -162,9 +162,9 @@ func (l *lib) Get(rootNode *yaml.Node, path string) ([]*NodeContext, error) {
|
|||||||
return navigationStrategy.GetVisitedNodes(), error
|
return navigationStrategy.GetVisitedNodes(), error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *lib) GetForMerge(rootNode *yaml.Node, path string, deeplyTraverseArrays bool) ([]*NodeContext, error) {
|
func (l *lib) GetForMerge(rootNode *yaml.Node, path string, deeplyTraverseArrays bool, overwriteArray bool) ([]*NodeContext, error) {
|
||||||
var paths = l.parser.ParsePath(path)
|
var paths = l.parser.ParsePath(path)
|
||||||
navigationStrategy := ReadForMergeNavigationStrategy(deeplyTraverseArrays)
|
navigationStrategy := ReadForMergeNavigationStrategy(deeplyTraverseArrays, overwriteArray)
|
||||||
navigator := NewDataNavigator(navigationStrategy)
|
navigator := NewDataNavigator(navigationStrategy)
|
||||||
error := navigator.Traverse(rootNode, paths)
|
error := navigator.Traverse(rootNode, paths)
|
||||||
return navigationStrategy.GetVisitedNodes(), error
|
return navigationStrategy.GetVisitedNodes(), error
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
func ReadForMergeNavigationStrategy(deeplyTraverseArrays bool) NavigationStrategy {
|
import "gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
func ReadForMergeNavigationStrategy(deeplyTraverseArrays bool, overwriteArray bool) NavigationStrategy {
|
||||||
return &NavigationStrategyImpl{
|
return &NavigationStrategyImpl{
|
||||||
visitedNodes: []*NodeContext{},
|
visitedNodes: []*NodeContext{},
|
||||||
pathParser: NewPathParser(),
|
pathParser: NewPathParser(),
|
||||||
@ -14,6 +16,11 @@ func ReadForMergeNavigationStrategy(deeplyTraverseArrays bool) NavigationStrateg
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
shouldDeeplyTraverse: func(nodeContext NodeContext) bool {
|
shouldDeeplyTraverse: func(nodeContext NodeContext) bool {
|
||||||
|
if nodeContext.Node.Kind == yaml.SequenceNode && overwriteArray {
|
||||||
|
nodeContext.IsMiddleNode = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var isInArray = false
|
var isInArray = false
|
||||||
if len(nodeContext.PathStack) > 0 {
|
if len(nodeContext.PathStack) > 0 {
|
||||||
var lastElement = nodeContext.PathStack[len(nodeContext.PathStack)-1]
|
var lastElement = nodeContext.PathStack[len(nodeContext.PathStack)-1]
|
||||||
|
Loading…
Reference in New Issue
Block a user