mirror of
https://github.com/mikefarah/yq.git
synced 2024-11-12 13:48:06 +00:00
Bugfix: Read yaml array
Parsing an array into MapSlice results in `[{nil, nil}]`. Parse into `[]map[interface{}]interface{}` allows for the processing of top level arrays in the document. Resolves: #23
This commit is contained in:
parent
b9ac6a3d9d
commit
51fa1a87b7
@ -106,6 +106,99 @@ func TestReadCmd(t *testing.T) {
|
||||
assertResult(t, "2\n", result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [0].gather_facts")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
assertResult(t, "false\n", result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_NoPath(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `- become: true
|
||||
gather_facts: false
|
||||
hosts: lalaland
|
||||
name: Apply smth
|
||||
roles:
|
||||
- lala
|
||||
- land
|
||||
serial: 1
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_OneElement(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [0]")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `become: true
|
||||
gather_facts: false
|
||||
hosts: lalaland
|
||||
name: Apply smth
|
||||
roles:
|
||||
- lala
|
||||
- land
|
||||
serial: 1
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_Splat(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [*]")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `- become: true
|
||||
gather_facts: false
|
||||
hosts: lalaland
|
||||
name: Apply smth
|
||||
roles:
|
||||
- lala
|
||||
- land
|
||||
serial: 1
|
||||
`
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_SplatKey(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [*].gather_facts")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := "- false\n"
|
||||
assertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [x].gather_facts")
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to invalid path")
|
||||
}
|
||||
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||
assertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read examples/array.yaml [*].roles[x]")
|
||||
if result.Error == nil {
|
||||
t.Error("Expected command to fail due to invalid path")
|
||||
}
|
||||
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
|
||||
assertResult(t, expectedOutput, result.Error.Error())
|
||||
}
|
||||
|
||||
func TestReadCmd_Error(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := runCmd(cmd, "read")
|
||||
|
9
examples/array.yaml
Normal file
9
examples/array.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
- become: true
|
||||
gather_facts: false
|
||||
hosts: lalaland
|
||||
name: "Apply smth"
|
||||
roles:
|
||||
- lala
|
||||
- land
|
||||
serial: 1
|
43
yaml.go
43
yaml.go
@ -185,6 +185,17 @@ func read(args []string) (interface{}, error) {
|
||||
path = "thing." + path
|
||||
}
|
||||
|
||||
if parsedData != nil && parsedData[0].Key == nil {
|
||||
var interfaceData []map[interface{}]interface{}
|
||||
if err := readData(args[0], &interfaceData); err == nil {
|
||||
var listMap []yaml.MapSlice
|
||||
for _, item := range interfaceData {
|
||||
listMap = append(listMap, mapToMapSlice(item))
|
||||
}
|
||||
return readYamlArray(listMap, path)
|
||||
}
|
||||
}
|
||||
|
||||
if path == "" {
|
||||
return parsedData, nil
|
||||
}
|
||||
@ -194,6 +205,38 @@ func read(args []string) (interface{}, error) {
|
||||
return readMap(parsedData, paths[0], paths[1:])
|
||||
}
|
||||
|
||||
func readYamlArray(listMap []yaml.MapSlice, path string) (interface{}, error) {
|
||||
if path == "" {
|
||||
return listMap, nil
|
||||
}
|
||||
|
||||
var paths = parsePath(path)
|
||||
|
||||
if paths[0] == "*" {
|
||||
if len(paths[1:]) == 0 {
|
||||
return listMap, nil
|
||||
}
|
||||
var results []interface{}
|
||||
for _, m := range listMap {
|
||||
value, err := readMap(m, paths[1], paths[2:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, value)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
index, err := strconv.ParseInt(paths[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error accessing array: %v", err)
|
||||
}
|
||||
if len(paths[1:]) == 0 {
|
||||
return listMap[index], nil
|
||||
}
|
||||
return readMap(listMap[index], paths[1], paths[2:])
|
||||
}
|
||||
|
||||
func newProperty(cmd *cobra.Command, args []string) error {
|
||||
updatedData, err := newYaml(args)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user