mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 05:38:04 +00:00
Delete now supports multi docs!
This commit is contained in:
parent
1b22e1d812
commit
1a4064429d
@ -503,6 +503,72 @@ b:
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestDeleteYaml(t *testing.T) {
|
||||
content := `a: 2
|
||||
b:
|
||||
c: things
|
||||
d: something else
|
||||
`
|
||||
filename := writeTempYamlFile(content)
|
||||
defer removeTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
|
||||
expectedOutput := `a: 2
|
||||
b:
|
||||
d: something else
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestDeleteYamlArray(t *testing.T) {
|
||||
content := `- 1
|
||||
- 2
|
||||
- 3
|
||||
`
|
||||
filename := writeTempYamlFile(content)
|
||||
defer removeTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, fmt.Sprintf("delete %s [1]", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
|
||||
expectedOutput := `- 1
|
||||
- 3
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestDeleteYamlMulti(t *testing.T) {
|
||||
content := `apples: great
|
||||
---
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
`
|
||||
filename := writeTempYamlFile(content)
|
||||
defer removeTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
|
||||
expectedOutput := `apples: great
|
||||
---
|
||||
- 1
|
||||
- 3
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestMergeCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "merge examples/data1.yaml examples/data2.yaml")
|
||||
|
71
yq.go
71
yq.go
@ -152,6 +152,7 @@ Outputs to STDOUT unless the inplace flag is used, in which case the file is upd
|
||||
RunE: deleteProperty,
|
||||
}
|
||||
cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
cmdDelete.PersistentFlags().IntVarP(&docIndex, "doc", "d", 0, "process document index number (0 based)")
|
||||
return cmdDelete
|
||||
}
|
||||
|
||||
@ -268,7 +269,9 @@ func newYaml(args []string) (interface{}, error) {
|
||||
return updateParsedData(parsedData, writeCommands, prependCommand)
|
||||
}
|
||||
|
||||
func mapYamlDecoder(writeCommands yaml.MapSlice, encoder *yaml.Encoder) yamlDecoderFn {
|
||||
type updateDataFn func(dataBucket interface{}, currentIndex int) interface{}
|
||||
|
||||
func mapYamlDecoder(updateData updateDataFn, encoder *yaml.Encoder) yamlDecoderFn {
|
||||
return func(decoder *yaml.Decoder) error {
|
||||
var dataBucket interface{}
|
||||
var errorReading error
|
||||
@ -284,17 +287,7 @@ func mapYamlDecoder(writeCommands yaml.MapSlice, encoder *yaml.Encoder) yamlDeco
|
||||
} else if errorReading != nil {
|
||||
return fmt.Errorf("Error reading document at index %v, %v", currentIndex, errorReading)
|
||||
}
|
||||
|
||||
if currentIndex == docIndex {
|
||||
log.Debugf("Updating doc %v", currentIndex)
|
||||
for _, entry := range writeCommands {
|
||||
path := entry.Key.(string)
|
||||
value := entry.Value
|
||||
log.Debugf("setting %v to %v", path, value)
|
||||
var paths = parsePath(path)
|
||||
dataBucket = updatedChildValue(dataBucket, paths, value)
|
||||
}
|
||||
}
|
||||
dataBucket = updateData(dataBucket, currentIndex)
|
||||
|
||||
errorWriting = encoder.Encode(dataBucket)
|
||||
|
||||
@ -311,7 +304,23 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
if writeCommandsError != nil {
|
||||
return writeCommandsError
|
||||
}
|
||||
var inputFile = args[0]
|
||||
var updateData = func(dataBucket interface{}, currentIndex int) interface{} {
|
||||
if currentIndex == docIndex {
|
||||
log.Debugf("Updating doc %v", currentIndex)
|
||||
for _, entry := range writeCommands {
|
||||
path := entry.Key.(string)
|
||||
value := entry.Value
|
||||
log.Debugf("setting %v to %v", path, value)
|
||||
var paths = parsePath(path)
|
||||
dataBucket = updatedChildValue(dataBucket, paths, value)
|
||||
}
|
||||
}
|
||||
return dataBucket
|
||||
}
|
||||
return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
|
||||
}
|
||||
|
||||
func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn) error {
|
||||
var destination io.Writer
|
||||
var destinationName string
|
||||
if writeInplace {
|
||||
@ -326,15 +335,14 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
safelyRenameFile(tempFile.Name(), inputFile)
|
||||
}()
|
||||
} else {
|
||||
var writer = bufio.NewWriter(cmd.OutOrStdout())
|
||||
var writer = bufio.NewWriter(stdOut)
|
||||
destination = writer
|
||||
destinationName = "Stdout"
|
||||
defer safelyFlush(writer)
|
||||
}
|
||||
var encoder = yaml.NewEncoder(destination)
|
||||
log.Debugf("Writing to %v from %v", destinationName, inputFile)
|
||||
//need to use a temp file if writeInplace is given
|
||||
return readStream(inputFile, mapYamlDecoder(writeCommands, encoder))
|
||||
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||
}
|
||||
|
||||
func write(cmd *cobra.Command, filename string, updatedData interface{}) error {
|
||||
@ -354,29 +362,20 @@ func write(cmd *cobra.Command, filename string, updatedData interface{}) error {
|
||||
}
|
||||
|
||||
func deleteProperty(cmd *cobra.Command, args []string) error {
|
||||
updatedData, err := deleteYaml(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return write(cmd, args[0], updatedData)
|
||||
}
|
||||
|
||||
func deleteYaml(args []string) (interface{}, error) {
|
||||
var parsedData interface{}
|
||||
var deletePath string
|
||||
|
||||
if len(args) < 2 {
|
||||
return nil, errors.New("Must provide <filename> <path_to_delete>")
|
||||
return errors.New("Must provide <filename> <path_to_delete>")
|
||||
}
|
||||
var deletePath = args[1]
|
||||
var paths = parsePath(deletePath)
|
||||
var updateData = func(dataBucket interface{}, currentIndex int) interface{} {
|
||||
if currentIndex == docIndex {
|
||||
log.Debugf("Updating doc %v", currentIndex)
|
||||
return deleteChildValue(dataBucket, paths)
|
||||
}
|
||||
return dataBucket
|
||||
}
|
||||
|
||||
deletePath = args[1]
|
||||
|
||||
if err := readData(args[0], 0, &parsedData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paths := parsePath(deletePath)
|
||||
return deleteChildValue(parsedData, paths), nil
|
||||
return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
|
||||
}
|
||||
|
||||
func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
|
16
yq_test.go
16
yq_test.go
@ -98,19 +98,3 @@ func TestNewYaml_WithUnknownScript(t *testing.T) {
|
||||
expectedOutput := `open fake-unknown: no such file or directory`
|
||||
assertResult(t, expectedOutput, err.Error())
|
||||
}
|
||||
|
||||
func TestDeleteYaml(t *testing.T) {
|
||||
result, _ := deleteYaml([]string{"examples/sample.yaml", "b.c"})
|
||||
formattedResult := fmt.Sprintf("%v", result)
|
||||
assertResult(t,
|
||||
"[{a Easy! as one two three} {b [{d [3 4]} {e [[{name fred} {value 3}] [{name sam} {value 4}]]}]}]",
|
||||
formattedResult)
|
||||
}
|
||||
|
||||
func TestDeleteYamlArray(t *testing.T) {
|
||||
result, _ := deleteYaml([]string{"examples/sample_array.yaml", "[1]"})
|
||||
formattedResult := fmt.Sprintf("%v", result)
|
||||
assertResult(t,
|
||||
"[1 3]",
|
||||
formattedResult)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user