diff --git a/commands_test.go b/commands_test.go index 6f0e1fc2..420064b6 100644 --- a/commands_test.go +++ b/commands_test.go @@ -128,6 +128,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") diff --git a/examples/array.yaml b/examples/array.yaml new file mode 100644 index 00000000..67c34c04 --- /dev/null +++ b/examples/array.yaml @@ -0,0 +1,9 @@ +--- +- become: true + gather_facts: false + hosts: lalaland + name: "Apply smth" + roles: + - lala + - land + serial: 1 diff --git a/yaml.go b/yaml.go index a5804dda..bff7eeee 100644 --- a/yaml.go +++ b/yaml.go @@ -196,6 +196,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 } @@ -205,6 +216,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 {