mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
read command
This commit is contained in:
148
cmd/compare.go
148
cmd/compare.go
@@ -1,89 +1,89 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
// import (
|
||||
// "bufio"
|
||||
// "bytes"
|
||||
// "os"
|
||||
// "strings"
|
||||
|
||||
"github.com/kylelemons/godebug/diff"
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
errors "github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
// "github.com/kylelemons/godebug/diff"
|
||||
// "github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
// errors "github.com/pkg/errors"
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
// turn off for unit tests :(
|
||||
var forceOsExit = true
|
||||
// // turn off for unit tests :(
|
||||
// var forceOsExit = true
|
||||
|
||||
func createCompareCmd() *cobra.Command {
|
||||
var cmdCompare = &cobra.Command{
|
||||
Use: "compare [yaml_file_a] [yaml_file_b]",
|
||||
Aliases: []string{"x"},
|
||||
Short: "yq x [--prettyPrint/-P] dataA.yaml dataB.yaml 'b.e(name==fr*).value'",
|
||||
Example: `
|
||||
yq x - data2.yml # reads from stdin
|
||||
yq x -pp dataA.yaml dataB.yaml '**' # compare paths
|
||||
yq x -d1 dataA.yaml dataB.yaml 'a.b.c'
|
||||
`,
|
||||
Long: "Deeply compares two yaml files, prints the difference. Use with prettyPrint flag to ignore formatting differences.",
|
||||
RunE: compareDocuments,
|
||||
}
|
||||
cmdCompare.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
cmdCompare.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||
cmdCompare.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||
cmdCompare.PersistentFlags().BoolVarP(&stripComments, "stripComments", "", false, "strip comments out before comparing")
|
||||
cmdCompare.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
||||
return cmdCompare
|
||||
}
|
||||
// func createCompareCmd() *cobra.Command {
|
||||
// var cmdCompare = &cobra.Command{
|
||||
// Use: "compare [yaml_file_a] [yaml_file_b]",
|
||||
// Aliases: []string{"x"},
|
||||
// Short: "yq x [--prettyPrint/-P] dataA.yaml dataB.yaml 'b.e(name==fr*).value'",
|
||||
// Example: `
|
||||
// yq x - data2.yml # reads from stdin
|
||||
// yq x -pp dataA.yaml dataB.yaml '**' # compare paths
|
||||
// yq x -d1 dataA.yaml dataB.yaml 'a.b.c'
|
||||
// `,
|
||||
// Long: "Deeply compares two yaml files, prints the difference. Use with prettyPrint flag to ignore formatting differences.",
|
||||
// RunE: compareDocuments,
|
||||
// }
|
||||
// cmdCompare.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// cmdCompare.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||
// cmdCompare.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||
// cmdCompare.PersistentFlags().BoolVarP(&stripComments, "stripComments", "", false, "strip comments out before comparing")
|
||||
// cmdCompare.PersistentFlags().BoolVarP(&explodeAnchors, "explodeAnchors", "X", false, "explode anchors")
|
||||
// return cmdCompare
|
||||
// }
|
||||
|
||||
func compareDocuments(cmd *cobra.Command, args []string) error {
|
||||
var path = ""
|
||||
// func compareDocuments(cmd *cobra.Command, args []string) error {
|
||||
// var path = ""
|
||||
|
||||
if len(args) < 2 {
|
||||
return errors.New("Must provide at 2 yaml files")
|
||||
} else if len(args) > 2 {
|
||||
path = args[2]
|
||||
}
|
||||
// if len(args) < 2 {
|
||||
// return errors.New("Must provide at 2 yaml files")
|
||||
// } else if len(args) > 2 {
|
||||
// path = args[2]
|
||||
// }
|
||||
|
||||
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
if errorParsingDocIndex != nil {
|
||||
return errorParsingDocIndex
|
||||
}
|
||||
// var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
// if errorParsingDocIndex != nil {
|
||||
// return errorParsingDocIndex
|
||||
// }
|
||||
|
||||
var matchingNodesA []*yqlib.NodeContext
|
||||
var matchingNodesB []*yqlib.NodeContext
|
||||
var errorDoingThings error
|
||||
// var matchingNodesA []*yqlib.NodeContext
|
||||
// var matchingNodesB []*yqlib.NodeContext
|
||||
// var errorDoingThings error
|
||||
|
||||
matchingNodesA, errorDoingThings = readYamlFile(args[0], path, updateAll, docIndexInt)
|
||||
// matchingNodesA, errorDoingThings = readYamlFile(args[0], path, updateAll, docIndexInt)
|
||||
|
||||
if errorDoingThings != nil {
|
||||
return errorDoingThings
|
||||
}
|
||||
// if errorDoingThings != nil {
|
||||
// return errorDoingThings
|
||||
// }
|
||||
|
||||
matchingNodesB, errorDoingThings = readYamlFile(args[1], path, updateAll, docIndexInt)
|
||||
if errorDoingThings != nil {
|
||||
return errorDoingThings
|
||||
}
|
||||
// matchingNodesB, errorDoingThings = readYamlFile(args[1], path, updateAll, docIndexInt)
|
||||
// if errorDoingThings != nil {
|
||||
// return errorDoingThings
|
||||
// }
|
||||
|
||||
var dataBufferA bytes.Buffer
|
||||
var dataBufferB bytes.Buffer
|
||||
errorDoingThings = printResults(matchingNodesA, bufio.NewWriter(&dataBufferA))
|
||||
if errorDoingThings != nil {
|
||||
return errorDoingThings
|
||||
}
|
||||
errorDoingThings = printResults(matchingNodesB, bufio.NewWriter(&dataBufferB))
|
||||
if errorDoingThings != nil {
|
||||
return errorDoingThings
|
||||
}
|
||||
// var dataBufferA bytes.Buffer
|
||||
// var dataBufferB bytes.Buffer
|
||||
// errorDoingThings = printResults(matchingNodesA, bufio.NewWriter(&dataBufferA))
|
||||
// if errorDoingThings != nil {
|
||||
// return errorDoingThings
|
||||
// }
|
||||
// errorDoingThings = printResults(matchingNodesB, bufio.NewWriter(&dataBufferB))
|
||||
// if errorDoingThings != nil {
|
||||
// return errorDoingThings
|
||||
// }
|
||||
|
||||
diffString := diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n"))
|
||||
// diffString := diff.Diff(strings.TrimSuffix(dataBufferA.String(), "\n"), strings.TrimSuffix(dataBufferB.String(), "\n"))
|
||||
|
||||
if len(diffString) > 1 {
|
||||
cmd.Print(diffString)
|
||||
cmd.Print("\n")
|
||||
if forceOsExit {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// if len(diffString) > 1 {
|
||||
// cmd.Print(diffString)
|
||||
// cmd.Print("\n")
|
||||
// if forceOsExit {
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
@@ -1,115 +1,115 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
// import (
|
||||
// "testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
)
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// )
|
||||
|
||||
func TestCompareSameCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := ``
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestCompareSameCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1.yaml")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := ``
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestCompareIgnoreCommentsCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare --stripComments ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := ``
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestCompareIgnoreCommentsCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare --stripComments ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := ``
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestCompareDontIgnoreCommentsCmd(t *testing.T) {
|
||||
forceOsExit = false
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||
// func TestCompareDontIgnoreCommentsCmd(t *testing.T) {
|
||||
// forceOsExit = false
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data1-no-comments.yaml")
|
||||
|
||||
expectedOutput := `-a: simple # just the best
|
||||
+a: simple
|
||||
b: [1, 2]
|
||||
c:
|
||||
test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `-a: simple # just the best
|
||||
// +a: simple
|
||||
// b: [1, 2]
|
||||
// c:
|
||||
// test: 1
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestCompareExplodeAnchorsCommentsCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare --explodeAnchors ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := ``
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestCompareExplodeAnchorsCommentsCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare --explodeAnchors ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := ``
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestCompareDontExplodeAnchorsCmd(t *testing.T) {
|
||||
forceOsExit = false
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||
// func TestCompareDontExplodeAnchorsCmd(t *testing.T) {
|
||||
// forceOsExit = false
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare ../examples/simple-anchor.yaml ../examples/simple-anchor-exploded.yaml")
|
||||
|
||||
expectedOutput := `-foo: &foo
|
||||
+foo:
|
||||
a: 1
|
||||
foobar:
|
||||
- !!merge <<: *foo
|
||||
+ a: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `-foo: &foo
|
||||
// +foo:
|
||||
// a: 1
|
||||
// foobar:
|
||||
// - !!merge <<: *foo
|
||||
// + a: 1
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestCompareDifferentCmd(t *testing.T) {
|
||||
forceOsExit = false
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data3.yaml")
|
||||
// func TestCompareDifferentCmd(t *testing.T) {
|
||||
// forceOsExit = false
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare ../examples/data1.yaml ../examples/data3.yaml")
|
||||
|
||||
expectedOutput := `-a: simple # just the best
|
||||
-b: [1, 2]
|
||||
+a: "simple" # just the best
|
||||
+b: [1, 3]
|
||||
c:
|
||||
test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `-a: simple # just the best
|
||||
// -b: [1, 2]
|
||||
// +a: "simple" # just the best
|
||||
// +b: [1, 3]
|
||||
// c:
|
||||
// test: 1
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestComparePrettyCmd(t *testing.T) {
|
||||
forceOsExit = false
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare -P ../examples/data1.yaml ../examples/data3.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := ` a: simple # just the best
|
||||
b:
|
||||
- 1
|
||||
- - 2
|
||||
+ - 3
|
||||
c:
|
||||
test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestComparePrettyCmd(t *testing.T) {
|
||||
// forceOsExit = false
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare -P ../examples/data1.yaml ../examples/data3.yaml")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := ` a: simple # just the best
|
||||
// b:
|
||||
// - 1
|
||||
// - - 2
|
||||
// + - 3
|
||||
// c:
|
||||
// test: 1
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestComparePathsCmd(t *testing.T) {
|
||||
forceOsExit = false
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "compare -P -ppv ../examples/data1.yaml ../examples/data3.yaml **")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := ` a: simple # just the best
|
||||
b.[0]: 1
|
||||
-b.[1]: 2
|
||||
+b.[1]: 3
|
||||
c.test: 1
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestComparePathsCmd(t *testing.T) {
|
||||
// forceOsExit = false
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "compare -P -ppv ../examples/data1.yaml ../examples/data3.yaml **")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := ` a: simple # just the best
|
||||
// b.[0]: 1
|
||||
// -b.[1]: 2
|
||||
// +b.[1]: 3
|
||||
// c.test: 1
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
@@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib/treeops"
|
||||
logging "gopkg.in/op/go-logging.v1"
|
||||
)
|
||||
|
||||
@@ -32,5 +33,5 @@ var verbose = false
|
||||
var version = false
|
||||
var docIndex = "0"
|
||||
var log = logging.MustGetLogger("yq")
|
||||
var lib = yqlib.NewYqLib()
|
||||
var lib = treeops.NewYqTreeLib()
|
||||
var valueParser = yqlib.NewValueParser()
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
errors "github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
// import (
|
||||
// "github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
// errors "github.com/pkg/errors"
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
func createDeleteCmd() *cobra.Command {
|
||||
var cmdDelete = &cobra.Command{
|
||||
Use: "delete [yaml_file] [path_expression]",
|
||||
Aliases: []string{"d"},
|
||||
Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'",
|
||||
Example: `
|
||||
yq delete things.yaml 'a.b.c'
|
||||
yq delete things.yaml 'a.*.c'
|
||||
yq delete things.yaml 'a.(child.subchild==co*).c'
|
||||
yq delete things.yaml 'a.**'
|
||||
yq delete --inplace things.yaml 'a.b.c'
|
||||
yq delete --inplace -- things.yaml '--key-starting-with-dash' # need to use '--' to stop processing arguments as flags
|
||||
yq d -i things.yaml 'a.b.c'
|
||||
`,
|
||||
Long: `Deletes the nodes matching the given path expression from the YAML file.
|
||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
`,
|
||||
RunE: deleteProperty,
|
||||
}
|
||||
cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
cmdDelete.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
return cmdDelete
|
||||
}
|
||||
// func createDeleteCmd() *cobra.Command {
|
||||
// var cmdDelete = &cobra.Command{
|
||||
// Use: "delete [yaml_file] [path_expression]",
|
||||
// Aliases: []string{"d"},
|
||||
// Short: "yq d [--inplace/-i] [--doc/-d index] sample.yaml 'b.e(name==fred)'",
|
||||
// Example: `
|
||||
// yq delete things.yaml 'a.b.c'
|
||||
// yq delete things.yaml 'a.*.c'
|
||||
// yq delete things.yaml 'a.(child.subchild==co*).c'
|
||||
// yq delete things.yaml 'a.**'
|
||||
// yq delete --inplace things.yaml 'a.b.c'
|
||||
// yq delete --inplace -- things.yaml '--key-starting-with-dash' # need to use '--' to stop processing arguments as flags
|
||||
// yq d -i things.yaml 'a.b.c'
|
||||
// `,
|
||||
// Long: `Deletes the nodes matching the given path expression from the YAML file.
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
// `,
|
||||
// RunE: deleteProperty,
|
||||
// }
|
||||
// cmdDelete.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdDelete.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// return cmdDelete
|
||||
// }
|
||||
|
||||
func deleteProperty(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return errors.New("Must provide <filename> <path_to_delete>")
|
||||
}
|
||||
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 1)
|
||||
updateCommands[0] = yqlib.UpdateCommand{Command: "delete", Path: args[1]}
|
||||
// func deleteProperty(cmd *cobra.Command, args []string) error {
|
||||
// if len(args) < 2 {
|
||||
// return errors.New("Must provide <filename> <path_to_delete>")
|
||||
// }
|
||||
// var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 1)
|
||||
// updateCommands[0] = yqlib.UpdateCommand{Command: "delete", Path: args[1]}
|
||||
|
||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
}
|
||||
// return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
// }
|
||||
|
||||
@@ -1,246 +1,246 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
// import (
|
||||
// "fmt"
|
||||
// "strings"
|
||||
// "testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
)
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// )
|
||||
|
||||
func TestDeleteYamlCmd(t *testing.T) {
|
||||
content := `a: 2
|
||||
b:
|
||||
c: things
|
||||
d: something else
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteYamlCmd(t *testing.T) {
|
||||
// content := `a: 2
|
||||
// b:
|
||||
// c: things
|
||||
// d: something else
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `a: 2
|
||||
b:
|
||||
d: something else
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `a: 2
|
||||
// b:
|
||||
// d: something else
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteDeepDoesNotExistCmd(t *testing.T) {
|
||||
content := `a: 2`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteDeepDoesNotExistCmd(t *testing.T) {
|
||||
// content := `a: 2`
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `a: 2
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `a: 2
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteSplatYaml(t *testing.T) {
|
||||
content := `a: other
|
||||
b: [3, 4]
|
||||
c:
|
||||
toast: leave
|
||||
test: 1
|
||||
tell: 1
|
||||
tasty.taco: cool
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteSplatYaml(t *testing.T) {
|
||||
// content := `a: other
|
||||
// b: [3, 4]
|
||||
// c:
|
||||
// toast: leave
|
||||
// test: 1
|
||||
// tell: 1
|
||||
// tasty.taco: cool
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s c.te*", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s c.te*", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `a: other
|
||||
b: [3, 4]
|
||||
c:
|
||||
toast: leave
|
||||
tasty.taco: cool
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `a: other
|
||||
// b: [3, 4]
|
||||
// c:
|
||||
// toast: leave
|
||||
// tasty.taco: cool
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteSplatArrayYaml(t *testing.T) {
|
||||
content := `a: 2
|
||||
b:
|
||||
hi:
|
||||
- thing: item1
|
||||
name: fred
|
||||
- thing: item2
|
||||
name: sam
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteSplatArrayYaml(t *testing.T) {
|
||||
// content := `a: 2
|
||||
// b:
|
||||
// hi:
|
||||
// - thing: item1
|
||||
// name: fred
|
||||
// - thing: item2
|
||||
// name: sam
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.hi[*].thing", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.hi[*].thing", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `a: 2
|
||||
b:
|
||||
hi:
|
||||
- name: fred
|
||||
- name: sam
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `a: 2
|
||||
// b:
|
||||
// hi:
|
||||
// - name: fred
|
||||
// - name: sam
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteDeepSplatArrayYaml(t *testing.T) {
|
||||
content := `thing: 123
|
||||
b:
|
||||
hi:
|
||||
- thing: item1
|
||||
name: fred
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteDeepSplatArrayYaml(t *testing.T) {
|
||||
// content := `thing: 123
|
||||
// b:
|
||||
// hi:
|
||||
// - thing: item1
|
||||
// name: fred
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s **.thing", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s **.thing", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `b:
|
||||
hi:
|
||||
- name: fred
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `b:
|
||||
// hi:
|
||||
// - name: fred
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteSplatPrefixYaml(t *testing.T) {
|
||||
content := `a: 2
|
||||
b:
|
||||
hi:
|
||||
c: things
|
||||
d: something else
|
||||
there:
|
||||
c: more things
|
||||
d: more something else
|
||||
there2:
|
||||
c: more things also
|
||||
d: more something else also
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteSplatPrefixYaml(t *testing.T) {
|
||||
// content := `a: 2
|
||||
// b:
|
||||
// hi:
|
||||
// c: things
|
||||
// d: something else
|
||||
// there:
|
||||
// c: more things
|
||||
// d: more something else
|
||||
// there2:
|
||||
// c: more things also
|
||||
// d: more something else also
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.there*.c", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.there*.c", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `a: 2
|
||||
b:
|
||||
hi:
|
||||
c: things
|
||||
d: something else
|
||||
there:
|
||||
d: more something else
|
||||
there2:
|
||||
d: more something else also
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `a: 2
|
||||
// b:
|
||||
// hi:
|
||||
// c: things
|
||||
// d: something else
|
||||
// there:
|
||||
// d: more something else
|
||||
// there2:
|
||||
// d: more something else also
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteYamlArrayCmd(t *testing.T) {
|
||||
content := `- 1
|
||||
- 2
|
||||
- 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteYamlArrayCmd(t *testing.T) {
|
||||
// content := `- 1
|
||||
// - 2
|
||||
// - 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s [1]", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s [1]", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `- 1
|
||||
- 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `- 1
|
||||
// - 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteYamlArrayExpressionCmd(t *testing.T) {
|
||||
content := `- name: fred
|
||||
- name: cat
|
||||
- name: thing
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteYamlArrayExpressionCmd(t *testing.T) {
|
||||
// content := `- name: fred
|
||||
// - name: cat
|
||||
// - name: thing
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s (name==cat)", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s (name==cat)", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `- name: fred
|
||||
- name: thing
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `- name: fred
|
||||
// - name: thing
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteYamlMulti(t *testing.T) {
|
||||
content := `apples: great
|
||||
---
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteYamlMulti(t *testing.T) {
|
||||
// content := `apples: great
|
||||
// ---
|
||||
// - 1
|
||||
// - 2
|
||||
// - 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
|
||||
expectedOutput := `apples: great
|
||||
---
|
||||
- 1
|
||||
- 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// expectedOutput := `apples: great
|
||||
// ---
|
||||
// - 1
|
||||
// - 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestDeleteYamlMultiAllCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
apples: great
|
||||
---
|
||||
apples: great
|
||||
something: else
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestDeleteYamlMultiAllCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// apples: great
|
||||
// ---
|
||||
// apples: great
|
||||
// something: else
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("delete %s -d * apples", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
---
|
||||
something: else`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("delete %s -d * apples", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// something: else`
|
||||
// test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
// }
|
||||
|
||||
222
cmd/merge.go
222
cmd/merge.go
@@ -1,124 +1,124 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
errors "github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
// import (
|
||||
// "github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
// errors "github.com/pkg/errors"
|
||||
// "github.com/spf13/cobra"
|
||||
// yaml "gopkg.in/yaml.v3"
|
||||
// )
|
||||
|
||||
func createMergeCmd() *cobra.Command {
|
||||
var cmdMerge = &cobra.Command{
|
||||
Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
||||
Aliases: []string{"m"},
|
||||
Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--arrayMerge/-a strategy] sample.yaml sample2.yaml",
|
||||
Example: `
|
||||
yq merge things.yaml other.yaml
|
||||
yq merge --inplace things.yaml other.yaml
|
||||
yq m -i things.yaml other.yaml
|
||||
yq m --overwrite things.yaml other.yaml
|
||||
yq m -i -x things.yaml other.yaml
|
||||
yq m -i -a=append things.yaml other.yaml
|
||||
yq m -i --autocreate=false things.yaml other.yaml
|
||||
`,
|
||||
Long: `Updates the yaml file by adding/updating the path(s) and value(s) from additional yaml file(s).
|
||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
// func createMergeCmd() *cobra.Command {
|
||||
// var cmdMerge = &cobra.Command{
|
||||
// Use: "merge [initial_yaml_file] [additional_yaml_file]...",
|
||||
// Aliases: []string{"m"},
|
||||
// Short: "yq m [--inplace/-i] [--doc/-d index] [--overwrite/-x] [--arrayMerge/-a strategy] sample.yaml sample2.yaml",
|
||||
// Example: `
|
||||
// yq merge things.yaml other.yaml
|
||||
// yq merge --inplace things.yaml other.yaml
|
||||
// yq m -i things.yaml other.yaml
|
||||
// yq m --overwrite things.yaml other.yaml
|
||||
// yq m -i -x things.yaml other.yaml
|
||||
// yq m -i -a=append things.yaml other.yaml
|
||||
// yq m -i --autocreate=false things.yaml other.yaml
|
||||
// `,
|
||||
// Long: `Updates the yaml file by adding/updating the path(s) and value(s) from additional yaml file(s).
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
|
||||
If overwrite flag is set then existing values will be overwritten using the values from each additional yaml file.
|
||||
If append flag is set then existing arrays will be merged with the arrays from each additional yaml file.
|
||||
`,
|
||||
RunE: mergeProperties,
|
||||
}
|
||||
cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
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().StringVarP(&arrayMergeStrategyFlag, "arrays", "a", "update", `array merge strategy (update/append/overwrite)
|
||||
update: recursively update arrays by their index
|
||||
append: concatenate arrays together
|
||||
overwrite: replace arrays
|
||||
`)
|
||||
cmdMerge.PersistentFlags().StringVarP(&commentsMergeStrategyFlag, "comments", "", "setWhenBlank", `comments merge strategy (setWhenBlank/ignore/append/overwrite)
|
||||
setWhenBlank: set comment if the original document has no comment at that node
|
||||
ignore: leave comments as-is in the original
|
||||
append: append comments together
|
||||
overwrite: overwrite comments completely
|
||||
`)
|
||||
cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
return cmdMerge
|
||||
}
|
||||
// If overwrite flag is set then existing values will be overwritten using the values from each additional yaml file.
|
||||
// If append flag is set then existing arrays will be merged with the arrays from each additional yaml file.
|
||||
// `,
|
||||
// RunE: mergeProperties,
|
||||
// }
|
||||
// cmdMerge.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// 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().StringVarP(&arrayMergeStrategyFlag, "arrays", "a", "update", `array merge strategy (update/append/overwrite)
|
||||
// update: recursively update arrays by their index
|
||||
// append: concatenate arrays together
|
||||
// overwrite: replace arrays
|
||||
// `)
|
||||
// cmdMerge.PersistentFlags().StringVarP(&commentsMergeStrategyFlag, "comments", "", "setWhenBlank", `comments merge strategy (setWhenBlank/ignore/append/overwrite)
|
||||
// setWhenBlank: set comment if the original document has no comment at that node
|
||||
// ignore: leave comments as-is in the original
|
||||
// append: append comments together
|
||||
// overwrite: overwrite comments completely
|
||||
// `)
|
||||
// cmdMerge.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// return cmdMerge
|
||||
// }
|
||||
|
||||
/*
|
||||
* We don't deeply traverse arrays when appending a merge, instead we want to
|
||||
* append the entire array element.
|
||||
*/
|
||||
func createReadFunctionForMerge(arrayMergeStrategy yqlib.ArrayMergeStrategy) func(*yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
return lib.GetForMerge(dataBucket, "**", arrayMergeStrategy)
|
||||
}
|
||||
}
|
||||
// /*
|
||||
// * We don't deeply traverse arrays when appending a merge, instead we want to
|
||||
// * append the entire array element.
|
||||
// */
|
||||
// func createReadFunctionForMerge(arrayMergeStrategy yqlib.ArrayMergeStrategy) func(*yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
// return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
// return lib.GetForMerge(dataBucket, "**", arrayMergeStrategy)
|
||||
// }
|
||||
// }
|
||||
|
||||
func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 0)
|
||||
// func mergeProperties(cmd *cobra.Command, args []string) error {
|
||||
// var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 0)
|
||||
|
||||
if len(args) < 1 {
|
||||
return errors.New("Must provide at least 1 yaml file")
|
||||
}
|
||||
var arrayMergeStrategy yqlib.ArrayMergeStrategy
|
||||
// if len(args) < 1 {
|
||||
// return errors.New("Must provide at least 1 yaml file")
|
||||
// }
|
||||
// var arrayMergeStrategy yqlib.ArrayMergeStrategy
|
||||
|
||||
switch arrayMergeStrategyFlag {
|
||||
case "update":
|
||||
arrayMergeStrategy = yqlib.UpdateArrayMergeStrategy
|
||||
case "append":
|
||||
arrayMergeStrategy = yqlib.AppendArrayMergeStrategy
|
||||
case "overwrite":
|
||||
arrayMergeStrategy = yqlib.OverwriteArrayMergeStrategy
|
||||
default:
|
||||
return errors.New("Array merge strategy must be one of: update/append/overwrite")
|
||||
}
|
||||
// switch arrayMergeStrategyFlag {
|
||||
// case "update":
|
||||
// arrayMergeStrategy = yqlib.UpdateArrayMergeStrategy
|
||||
// case "append":
|
||||
// arrayMergeStrategy = yqlib.AppendArrayMergeStrategy
|
||||
// case "overwrite":
|
||||
// arrayMergeStrategy = yqlib.OverwriteArrayMergeStrategy
|
||||
// default:
|
||||
// return errors.New("Array merge strategy must be one of: update/append/overwrite")
|
||||
// }
|
||||
|
||||
var commentsMergeStrategy yqlib.CommentsMergeStrategy
|
||||
// var commentsMergeStrategy yqlib.CommentsMergeStrategy
|
||||
|
||||
switch commentsMergeStrategyFlag {
|
||||
case "setWhenBlank":
|
||||
commentsMergeStrategy = yqlib.SetWhenBlankCommentsMergeStrategy
|
||||
case "ignore":
|
||||
commentsMergeStrategy = yqlib.IgnoreCommentsMergeStrategy
|
||||
case "append":
|
||||
commentsMergeStrategy = yqlib.AppendCommentsMergeStrategy
|
||||
case "overwrite":
|
||||
commentsMergeStrategy = yqlib.OverwriteCommentsMergeStrategy
|
||||
default:
|
||||
return errors.New("Comments merge strategy must be one of: setWhenBlank/ignore/append/overwrite")
|
||||
}
|
||||
// switch commentsMergeStrategyFlag {
|
||||
// case "setWhenBlank":
|
||||
// commentsMergeStrategy = yqlib.SetWhenBlankCommentsMergeStrategy
|
||||
// case "ignore":
|
||||
// commentsMergeStrategy = yqlib.IgnoreCommentsMergeStrategy
|
||||
// case "append":
|
||||
// commentsMergeStrategy = yqlib.AppendCommentsMergeStrategy
|
||||
// case "overwrite":
|
||||
// commentsMergeStrategy = yqlib.OverwriteCommentsMergeStrategy
|
||||
// default:
|
||||
// return errors.New("Comments merge strategy must be one of: setWhenBlank/ignore/append/overwrite")
|
||||
// }
|
||||
|
||||
if len(args) > 1 {
|
||||
// first generate update commands from the file
|
||||
var filesToMerge = args[1:]
|
||||
// if len(args) > 1 {
|
||||
// // first generate update commands from the file
|
||||
// var filesToMerge = args[1:]
|
||||
|
||||
for _, fileToMerge := range filesToMerge {
|
||||
matchingNodes, errorProcessingFile := doReadYamlFile(fileToMerge, createReadFunctionForMerge(arrayMergeStrategy), false, 0)
|
||||
if errorProcessingFile != nil {
|
||||
return errorProcessingFile
|
||||
}
|
||||
log.Debugf("finished reading for merge!")
|
||||
for _, matchingNode := range matchingNodes {
|
||||
log.Debugf("matched node %v", lib.PathStackToString(matchingNode.PathStack))
|
||||
yqlib.DebugNode(matchingNode.Node)
|
||||
}
|
||||
for _, matchingNode := range matchingNodes {
|
||||
mergePath := lib.MergePathStackToString(matchingNode.PathStack, arrayMergeStrategy)
|
||||
updateCommands = append(updateCommands, yqlib.UpdateCommand{
|
||||
Command: "merge",
|
||||
Path: mergePath,
|
||||
Value: matchingNode.Node,
|
||||
Overwrite: overwriteFlag,
|
||||
CommentsMergeStrategy: commentsMergeStrategy,
|
||||
// dont update the content for nodes midway, only leaf nodes
|
||||
DontUpdateNodeContent: matchingNode.IsMiddleNode && (arrayMergeStrategy != yqlib.OverwriteArrayMergeStrategy || matchingNode.Node.Kind != yaml.SequenceNode),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// for _, fileToMerge := range filesToMerge {
|
||||
// matchingNodes, errorProcessingFile := doReadYamlFile(fileToMerge, createReadFunctionForMerge(arrayMergeStrategy), false, 0)
|
||||
// if errorProcessingFile != nil {
|
||||
// return errorProcessingFile
|
||||
// }
|
||||
// log.Debugf("finished reading for merge!")
|
||||
// for _, matchingNode := range matchingNodes {
|
||||
// log.Debugf("matched node %v", lib.PathStackToString(matchingNode.PathStack))
|
||||
// yqlib.DebugNode(matchingNode.Node)
|
||||
// }
|
||||
// for _, matchingNode := range matchingNodes {
|
||||
// mergePath := lib.MergePathStackToString(matchingNode.PathStack, arrayMergeStrategy)
|
||||
// updateCommands = append(updateCommands, yqlib.UpdateCommand{
|
||||
// Command: "merge",
|
||||
// Path: mergePath,
|
||||
// Value: matchingNode.Node,
|
||||
// Overwrite: overwriteFlag,
|
||||
// CommentsMergeStrategy: commentsMergeStrategy,
|
||||
// // dont update the content for nodes midway, only leaf nodes
|
||||
// DontUpdateNodeContent: matchingNode.IsMiddleNode && (arrayMergeStrategy != yqlib.OverwriteArrayMergeStrategy || matchingNode.Node.Kind != yaml.SequenceNode),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
}
|
||||
// return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
// }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
92
cmd/new.go
92
cmd/new.go
@@ -1,55 +1,55 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
// import (
|
||||
// "github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
func createNewCmd() *cobra.Command {
|
||||
var cmdNew = &cobra.Command{
|
||||
Use: "new [path] [value]",
|
||||
Aliases: []string{"n"},
|
||||
Short: "yq n [--script/-s script_file] a.b.c newValue",
|
||||
Example: `
|
||||
yq new 'a.b.c' cat
|
||||
yq n 'a.b.c' --tag '!!str' true # force 'true' to be interpreted as a string instead of bool
|
||||
yq n 'a.b[+]' cat
|
||||
yq n -- '--key-starting-with-dash' cat # need to use '--' to stop processing arguments as flags
|
||||
yq n --script create_script.yaml
|
||||
`,
|
||||
Long: `Creates a new yaml w.r.t the given path and value.
|
||||
Outputs to STDOUT
|
||||
// func createNewCmd() *cobra.Command {
|
||||
// var cmdNew = &cobra.Command{
|
||||
// Use: "new [path] [value]",
|
||||
// Aliases: []string{"n"},
|
||||
// Short: "yq n [--script/-s script_file] a.b.c newValue",
|
||||
// Example: `
|
||||
// yq new 'a.b.c' cat
|
||||
// yq n 'a.b.c' --tag '!!str' true # force 'true' to be interpreted as a string instead of bool
|
||||
// yq n 'a.b[+]' cat
|
||||
// yq n -- '--key-starting-with-dash' cat # need to use '--' to stop processing arguments as flags
|
||||
// yq n --script create_script.yaml
|
||||
// `,
|
||||
// Long: `Creates a new yaml w.r.t the given path and value.
|
||||
// Outputs to STDOUT
|
||||
|
||||
Create Scripts:
|
||||
Note that you can give a create script to perform more sophisticated yaml. This follows the same format as the update script.
|
||||
`,
|
||||
RunE: newProperty,
|
||||
}
|
||||
cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for creating yaml")
|
||||
cmdNew.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||
cmdNew.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||
cmdNew.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||
cmdNew.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||
return cmdNew
|
||||
}
|
||||
// Create Scripts:
|
||||
// Note that you can give a create script to perform more sophisticated yaml. This follows the same format as the update script.
|
||||
// `,
|
||||
// RunE: newProperty,
|
||||
// }
|
||||
// cmdNew.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for creating yaml")
|
||||
// cmdNew.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||
// cmdNew.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||
// cmdNew.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||
// cmdNew.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||
// return cmdNew
|
||||
// }
|
||||
|
||||
func newProperty(cmd *cobra.Command, args []string) error {
|
||||
var badArgsMessage = "Must provide <path_to_update> <value>"
|
||||
var updateCommands, updateCommandsError = readUpdateCommands(args, 2, badArgsMessage, false)
|
||||
if updateCommandsError != nil {
|
||||
return updateCommandsError
|
||||
}
|
||||
newNode := lib.New(updateCommands[0].Path)
|
||||
// func newProperty(cmd *cobra.Command, args []string) error {
|
||||
// var badArgsMessage = "Must provide <path_to_update> <value>"
|
||||
// var updateCommands, updateCommandsError = readUpdateCommands(args, 2, badArgsMessage, false)
|
||||
// if updateCommandsError != nil {
|
||||
// return updateCommandsError
|
||||
// }
|
||||
// newNode := lib.New(updateCommands[0].Path)
|
||||
|
||||
for _, updateCommand := range updateCommands {
|
||||
// for _, updateCommand := range updateCommands {
|
||||
|
||||
errorUpdating := lib.Update(&newNode, updateCommand, true)
|
||||
// errorUpdating := lib.Update(&newNode, updateCommand, true)
|
||||
|
||||
if errorUpdating != nil {
|
||||
return errorUpdating
|
||||
}
|
||||
}
|
||||
// if errorUpdating != nil {
|
||||
// return errorUpdating
|
||||
// }
|
||||
// }
|
||||
|
||||
var encoder = yqlib.NewYamlEncoder(cmd.OutOrStdout(), indent, colorsEnabled)
|
||||
return encoder.Encode(&newNode)
|
||||
}
|
||||
// var encoder = yqlib.NewYamlEncoder(cmd.OutOrStdout(), indent, colorsEnabled)
|
||||
// return encoder.Encode(&newNode)
|
||||
// }
|
||||
|
||||
214
cmd/new_test.go
214
cmd/new_test.go
@@ -1,120 +1,120 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
// import (
|
||||
// "fmt"
|
||||
// "testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
)
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// )
|
||||
|
||||
func TestNewCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c 3")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c 3")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewCmdScript(t *testing.T) {
|
||||
updateScript := `- command: update
|
||||
path: b.c
|
||||
value: 7`
|
||||
scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||
defer test.RemoveTempYamlFile(scriptFilename)
|
||||
// func TestNewCmdScript(t *testing.T) {
|
||||
// updateScript := `- command: update
|
||||
// path: b.c
|
||||
// value: 7`
|
||||
// scriptFilename := test.WriteTempYamlFile(updateScript)
|
||||
// defer test.RemoveTempYamlFile(scriptFilename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("new --script %s", scriptFilename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 7
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("new --script %s", scriptFilename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 7
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewAnchorCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c 3 --anchorName=fred")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: &fred 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewAnchorCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c 3 --anchorName=fred")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: &fred 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewAliasCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c foo --makeAlias")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: *foo
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewAliasCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c foo --makeAlias")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: *foo
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewArrayCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b[0] 3")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
- 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewArrayCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b[0] 3")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// - 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewCmd_Error(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c")
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to missing arg")
|
||||
}
|
||||
expectedOutput := `Must provide <path_to_update> <value>`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
// func TestNewCmd_Error(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c")
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to missing arg")
|
||||
// }
|
||||
// expectedOutput := `Must provide <path_to_update> <value>`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
func TestNewWithTaggedStyleCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c cat --tag=!!str --style=tagged")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: !!str cat
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewWithTaggedStyleCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c cat --tag=!!str --style=tagged")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: !!str cat
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewWithDoubleQuotedStyleCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c cat --style=double")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: "cat"
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewWithDoubleQuotedStyleCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c cat --style=double")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: "cat"
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestNewWithSingleQuotedStyleCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "new b.c cat --style=single")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 'cat'
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// func TestNewWithSingleQuotedStyleCmd(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "new b.c cat --style=single")
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 'cat'
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
errors "github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
// import (
|
||||
// "github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
// errors "github.com/pkg/errors"
|
||||
// "github.com/spf13/cobra"
|
||||
// yaml "gopkg.in/yaml.v3"
|
||||
// )
|
||||
|
||||
func createPrefixCmd() *cobra.Command {
|
||||
var cmdPrefix = &cobra.Command{
|
||||
Use: "prefix [yaml_file] [path]",
|
||||
Aliases: []string{"p"},
|
||||
Short: "yq p [--inplace/-i] [--doc/-d index] sample.yaml a.b.c",
|
||||
Example: `
|
||||
yq prefix things.yaml 'a.b.c'
|
||||
yq prefix --inplace things.yaml 'a.b.c'
|
||||
yq prefix --inplace -- things.yaml '--key-starting-with-dash' # need to use '--' to stop processing arguments as flags
|
||||
yq p -i things.yaml 'a.b.c'
|
||||
yq p --doc 2 things.yaml 'a.b.d'
|
||||
yq p -d2 things.yaml 'a.b.d'
|
||||
`,
|
||||
Long: `Prefixes w.r.t to the yaml file at the given path.
|
||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
`,
|
||||
RunE: prefixProperty,
|
||||
}
|
||||
cmdPrefix.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
cmdPrefix.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
return cmdPrefix
|
||||
}
|
||||
// func createPrefixCmd() *cobra.Command {
|
||||
// var cmdPrefix = &cobra.Command{
|
||||
// Use: "prefix [yaml_file] [path]",
|
||||
// Aliases: []string{"p"},
|
||||
// Short: "yq p [--inplace/-i] [--doc/-d index] sample.yaml a.b.c",
|
||||
// Example: `
|
||||
// yq prefix things.yaml 'a.b.c'
|
||||
// yq prefix --inplace things.yaml 'a.b.c'
|
||||
// yq prefix --inplace -- things.yaml '--key-starting-with-dash' # need to use '--' to stop processing arguments as flags
|
||||
// yq p -i things.yaml 'a.b.c'
|
||||
// yq p --doc 2 things.yaml 'a.b.d'
|
||||
// yq p -d2 things.yaml 'a.b.d'
|
||||
// `,
|
||||
// Long: `Prefixes w.r.t to the yaml file at the given path.
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
// `,
|
||||
// RunE: prefixProperty,
|
||||
// }
|
||||
// cmdPrefix.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdPrefix.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// return cmdPrefix
|
||||
// }
|
||||
|
||||
func prefixProperty(cmd *cobra.Command, args []string) error {
|
||||
// func prefixProperty(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if len(args) < 2 {
|
||||
return errors.New("Must provide <filename> <prefixed_path>")
|
||||
}
|
||||
updateCommand := yqlib.UpdateCommand{Command: "update", Path: args[1]}
|
||||
log.Debugf("args %v", args)
|
||||
// if len(args) < 2 {
|
||||
// return errors.New("Must provide <filename> <prefixed_path>")
|
||||
// }
|
||||
// updateCommand := yqlib.UpdateCommand{Command: "update", Path: args[1]}
|
||||
// log.Debugf("args %v", args)
|
||||
|
||||
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
if errorParsingDocIndex != nil {
|
||||
return errorParsingDocIndex
|
||||
}
|
||||
// var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
// if errorParsingDocIndex != nil {
|
||||
// return errorParsingDocIndex
|
||||
// }
|
||||
|
||||
var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
||||
return prefixDocument(updateAll, docIndexInt, currentIndex, dataBucket, updateCommand)
|
||||
}
|
||||
return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
|
||||
}
|
||||
// var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
||||
// return prefixDocument(updateAll, docIndexInt, currentIndex, dataBucket, updateCommand)
|
||||
// }
|
||||
// return readAndUpdate(cmd.OutOrStdout(), args[0], updateData)
|
||||
// }
|
||||
|
||||
@@ -1,189 +1,189 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
// import (
|
||||
// "fmt"
|
||||
// "runtime"
|
||||
// "strings"
|
||||
// "testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
)
|
||||
// "github.com/mikefarah/yq/v3/test"
|
||||
// )
|
||||
|
||||
func TestPrefixCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `d:
|
||||
b:
|
||||
c: 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `d:
|
||||
// b:
|
||||
// c: 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestPrefixCmdArray(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixCmdArray(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s [+].d.[+]", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `- d:
|
||||
- b:
|
||||
c: 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s [+].d.[+]", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `- d:
|
||||
// - b:
|
||||
// c: 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestPrefixCmd_MultiLayer(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixCmd_MultiLayer(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d.e.f", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `d:
|
||||
e:
|
||||
f:
|
||||
b:
|
||||
c: 3
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d.e.f", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `d:
|
||||
// e:
|
||||
// f:
|
||||
// b:
|
||||
// c: 3
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
|
||||
func TestPrefixMultiCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
---
|
||||
apples: great
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixMultiCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// apples: great
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b:
|
||||
c: 3
|
||||
---
|
||||
d:
|
||||
apples: great
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
func TestPrefixInvalidDocumentIndexCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// d:
|
||||
// apples: great
|
||||
// `
|
||||
// test.AssertResult(t, expectedOutput, result.Output)
|
||||
// }
|
||||
// func TestPrefixInvalidDocumentIndexCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -df d", filename))
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to invalid path")
|
||||
}
|
||||
expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -df d", filename))
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to invalid path")
|
||||
// }
|
||||
// expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
func TestPrefixBadDocumentIndexCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixBadDocumentIndexCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||
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)`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
func TestPrefixMultiAllCmd(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
---
|
||||
apples: great
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename))
|
||||
// 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)`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
// func TestPrefixMultiAllCmd(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// ---
|
||||
// apples: great
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d * d", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `d:
|
||||
b:
|
||||
c: 3
|
||||
---
|
||||
d:
|
||||
apples: great`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d * d", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// expectedOutput := `d:
|
||||
// b:
|
||||
// c: 3
|
||||
// ---
|
||||
// d:
|
||||
// apples: great`
|
||||
// test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n "))
|
||||
// }
|
||||
|
||||
func TestPrefixCmd_Error(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "prefix")
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to missing arg")
|
||||
}
|
||||
expectedOutput := `Must provide <filename> <prefixed_path>`
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
// func TestPrefixCmd_Error(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "prefix")
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to missing arg")
|
||||
// }
|
||||
// expectedOutput := `Must provide <filename> <prefixed_path>`
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
func TestPrefixCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "prefix fake-unknown a.b")
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to unknown file")
|
||||
}
|
||||
var expectedOutput string
|
||||
if runtime.GOOS == "windows" {
|
||||
expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||
} else {
|
||||
expectedOutput = `open fake-unknown: no such file or directory`
|
||||
}
|
||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
// func TestPrefixCmd_ErrorUnreadableFile(t *testing.T) {
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, "prefix fake-unknown a.b")
|
||||
// if result.Error == nil {
|
||||
// t.Error("Expected command to fail due to unknown file")
|
||||
// }
|
||||
// var expectedOutput string
|
||||
// if runtime.GOOS == "windows" {
|
||||
// expectedOutput = `open fake-unknown: The system cannot find the file specified.`
|
||||
// } else {
|
||||
// expectedOutput = `open fake-unknown: no such file or directory`
|
||||
// }
|
||||
// test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||
// }
|
||||
|
||||
func TestPrefixCmd_Inplace(t *testing.T) {
|
||||
content := `b:
|
||||
c: 3
|
||||
`
|
||||
filename := test.WriteTempYamlFile(content)
|
||||
defer test.RemoveTempYamlFile(filename)
|
||||
// func TestPrefixCmd_Inplace(t *testing.T) {
|
||||
// content := `b:
|
||||
// c: 3
|
||||
// `
|
||||
// filename := test.WriteTempYamlFile(content)
|
||||
// defer test.RemoveTempYamlFile(filename)
|
||||
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, fmt.Sprintf("prefix -i %s d", filename))
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
gotOutput := test.ReadTempYamlFile(filename)
|
||||
expectedOutput := `d:
|
||||
b:
|
||||
c: 3`
|
||||
test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||
}
|
||||
// cmd := getRootCommand()
|
||||
// result := test.RunCmd(cmd, fmt.Sprintf("prefix -i %s d", filename))
|
||||
// if result.Error != nil {
|
||||
// t.Error(result.Error)
|
||||
// }
|
||||
// gotOutput := test.ReadTempYamlFile(filename)
|
||||
// expectedOutput := `d:
|
||||
// b:
|
||||
// c: 3`
|
||||
// test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n "))
|
||||
// }
|
||||
|
||||
@@ -26,7 +26,6 @@ yq r -- things.yaml '--key-starting-with-dashes.blah'
|
||||
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
cmdRead.PersistentFlags().StringVarP(&printMode, "printMode", "p", "v", "print mode (v (values, default), p (paths), pv (path and value pairs)")
|
||||
cmdRead.PersistentFlags().StringVarP(&defaultValue, "defaultValue", "D", "", "default value printed when there are no results")
|
||||
cmdRead.PersistentFlags().BoolVarP(&printLength, "length", "l", false, "print length of results")
|
||||
cmdRead.PersistentFlags().BoolVarP(&collectIntoArray, "collect", "c", false, "collect results into array")
|
||||
cmdRead.PersistentFlags().BoolVarP(&unwrapScalar, "unwrapScalar", "", true, "unwrap scalar, print the value with no quotes, colors or comments")
|
||||
cmdRead.PersistentFlags().BoolVarP(&stripComments, "stripComments", "", false, "print yaml without any comments")
|
||||
|
||||
@@ -127,7 +127,7 @@ func TestReadWithAdvancedFilterCmd(t *testing.T) {
|
||||
|
||||
func TestReadWithAdvancedFilterMapCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "read ../examples/sample.yaml b.e[name`==`fr*]")
|
||||
result := test.RunCmd(cmd, "read ../examples/sample.yaml b.e(name==fr*)")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
|
||||
12
cmd/root.go
12
cmd/root.go
@@ -48,13 +48,13 @@ func New() *cobra.Command {
|
||||
|
||||
rootCmd.AddCommand(
|
||||
createReadCmd(),
|
||||
createCompareCmd(),
|
||||
// createCompareCmd(),
|
||||
createValidateCmd(),
|
||||
createWriteCmd(),
|
||||
createPrefixCmd(),
|
||||
createDeleteCmd(),
|
||||
createNewCmd(),
|
||||
createMergeCmd(),
|
||||
// createWriteCmd(),
|
||||
// createPrefixCmd(),
|
||||
// createDeleteCmd(),
|
||||
// createNewCmd(),
|
||||
// createMergeCmd(),
|
||||
createBashCompletionCmd(rootCmd),
|
||||
)
|
||||
return rootCmd
|
||||
|
||||
296
cmd/utils.go
296
cmd/utils.go
@@ -4,29 +4,29 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib"
|
||||
"github.com/mikefarah/yq/v3/pkg/yqlib/treeops"
|
||||
errors "github.com/pkg/errors"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type readDataFn func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error)
|
||||
type readDataFn func(document int, dataBucket *yaml.Node) ([]*treeops.CandidateNode, error)
|
||||
|
||||
func createReadFunction(path string) func(*yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
return func(dataBucket *yaml.Node) ([]*yqlib.NodeContext, error) {
|
||||
return lib.Get(dataBucket, path)
|
||||
func createReadFunction(path string) func(int, *yaml.Node) ([]*treeops.CandidateNode, error) {
|
||||
return func(document int, dataBucket *yaml.Node) ([]*treeops.CandidateNode, error) {
|
||||
return lib.Get(document, dataBucket, path)
|
||||
}
|
||||
}
|
||||
|
||||
func readYamlFile(filename string, path string, updateAll bool, docIndexInt int) ([]*yqlib.NodeContext, error) {
|
||||
func readYamlFile(filename string, path string, updateAll bool, docIndexInt int) ([]*treeops.CandidateNode, error) {
|
||||
return doReadYamlFile(filename, createReadFunction(path), updateAll, docIndexInt)
|
||||
}
|
||||
|
||||
func doReadYamlFile(filename string, readFn readDataFn, updateAll bool, docIndexInt int) ([]*yqlib.NodeContext, error) {
|
||||
var matchingNodes []*yqlib.NodeContext
|
||||
func doReadYamlFile(filename string, readFn readDataFn, updateAll bool, docIndexInt int) ([]*treeops.CandidateNode, error) {
|
||||
var matchingNodes []*treeops.CandidateNode
|
||||
|
||||
var currentIndex = 0
|
||||
var errorReadingStream = readStream(filename, func(decoder *yaml.Decoder) error {
|
||||
@@ -63,14 +63,14 @@ func handleEOF(updateAll bool, docIndexInt int, currentIndex int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendDocument(originalMatchingNodes []*yqlib.NodeContext, dataBucket yaml.Node, readFn readDataFn, updateAll bool, docIndexInt int, currentIndex int) ([]*yqlib.NodeContext, error) {
|
||||
func appendDocument(originalMatchingNodes []*treeops.CandidateNode, dataBucket yaml.Node, readFn readDataFn, updateAll bool, docIndexInt int, currentIndex int) ([]*treeops.CandidateNode, error) {
|
||||
log.Debugf("processing document %v - requested index %v", currentIndex, docIndexInt)
|
||||
yqlib.DebugNode(&dataBucket)
|
||||
// yqlib.DebugNode(&dataBucket)
|
||||
if !updateAll && currentIndex != docIndexInt {
|
||||
return originalMatchingNodes, nil
|
||||
}
|
||||
log.Debugf("reading in document %v", currentIndex)
|
||||
matchingNodes, errorParsing := readFn(&dataBucket)
|
||||
matchingNodes, errorParsing := readFn(currentIndex, &dataBucket)
|
||||
if errorParsing != nil {
|
||||
return nil, errors.Wrapf(errorParsing, "Error reading path in document index %v", currentIndex)
|
||||
}
|
||||
@@ -114,7 +114,7 @@ func printNode(node *yaml.Node, writer io.Writer) error {
|
||||
return encoder.Encode(node)
|
||||
}
|
||||
|
||||
func removeComments(matchingNodes []*yqlib.NodeContext) {
|
||||
func removeComments(matchingNodes []*treeops.CandidateNode) {
|
||||
for _, nodeContext := range matchingNodes {
|
||||
removeCommentOfNode(nodeContext.Node)
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func removeCommentOfNode(node *yaml.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func setStyle(matchingNodes []*yqlib.NodeContext, style yaml.Style) {
|
||||
func setStyle(matchingNodes []*treeops.CandidateNode, style yaml.Style) {
|
||||
for _, nodeContext := range matchingNodes {
|
||||
updateStyleOfNode(nodeContext.Node, style)
|
||||
}
|
||||
@@ -234,10 +234,10 @@ func explodeNode(node *yaml.Node) error {
|
||||
}
|
||||
}
|
||||
|
||||
func explode(matchingNodes []*yqlib.NodeContext) error {
|
||||
func explode(matchingNodes []*treeops.CandidateNode) error {
|
||||
log.Debug("exploding nodes")
|
||||
for _, nodeContext := range matchingNodes {
|
||||
log.Debugf("exploding %v", nodeContext.Head)
|
||||
log.Debugf("exploding %v", nodeContext.GetKey())
|
||||
errorExplodingNode := explodeNode(nodeContext.Node)
|
||||
if errorExplodingNode != nil {
|
||||
return errorExplodingNode
|
||||
@@ -246,7 +246,7 @@ func explode(matchingNodes []*yqlib.NodeContext) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
||||
func printResults(matchingNodes []*treeops.CandidateNode, writer io.Writer) error {
|
||||
if prettyPrint {
|
||||
setStyle(matchingNodes, 0)
|
||||
}
|
||||
@@ -280,7 +280,7 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
||||
for _, mappedDoc := range matchingNodes {
|
||||
switch printMode {
|
||||
case "p":
|
||||
errorWriting = writeString(bufferedWriter, lib.PathStackToString(mappedDoc.PathStack)+"\n")
|
||||
errorWriting = writeString(bufferedWriter, mappedDoc.PathStackToString()+"\n")
|
||||
if errorWriting != nil {
|
||||
return errorWriting
|
||||
}
|
||||
@@ -288,7 +288,7 @@ func printResults(matchingNodes []*yqlib.NodeContext, writer io.Writer) error {
|
||||
// put it into a node and print that.
|
||||
var parentNode = yaml.Node{Kind: yaml.MappingNode}
|
||||
parentNode.Content = make([]*yaml.Node, 2)
|
||||
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: lib.PathStackToString(mappedDoc.PathStack)}
|
||||
parentNode.Content[0] = &yaml.Node{Kind: yaml.ScalarNode, Value: mappedDoc.PathStackToString()}
|
||||
parentNode.Content[1] = transformNode(mappedDoc.Node)
|
||||
if collectIntoArray {
|
||||
arrayCollection.Content = append(arrayCollection.Content, &parentNode)
|
||||
@@ -383,102 +383,102 @@ func mapYamlDecoder(updateData updateDataFn, encoder yqlib.Encoder) yamlDecoderF
|
||||
}
|
||||
}
|
||||
|
||||
func prefixDocument(updateAll bool, docIndexInt int, currentIndex int, dataBucket *yaml.Node, updateCommand yqlib.UpdateCommand) error {
|
||||
if updateAll || currentIndex == docIndexInt {
|
||||
log.Debugf("Prefixing document %v", currentIndex)
|
||||
yqlib.DebugNode(dataBucket)
|
||||
updateCommand.Value = dataBucket.Content[0]
|
||||
dataBucket.Content = make([]*yaml.Node, 1)
|
||||
// func prefixDocument(updateAll bool, docIndexInt int, currentIndex int, dataBucket *yaml.Node, updateCommand yqlib.UpdateCommand) error {
|
||||
// if updateAll || currentIndex == docIndexInt {
|
||||
// log.Debugf("Prefixing document %v", currentIndex)
|
||||
// // yqlib.DebugNode(dataBucket)
|
||||
// updateCommand.Value = dataBucket.Content[0]
|
||||
// dataBucket.Content = make([]*yaml.Node, 1)
|
||||
|
||||
newNode := lib.New(updateCommand.Path)
|
||||
dataBucket.Content[0] = &newNode
|
||||
// newNode := lib.New(updateCommand.Path)
|
||||
// dataBucket.Content[0] = &newNode
|
||||
|
||||
errorUpdating := lib.Update(dataBucket, updateCommand, true)
|
||||
if errorUpdating != nil {
|
||||
return errorUpdating
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// errorUpdating := lib.Update(dataBucket, updateCommand, true)
|
||||
// if errorUpdating != nil {
|
||||
// return errorUpdating
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func updateDoc(inputFile string, updateCommands []yqlib.UpdateCommand, writer io.Writer) error {
|
||||
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
if errorParsingDocIndex != nil {
|
||||
return errorParsingDocIndex
|
||||
}
|
||||
// func updateDoc(inputFile string, updateCommands []yqlib.UpdateCommand, writer io.Writer) error {
|
||||
// var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||
// if errorParsingDocIndex != nil {
|
||||
// return errorParsingDocIndex
|
||||
// }
|
||||
|
||||
var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
||||
if updateAll || currentIndex == docIndexInt {
|
||||
log.Debugf("Updating doc %v", currentIndex)
|
||||
for _, updateCommand := range updateCommands {
|
||||
log.Debugf("Processing update to Path %v", updateCommand.Path)
|
||||
errorUpdating := lib.Update(dataBucket, updateCommand, autoCreateFlag)
|
||||
if errorUpdating != nil {
|
||||
return errorUpdating
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return readAndUpdate(writer, inputFile, updateData)
|
||||
}
|
||||
// var updateData = func(dataBucket *yaml.Node, currentIndex int) error {
|
||||
// if updateAll || currentIndex == docIndexInt {
|
||||
// log.Debugf("Updating doc %v", currentIndex)
|
||||
// for _, updateCommand := range updateCommands {
|
||||
// log.Debugf("Processing update to Path %v", updateCommand.Path)
|
||||
// errorUpdating := lib.Update(dataBucket, updateCommand, autoCreateFlag)
|
||||
// if errorUpdating != nil {
|
||||
// return errorUpdating
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
// return readAndUpdate(writer, inputFile, updateData)
|
||||
// }
|
||||
|
||||
func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn) error {
|
||||
var destination io.Writer
|
||||
var destinationName string
|
||||
var completedSuccessfully = false
|
||||
if writeInplace {
|
||||
info, err := os.Stat(inputFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// mkdir temp dir as some docker images does not have temp dir
|
||||
_, err = os.Stat(os.TempDir())
|
||||
if os.IsNotExist(err) {
|
||||
err = os.Mkdir(os.TempDir(), 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
tempFile, err := ioutil.TempFile("", "temp")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
destinationName = tempFile.Name()
|
||||
err = os.Chmod(destinationName, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
destination = tempFile
|
||||
defer func() {
|
||||
safelyCloseFile(tempFile)
|
||||
if completedSuccessfully {
|
||||
safelyRenameFile(tempFile.Name(), inputFile)
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
destination = stdOut
|
||||
destinationName = "Stdout"
|
||||
}
|
||||
// func readAndUpdate(stdOut io.Writer, inputFile string, updateData updateDataFn) error {
|
||||
// var destination io.Writer
|
||||
// var destinationName string
|
||||
// var completedSuccessfully = false
|
||||
// if writeInplace {
|
||||
// info, err := os.Stat(inputFile)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // mkdir temp dir as some docker images does not have temp dir
|
||||
// _, err = os.Stat(os.TempDir())
|
||||
// if os.IsNotExist(err) {
|
||||
// err = os.Mkdir(os.TempDir(), 0700)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// } else if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// tempFile, err := ioutil.TempFile("", "temp")
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// destinationName = tempFile.Name()
|
||||
// err = os.Chmod(destinationName, info.Mode())
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// destination = tempFile
|
||||
// defer func() {
|
||||
// safelyCloseFile(tempFile)
|
||||
// if completedSuccessfully {
|
||||
// safelyRenameFile(tempFile.Name(), inputFile)
|
||||
// }
|
||||
// }()
|
||||
// } else {
|
||||
// destination = stdOut
|
||||
// destinationName = "Stdout"
|
||||
// }
|
||||
|
||||
log.Debugf("Writing to %v from %v", destinationName, inputFile)
|
||||
// log.Debugf("Writing to %v from %v", destinationName, inputFile)
|
||||
|
||||
bufferedWriter := bufio.NewWriter(destination)
|
||||
defer safelyFlush(bufferedWriter)
|
||||
// bufferedWriter := bufio.NewWriter(destination)
|
||||
// defer safelyFlush(bufferedWriter)
|
||||
|
||||
var encoder yqlib.Encoder
|
||||
if outputToJSON {
|
||||
encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
||||
} else {
|
||||
encoder = yqlib.NewYamlEncoder(bufferedWriter, indent, colorsEnabled)
|
||||
}
|
||||
// var encoder yqlib.Encoder
|
||||
// if outputToJSON {
|
||||
// encoder = yqlib.NewJsonEncoder(bufferedWriter, prettyPrint, indent)
|
||||
// } else {
|
||||
// encoder = yqlib.NewYamlEncoder(bufferedWriter, indent, colorsEnabled)
|
||||
// }
|
||||
|
||||
var errorProcessing = readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||
completedSuccessfully = errorProcessing == nil
|
||||
return errorProcessing
|
||||
}
|
||||
// var errorProcessing = readStream(inputFile, mapYamlDecoder(updateData, encoder))
|
||||
// completedSuccessfully = errorProcessing == nil
|
||||
// return errorProcessing
|
||||
// }
|
||||
|
||||
type updateCommandParsed struct {
|
||||
Command string
|
||||
@@ -486,53 +486,53 @@ type updateCommandParsed struct {
|
||||
Value yaml.Node
|
||||
}
|
||||
|
||||
func readUpdateCommands(args []string, expectedArgs int, badArgsMessage string, allowNoValue bool) ([]yqlib.UpdateCommand, error) {
|
||||
var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 0)
|
||||
if writeScript != "" {
|
||||
var parsedCommands = make([]updateCommandParsed, 0)
|
||||
// func readUpdateCommands(args []string, expectedArgs int, badArgsMessage string, allowNoValue bool) ([]yqlib.UpdateCommand, error) {
|
||||
// var updateCommands []yqlib.UpdateCommand = make([]yqlib.UpdateCommand, 0)
|
||||
// if writeScript != "" {
|
||||
// var parsedCommands = make([]updateCommandParsed, 0)
|
||||
|
||||
err := readData(writeScript, 0, &parsedCommands)
|
||||
// err := readData(writeScript, 0, &parsedCommands)
|
||||
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
// if err != nil && err != io.EOF {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
log.Debugf("Read write commands file '%v'", parsedCommands)
|
||||
for index := range parsedCommands {
|
||||
parsedCommand := parsedCommands[index]
|
||||
updateCommand := yqlib.UpdateCommand{Command: parsedCommand.Command, Path: parsedCommand.Path, Value: &parsedCommand.Value, Overwrite: true}
|
||||
updateCommands = append(updateCommands, updateCommand)
|
||||
}
|
||||
// log.Debugf("Read write commands file '%v'", parsedCommands)
|
||||
// for index := range parsedCommands {
|
||||
// parsedCommand := parsedCommands[index]
|
||||
// updateCommand := yqlib.UpdateCommand{Command: parsedCommand.Command, Path: parsedCommand.Path, Value: &parsedCommand.Value, Overwrite: true}
|
||||
// updateCommands = append(updateCommands, updateCommand)
|
||||
// }
|
||||
|
||||
log.Debugf("Read write commands file '%v'", updateCommands)
|
||||
} else if sourceYamlFile != "" && len(args) == expectedArgs-1 {
|
||||
log.Debugf("Reading value from %v", sourceYamlFile)
|
||||
var value yaml.Node
|
||||
err := readData(sourceYamlFile, 0, &value)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("args %v", args[expectedArgs-2])
|
||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value.Content[0], Overwrite: true}
|
||||
} else if len(args) == expectedArgs {
|
||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
log.Debug("args %v", args)
|
||||
log.Debug("path %v", args[expectedArgs-2])
|
||||
log.Debug("Value %v", args[expectedArgs-1])
|
||||
value := valueParser.Parse(args[expectedArgs-1], customTag, customStyle, anchorName, makeAlias)
|
||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value, Overwrite: true, CommentsMergeStrategy: yqlib.IgnoreCommentsMergeStrategy}
|
||||
} else if len(args) == expectedArgs-1 && allowNoValue {
|
||||
// don't update the value
|
||||
updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
log.Debug("args %v", args)
|
||||
log.Debug("path %v", args[expectedArgs-2])
|
||||
updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: valueParser.Parse("", customTag, customStyle, anchorName, makeAlias), Overwrite: true, DontUpdateNodeValue: true}
|
||||
} else {
|
||||
return nil, errors.New(badArgsMessage)
|
||||
}
|
||||
return updateCommands, nil
|
||||
}
|
||||
// log.Debugf("Read write commands file '%v'", updateCommands)
|
||||
// } else if sourceYamlFile != "" && len(args) == expectedArgs-1 {
|
||||
// log.Debugf("Reading value from %v", sourceYamlFile)
|
||||
// var value yaml.Node
|
||||
// err := readData(sourceYamlFile, 0, &value)
|
||||
// if err != nil && err != io.EOF {
|
||||
// return nil, err
|
||||
// }
|
||||
// log.Debug("args %v", args[expectedArgs-2])
|
||||
// updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
// updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value.Content[0], Overwrite: true}
|
||||
// } else if len(args) == expectedArgs {
|
||||
// updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
// log.Debug("args %v", args)
|
||||
// log.Debug("path %v", args[expectedArgs-2])
|
||||
// log.Debug("Value %v", args[expectedArgs-1])
|
||||
// value := valueParser.Parse(args[expectedArgs-1], customTag, customStyle, anchorName, makeAlias)
|
||||
// updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: value, Overwrite: true, CommentsMergeStrategy: yqlib.IgnoreCommentsMergeStrategy}
|
||||
// } else if len(args) == expectedArgs-1 && allowNoValue {
|
||||
// // don't update the value
|
||||
// updateCommands = make([]yqlib.UpdateCommand, 1)
|
||||
// log.Debug("args %v", args)
|
||||
// log.Debug("path %v", args[expectedArgs-2])
|
||||
// updateCommands[0] = yqlib.UpdateCommand{Command: "update", Path: args[expectedArgs-2], Value: valueParser.Parse("", customTag, customStyle, anchorName, makeAlias), Overwrite: true, DontUpdateNodeValue: true}
|
||||
// } else {
|
||||
// return nil, errors.New(badArgsMessage)
|
||||
// }
|
||||
// return updateCommands, nil
|
||||
// }
|
||||
|
||||
func safelyRenameFile(from string, to string) {
|
||||
if renameError := os.Rename(from, to); renameError != nil {
|
||||
|
||||
110
cmd/write.go
110
cmd/write.go
@@ -1,61 +1,61 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
// import (
|
||||
// "github.com/spf13/cobra"
|
||||
// )
|
||||
|
||||
func createWriteCmd() *cobra.Command {
|
||||
var cmdWrite = &cobra.Command{
|
||||
Use: "write [yaml_file] [path_expression] [value]",
|
||||
Aliases: []string{"w"},
|
||||
Short: "yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue",
|
||||
Example: `
|
||||
yq write things.yaml 'a.b.c' true
|
||||
yq write things.yaml 'a.*.c' true
|
||||
yq write things.yaml 'a.**' true
|
||||
yq write things.yaml 'a.(child.subchild==co*).c' true
|
||||
yq write things.yaml 'a.b.c' --tag '!!str' true # force 'true' to be interpreted as a string instead of bool
|
||||
yq write things.yaml 'a.b.c' --tag '!!float' 3
|
||||
yq write --inplace -- things.yaml 'a.b.c' '--cat' # need to use '--' to stop processing arguments as flags
|
||||
yq w -i things.yaml 'a.b.c' cat
|
||||
yq w -i -s update_script.yaml things.yaml
|
||||
yq w things.yaml 'a.b.d[+]' foo # appends a new node to the 'd' array
|
||||
yq w --doc 2 things.yaml 'a.b.d[+]' foo # updates the 3rd document of the yaml file
|
||||
`,
|
||||
Long: `Updates the yaml file w.r.t the given path and value.
|
||||
Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
// func createWriteCmd() *cobra.Command {
|
||||
// var cmdWrite = &cobra.Command{
|
||||
// Use: "write [yaml_file] [path_expression] [value]",
|
||||
// Aliases: []string{"w"},
|
||||
// Short: "yq w [--inplace/-i] [--script/-s script_file] [--doc/-d index] sample.yaml 'b.e(name==fr*).value' newValue",
|
||||
// Example: `
|
||||
// yq write things.yaml 'a.b.c' true
|
||||
// yq write things.yaml 'a.*.c' true
|
||||
// yq write things.yaml 'a.**' true
|
||||
// yq write things.yaml 'a.(child.subchild==co*).c' true
|
||||
// yq write things.yaml 'a.b.c' --tag '!!str' true # force 'true' to be interpreted as a string instead of bool
|
||||
// yq write things.yaml 'a.b.c' --tag '!!float' 3
|
||||
// yq write --inplace -- things.yaml 'a.b.c' '--cat' # need to use '--' to stop processing arguments as flags
|
||||
// yq w -i things.yaml 'a.b.c' cat
|
||||
// yq w -i -s update_script.yaml things.yaml
|
||||
// yq w things.yaml 'a.b.d[+]' foo # appends a new node to the 'd' array
|
||||
// yq w --doc 2 things.yaml 'a.b.d[+]' foo # updates the 3rd document of the yaml file
|
||||
// `,
|
||||
// Long: `Updates the yaml file w.r.t the given path and value.
|
||||
// Outputs to STDOUT unless the inplace flag is used, in which case the file is updated instead.
|
||||
|
||||
Append value to array adds the value to the end of array.
|
||||
// Append value to array adds the value to the end of array.
|
||||
|
||||
Update Scripts:
|
||||
Note that you can give an update script to perform more sophisticated update. Update script
|
||||
format is list of update commands (update or delete) like so:
|
||||
---
|
||||
- command: update
|
||||
path: b.c
|
||||
value:
|
||||
#great
|
||||
things: frog # wow!
|
||||
- command: delete
|
||||
path: b.d
|
||||
`,
|
||||
RunE: writeProperty,
|
||||
}
|
||||
cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
||||
cmdWrite.PersistentFlags().StringVarP(&sourceYamlFile, "from", "f", "", "yaml file for updating yaml (as-is)")
|
||||
cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||
cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
cmdWrite.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||
cmdWrite.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||
cmdWrite.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||
return cmdWrite
|
||||
}
|
||||
// Update Scripts:
|
||||
// Note that you can give an update script to perform more sophisticated update. Update script
|
||||
// format is list of update commands (update or delete) like so:
|
||||
// ---
|
||||
// - command: update
|
||||
// path: b.c
|
||||
// value:
|
||||
// #great
|
||||
// things: frog # wow!
|
||||
// - command: delete
|
||||
// path: b.d
|
||||
// `,
|
||||
// RunE: writeProperty,
|
||||
// }
|
||||
// cmdWrite.PersistentFlags().BoolVarP(&writeInplace, "inplace", "i", false, "update the yaml file inplace")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&writeScript, "script", "s", "", "yaml script for updating yaml")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&sourceYamlFile, "from", "f", "", "yaml file for updating yaml (as-is)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&customTag, "tag", "t", "", "set yaml tag (e.g. !!int)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&customStyle, "style", "", "", "formatting style of the value: single, double, folded, flow, literal, tagged")
|
||||
// cmdWrite.PersistentFlags().StringVarP(&anchorName, "anchorName", "", "", "anchor name")
|
||||
// cmdWrite.PersistentFlags().BoolVarP(&makeAlias, "makeAlias", "", false, "create an alias using the value as the anchor name")
|
||||
// return cmdWrite
|
||||
// }
|
||||
|
||||
func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
var updateCommands, updateCommandsError = readUpdateCommands(args, 3, "Must provide <filename> <path_to_update> <value>", true)
|
||||
if updateCommandsError != nil {
|
||||
return updateCommandsError
|
||||
}
|
||||
return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
}
|
||||
// func writeProperty(cmd *cobra.Command, args []string) error {
|
||||
// var updateCommands, updateCommandsError = readUpdateCommands(args, 3, "Must provide <filename> <path_to_update> <value>", true)
|
||||
// if updateCommandsError != nil {
|
||||
// return updateCommandsError
|
||||
// }
|
||||
// return updateDoc(args[0], updateCommands, cmd.OutOrStdout())
|
||||
// }
|
||||
|
||||
1217
cmd/write_test.go
1217
cmd/write_test.go
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user