mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1c1ab0a75 | ||
|
|
6ec8386f9e | ||
|
|
4dbe3636c2 | ||
|
|
4a5bd0ff5b |
@@ -94,6 +94,15 @@ func TestReadCmd(t *testing.T) {
|
|||||||
test.AssertResult(t, "2", result.Output)
|
test.AssertResult(t, "2", result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateCmd(t *testing.T) {
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, "validate ../examples/sample.yaml b.c")
|
||||||
|
if result.Error != nil {
|
||||||
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
test.AssertResult(t, "", result.Output)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadWithAdvancedFilterCmd(t *testing.T) {
|
func TestReadWithAdvancedFilterCmd(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "read -v ../examples/sample.yaml b.e(name==sam).value")
|
result := test.RunCmd(cmd, "read -v ../examples/sample.yaml b.e(name==sam).value")
|
||||||
@@ -438,21 +447,21 @@ true`
|
|||||||
func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) {
|
func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "read ../examples/array.yaml [x].gather_facts")
|
result := test.RunCmd(cmd, "read ../examples/array.yaml [x].gather_facts")
|
||||||
if result.Error == nil {
|
if result.Error != nil {
|
||||||
t.Error("Expected command to fail due to missing arg")
|
t.Error(result.Error)
|
||||||
}
|
}
|
||||||
expectedOutput := `Error reading path in document index 0: Error parsing array index 'x' for '': strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := ``
|
||||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) {
|
func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) {
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, "read ../examples/array.yaml [*].roles[x]")
|
result := test.RunCmd(cmd, "read ../examples/array.yaml [*].roles[x]")
|
||||||
if result.Error == nil {
|
if result.Error != nil {
|
||||||
t.Error("Expected command to fail due to missing arg")
|
t.Error(result.Error)
|
||||||
}
|
}
|
||||||
expectedOutput := `Error reading path in document index 0: Error parsing array index 'x' for '[0].roles': strconv.ParseInt: parsing "x": invalid syntax`
|
expectedOutput := ``
|
||||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadCmd_Error(t *testing.T) {
|
func TestReadCmd_Error(t *testing.T) {
|
||||||
@@ -505,8 +514,11 @@ func TestReadCmd_ErrorBadPath(t *testing.T) {
|
|||||||
|
|
||||||
cmd := getRootCommand()
|
cmd := getRootCommand()
|
||||||
result := test.RunCmd(cmd, fmt.Sprintf("read %s b.d.*.[x]", filename))
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s b.d.*.[x]", filename))
|
||||||
expectedOutput := `Error reading path in document index 0: Error parsing array index 'x' for 'b.d.e': strconv.ParseInt: parsing "x": invalid syntax`
|
if result.Error != nil {
|
||||||
test.AssertResult(t, expectedOutput, result.Error.Error())
|
t.Error(result.Error)
|
||||||
|
}
|
||||||
|
expectedOutput := ``
|
||||||
|
test.AssertResult(t, expectedOutput, result.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadCmd_Verbose(t *testing.T) {
|
func TestReadCmd_Verbose(t *testing.T) {
|
||||||
@@ -536,6 +548,34 @@ func TestReadCmd_Verbose(t *testing.T) {
|
|||||||
// test.AssertResult(t, "2\n", result.Output)
|
// test.AssertResult(t, "2\n", result.Output)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func TestReadBadDataCmd(t *testing.T) {
|
||||||
|
content := `[!Whatever]`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("read %s", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail")
|
||||||
|
}
|
||||||
|
expectedOutput := `yaml: line 1: did not find expected ',' or ']'`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateBadDataCmd(t *testing.T) {
|
||||||
|
content := `[!Whatever]`
|
||||||
|
filename := test.WriteTempYamlFile(content)
|
||||||
|
defer test.RemoveTempYamlFile(filename)
|
||||||
|
|
||||||
|
cmd := getRootCommand()
|
||||||
|
result := test.RunCmd(cmd, fmt.Sprintf("validate %s", filename))
|
||||||
|
if result.Error == nil {
|
||||||
|
t.Error("Expected command to fail")
|
||||||
|
}
|
||||||
|
expectedOutput := `yaml: line 1: did not find expected ',' or ']'`
|
||||||
|
test.AssertResult(t, expectedOutput, result.Error.Error())
|
||||||
|
}
|
||||||
|
|
||||||
func TestReadSplatPrefixCmd(t *testing.T) {
|
func TestReadSplatPrefixCmd(t *testing.T) {
|
||||||
content := `a: 2
|
content := `a: 2
|
||||||
b:
|
b:
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ func New() *cobra.Command {
|
|||||||
|
|
||||||
rootCmd.AddCommand(
|
rootCmd.AddCommand(
|
||||||
createReadCmd(),
|
createReadCmd(),
|
||||||
|
createValidateCmd(),
|
||||||
createWriteCmd(),
|
createWriteCmd(),
|
||||||
createPrefixCmd(),
|
createPrefixCmd(),
|
||||||
createDeleteCmd(),
|
createDeleteCmd(),
|
||||||
|
|||||||
@@ -25,12 +25,19 @@ func readYamlFile(filename string, path string, updateAll bool, docIndexInt int)
|
|||||||
|
|
||||||
if errorReading == io.EOF {
|
if errorReading == io.EOF {
|
||||||
return handleEOF(updateAll, docIndexInt, currentIndex)
|
return handleEOF(updateAll, docIndexInt, currentIndex)
|
||||||
|
} else if errorReading != nil {
|
||||||
|
return errorReading
|
||||||
}
|
}
|
||||||
|
|
||||||
var errorParsing error
|
var errorParsing error
|
||||||
matchingNodes, errorParsing = appendDocument(matchingNodes, dataBucket, path, updateAll, docIndexInt, currentIndex)
|
matchingNodes, errorParsing = appendDocument(matchingNodes, dataBucket, path, updateAll, docIndexInt, currentIndex)
|
||||||
if errorParsing != nil {
|
if errorParsing != nil {
|
||||||
return errorParsing
|
return errorParsing
|
||||||
}
|
}
|
||||||
|
if !updateAll && currentIndex == docIndexInt {
|
||||||
|
log.Debug("all done")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
currentIndex = currentIndex + 1
|
currentIndex = currentIndex + 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
37
cmd/validate.go
Normal file
37
cmd/validate.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
errors "github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createValidateCmd() *cobra.Command {
|
||||||
|
var cmdRead = &cobra.Command{
|
||||||
|
Use: "validate [yaml_file]",
|
||||||
|
Aliases: []string{"v"},
|
||||||
|
Short: "yq v sample.yaml",
|
||||||
|
Example: `
|
||||||
|
yq v - # reads from stdin
|
||||||
|
`,
|
||||||
|
RunE: validateProperty,
|
||||||
|
SilenceUsage: true,
|
||||||
|
SilenceErrors: true,
|
||||||
|
}
|
||||||
|
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
|
||||||
|
return cmdRead
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateProperty(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return errors.New("Must provide filename")
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
|
||||||
|
if errorParsingDocIndex != nil {
|
||||||
|
return errorParsingDocIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
_, errorReadingStream := readYamlFile(args[0], "", updateAll, docIndexInt)
|
||||||
|
|
||||||
|
return errorReadingStream
|
||||||
|
}
|
||||||
8
examples/bad.yaml
Normal file
8
examples/bad.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
b:
|
||||||
|
d: be gone
|
||||||
|
c: 2
|
||||||
|
e:
|
||||||
|
- name: Billy Bob # comment over here
|
||||||
|
|
||||||
|
---
|
||||||
|
[123123
|
||||||
@@ -3,7 +3,6 @@ package yqlib
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
errors "github.com/pkg/errors"
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,12 +68,15 @@ func (n *navigator) recurse(value *yaml.Node, head string, tail []string, pathSt
|
|||||||
return n.recurseMap(value, head, tail, pathStack)
|
return n.recurseMap(value, head, tail, pathStack)
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
log.Debug("its a sequence of %v things!", len(value.Content))
|
log.Debug("its a sequence of %v things!", len(value.Content))
|
||||||
if n.navigationStrategy.GetPathParser().IsPathExpression(head) {
|
|
||||||
return n.splatArray(value, head, tail, pathStack)
|
var index, errorParsingIndex = strconv.ParseInt(head, 10, 64) // nolint
|
||||||
|
if errorParsingIndex == nil {
|
||||||
|
return n.recurseArray(value, index, head, tail, pathStack)
|
||||||
} else if head == "+" {
|
} else if head == "+" {
|
||||||
return n.appendArray(value, head, tail, pathStack)
|
return n.appendArray(value, head, tail, pathStack)
|
||||||
}
|
}
|
||||||
return n.recurseArray(value, head, tail, pathStack)
|
return n.splatArray(value, head, tail, pathStack)
|
||||||
|
|
||||||
case yaml.AliasNode:
|
case yaml.AliasNode:
|
||||||
log.Debug("its an alias!")
|
log.Debug("its an alias!")
|
||||||
DebugNode(value.Alias)
|
DebugNode(value.Alias)
|
||||||
@@ -233,12 +235,7 @@ func (n *navigator) appendArray(value *yaml.Node, head string, tail []string, pa
|
|||||||
return n.doTraverse(&newNode, head, tail, append(pathStack, len(value.Content)-1))
|
return n.doTraverse(&newNode, head, tail, append(pathStack, len(value.Content)-1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *navigator) recurseArray(value *yaml.Node, head string, tail []string, pathStack []interface{}) error {
|
func (n *navigator) recurseArray(value *yaml.Node, index int64, head string, tail []string, pathStack []interface{}) error {
|
||||||
var index, err = strconv.ParseInt(head, 10, 64) // nolint
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "Error parsing array index '%v' for '%v'", head, pathStackToString(pathStack))
|
|
||||||
}
|
|
||||||
|
|
||||||
for int64(len(value.Content)) <= index {
|
for int64(len(value.Content)) <= index {
|
||||||
value.Content = append(value.Content, &yaml.Node{Kind: guessKind(head, tail, 0)})
|
value.Content = append(value.Content, &yaml.Node{Kind: guessKind(head, tail, 0)})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey str
|
|||||||
navigator := NewDataNavigator(navigationStrategy)
|
navigator := NewDataNavigator(navigationStrategy)
|
||||||
err := navigator.Traverse(nodeContext.Node, p.ParsePath(path))
|
err := navigator.Traverse(nodeContext.Node, p.ParsePath(path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error("Error deep recursing - ignoring")
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
}
|
}
|
||||||
//crap handle error
|
|
||||||
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
log.Debug("done deep recursing, found %v matches", len(navigationStrategy.GetVisitedNodes()))
|
||||||
return len(navigationStrategy.GetVisitedNodes()) > 0
|
return len(navigationStrategy.GetVisitedNodes()) > 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user