mirror of
https://github.com/mikefarah/yq.git
synced 2025-02-26 09:42:29 +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)
|
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) {
|
func TestMergeCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := runCmd(cmd, "merge examples/data1.yaml examples/data2.yaml")
|
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,
|
RunE: deleteProperty,
|
||||||
}
|
}
|
||||||
cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
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
|
return cmdDelete
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +269,9 @@ func newYaml(args []string) (interface{}, error) {
|
|||||||
return updateParsedData(parsedData, writeCommands, prependCommand)
|
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 {
|
return func(decoder *yaml.Decoder) error {
|
||||||
var dataBucket interface{}
|
var dataBucket interface{}
|
||||||
var errorReading error
|
var errorReading error
|
||||||
@ -284,17 +287,7 @@ func mapYamlDecoder(writeCommands yaml.MapSlice, encoder *yaml.Encoder) yamlDeco
|
|||||||
} else if errorReading != nil {
|
} else if errorReading != nil {
|
||||||
return fmt.Errorf("Error reading document at index %v, %v", currentIndex, errorReading)
|
return fmt.Errorf("Error reading document at index %v, %v", currentIndex, errorReading)
|
||||||
}
|
}
|
||||||
|
dataBucket = updateData(dataBucket, currentIndex)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorWriting = encoder.Encode(dataBucket)
|
errorWriting = encoder.Encode(dataBucket)
|
||||||
|
|
||||||
@ -311,7 +304,23 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
|||||||
if writeCommandsError != nil {
|
if writeCommandsError != nil {
|
||||||
return writeCommandsError
|
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 destination io.Writer
|
||||||
var destinationName string
|
var destinationName string
|
||||||
if writeInplace {
|
if writeInplace {
|
||||||
@ -326,15 +335,14 @@ func writeProperty(cmd *cobra.Command, args []string) error {
|
|||||||
safelyRenameFile(tempFile.Name(), inputFile)
|
safelyRenameFile(tempFile.Name(), inputFile)
|
||||||
}()
|
}()
|
||||||
} else {
|
} else {
|
||||||
var writer = bufio.NewWriter(cmd.OutOrStdout())
|
var writer = bufio.NewWriter(stdOut)
|
||||||
destination = writer
|
destination = writer
|
||||||
destinationName = "Stdout"
|
destinationName = "Stdout"
|
||||||
defer safelyFlush(writer)
|
defer safelyFlush(writer)
|
||||||
}
|
}
|
||||||
var encoder = yaml.NewEncoder(destination)
|
var encoder = yaml.NewEncoder(destination)
|
||||||
log.Debugf("Writing to %v from %v", destinationName, inputFile)
|
log.Debugf("Writing to %v from %v", destinationName, inputFile)
|
||||||
//need to use a temp file if writeInplace is given
|
return readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||||
return readStream(inputFile, mapYamlDecoder(writeCommands, encoder))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func write(cmd *cobra.Command, filename string, updatedData interface{}) error {
|
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 {
|
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 {
|
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]
|
return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
|
||||||
|
|
||||||
if err := readData(args[0], 0, &parsedData); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
paths := parsePath(deletePath)
|
|
||||||
return deleteChildValue(parsedData, paths), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeProperties(cmd *cobra.Command, args []string) error {
|
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`
|
expectedOutput := `open fake-unknown: no such file or directory`
|
||||||
assertResult(t, expectedOutput, err.Error())
|
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