1
0
mirror of https://github.com/taigrr/yq synced 2025-01-18 04:53:17 -08:00

read command

This commit is contained in:
Mike Farah
2020-10-13 12:51:37 +11:00
parent 6a0a4efa7b
commit d19e9f6917
37 changed files with 2308 additions and 3604 deletions

View File

@@ -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
// }

View File

@@ -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)
// }

View File

@@ -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()

View File

@@ -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())
// }

View File

@@ -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 "))
// }

View File

@@ -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

View File

@@ -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)
// }

View File

@@ -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)
// }

View File

@@ -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)
// }

View File

@@ -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 "))
// }

View File

@@ -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")

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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())
// }

File diff suppressed because it is too large Load Diff