mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Merge can allow empty merges!
This commit is contained in:
parent
e3f4eedd51
commit
d8c29b26c1
119
commands_test.go
119
commands_test.go
@ -243,7 +243,7 @@ func TestReadBadDocumentIndexCmd(t *testing.T) {
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to invalid path")
|
||||
}
|
||||
expectedOutput := `asked to process document index 1 but there are only 1 document(s)`
|
||||
expectedOutput := `Could not process document index 1 as there are only 1 document(s)`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
@ -829,18 +829,6 @@ func TestNewCmd_Error(t *testing.T) {
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func TestNewCmd_Verbose(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "-v new b.c 3")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestWriteCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
@ -998,24 +986,6 @@ func TestWriteCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func TestWriteCmd_Verbose(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("-v write %s b.c 7", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 7
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestWriteCmd_Inplace(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
@ -1193,7 +1163,7 @@ b:
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete -v %s b.hi[*].thing", filename))
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.hi[*].thing", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
@ -1224,7 +1194,7 @@ b:
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete -v %s b.there*.c", filename))
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.there*.c", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
@ -1315,7 +1285,7 @@ func TestMergeCmd(t *testing.T) {
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `a: simple
|
||||
expectedOutput := `a: simple # just the best
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
@ -1332,7 +1302,7 @@ func TestMergeNoAutoCreateCmd(t *testing.T) {
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `a: simple
|
||||
expectedOutput := `a: simple # just the best
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
@ -1401,7 +1371,7 @@ c:
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func xTestMergeYamlMultiAllCmd(t *testing.T) {
|
||||
func TestMergeYamlMultiAllCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
apples: green
|
||||
@ -1420,17 +1390,18 @@ something: good`
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `apples: green
|
||||
b:
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
apples: green
|
||||
something: good
|
||||
---
|
||||
something: else
|
||||
apples: red
|
||||
something: else`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func xTestMergeYamlMultiAllOverwriteCmd(t *testing.T) {
|
||||
func TestMergeYamlMultiAllOverwriteCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
apples: green
|
||||
@ -1449,17 +1420,18 @@ something: good`
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `apples: red
|
||||
b:
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
apples: red
|
||||
something: good
|
||||
---
|
||||
something: good
|
||||
apples: red
|
||||
something: good`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func xTestMergeCmd_Error(t *testing.T) {
|
||||
func TestMergeCmd_Error(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "merge examples/data1.yaml")
|
||||
if result.Error == nil {
|
||||
@ -1469,7 +1441,7 @@ func xTestMergeCmd_Error(t *testing.T) {
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func xTestMergeCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
func TestMergeCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "merge examples/data1.yaml fake-unknown")
|
||||
if result.Error == nil {
|
||||
@ -1477,30 +1449,14 @@ func xTestMergeCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
}
|
||||
var expectedOutput string
|
||||
if runtime.GOOS == "windows" {
|
||||
expectedOutput = `Error updating document at index 0: open fake-unknown: The system cannot find the file specified.`
|
||||
expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||
} else {
|
||||
expectedOutput = `Error updating document at index 0: open fake-unknown: no such file or directory`
|
||||
expectedOutput = `open fake-unknown: no such file or directory`
|
||||
}
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func xTestMergeCmd_Verbose(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "-v merge examples/data1.yaml examples/data2.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `a: simple
|
||||
b:
|
||||
- 1
|
||||
- 2
|
||||
c:
|
||||
test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func xTestMergeCmd_Inplace(t *testing.T) {
|
||||
func TestMergeCmd_Inplace(t *testing.T) {
|
||||
filename := test.WriteTempYamlFile(test.ReadTempYamlFile("examples/data1.yaml"))
|
||||
err := os.Chmod(filename, os.FileMode(int(0666)))
|
||||
if err != nil {
|
||||
@ -1515,26 +1471,35 @@ func xTestMergeCmd_Inplace(t *testing.T) {
|
||||
}
|
||||
info, _ := os.Stat(filename)
|
||||
gotOutput := test.ReadTempYamlFile(filename)
|
||||
expectedOutput := `a: simple
|
||||
b:
|
||||
- 1
|
||||
- 2
|
||||
expectedOutput := `a: simple # just the best
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||
test: 1
|
||||
toast: leave
|
||||
tell: 1
|
||||
taco: cool
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, gotOutput)
|
||||
test.AssertResult(t, os.FileMode(int(0666)), info.Mode())
|
||||
}
|
||||
|
||||
func xTestMergeAllowEmptyCmd(t *testing.T) {
|
||||
func TestMergeAllowEmptyCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "merge --allow-empty examples/data1.yaml examples/empty.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `a: simple
|
||||
b:
|
||||
- 1
|
||||
- 2
|
||||
expectedOutput := `a: simple # just the best
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestMergeDontAllowEmptyCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "merge examples/data1.yaml examples/empty.yaml")
|
||||
expectedOutput := `Could not process document index 0 as there are only 0 document(s)`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
52
yq.go
52
yq.go
@ -7,6 +7,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
|
||||
@ -239,7 +240,7 @@ Note that if you set both flags only overwrite will take effect.
|
||||
cmdMerge.PersistentFlags().BoolVarP(&overwriteFlag, "overwrite", "x", false, "update the yaml file by overwriting existing values")
|
||||
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(&allowEmptyFlag, "allow-empty", "e", false, "allow empty yaml files")
|
||||
cmdMerge.PersistentFlags().BoolVarP(&allowEmptyFlag, "allow-empty", "e", false, "allow empty yaml files")
|
||||
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
return cmdMerge
|
||||
}
|
||||
@ -293,7 +294,7 @@ func readYamlFile(filename string, path string, updateAll bool, docIndexInt int)
|
||||
func handleEOF(updateAll bool, docIndexInt int, currentIndex int) error {
|
||||
log.Debugf("done %v / %v", currentIndex, docIndexInt)
|
||||
if !updateAll && currentIndex <= docIndexInt {
|
||||
return fmt.Errorf("asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
|
||||
return fmt.Errorf("Could not process document index %v as there are only %v document(s)", docIndex, currentIndex)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -425,13 +426,16 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return errors.New("Must provide at least 2 yaml files")
|
||||
}
|
||||
// first generate update commands from the file
|
||||
var filesToMerge = args[1:]
|
||||
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 0)
|
||||
|
||||
for _, fileToMerge := range filesToMerge {
|
||||
matchingNodes, errorProcessingFile := readYamlFile(fileToMerge, "**", false, 0)
|
||||
if errorProcessingFile != nil {
|
||||
if errorProcessingFile != nil && (allowEmptyFlag == false || !strings.HasPrefix(errorProcessingFile.Error(), "Could not process document index")) {
|
||||
return errorProcessingFile
|
||||
}
|
||||
for _, matchingNode := range matchingNodes {
|
||||
@ -569,48 +573,6 @@ func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn)
|
||||
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||
}
|
||||
|
||||
// func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
// if len(args) < 2 {
|
||||
// return errors.New("Must provide at least 2 yaml files")
|
||||
// }
|
||||
// var input = args[0]
|
||||
// var filesToMerge = args[1:]
|
||||
// var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
// if errorParsingDocIndex != nil {
|
||||
// return errorParsingDocIndex
|
||||
// }
|
||||
|
||||
// var updateData = func(dataBucket interface{}, currentIndex int) (interface{}, error) {
|
||||
// if updateAll || currentIndex == docIndexInt {
|
||||
// log.Debugf("Merging doc %v", currentIndex)
|
||||
// var mergedData map[interface{}]interface{}
|
||||
// // merge only works for maps, so put everything in a temporary
|
||||
// // map
|
||||
// var mapDataBucket = make(map[interface{}]interface{})
|
||||
// mapDataBucket["root"] = dataBucket
|
||||
// if err := lib.Merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// for _, f := range filesToMerge {
|
||||
// var fileToMerge interface{}
|
||||
// if err := readData(f, 0, &fileToMerge); err != nil {
|
||||
// if allowEmptyFlag && err == io.EOF {
|
||||
// continue
|
||||
// }
|
||||
// return nil, err
|
||||
// }
|
||||
// mapDataBucket["root"] = fileToMerge
|
||||
// if err := lib.Merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
// return mergedData["root"], nil
|
||||
// }
|
||||
// return dataBucket, nil
|
||||
// }
|
||||
// return readAndUpdate(cmd.OutOrStdout(), input, updateData)
|
||||
// }
|
||||
|
||||
type updateCommandParsed struct {
|
||||
Command string
|
||||
Path string
|
||||
|
Loading…
x
Reference in New Issue
Block a user