Skip to content

Commit

Permalink
Can read from all documents
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Farah committed Jul 8, 2018
1 parent 2c15048 commit 86b9fe3
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 64 deletions.
32 changes: 29 additions & 3 deletions commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ func TestReadCmd(t *testing.T) {
assertResult(t, "2\n", result.Output)
}

func TestReadOrderCmd(t *testing.T) {
cmd := getRootCommand()
result := runCmd(cmd, "read examples/order.yaml")
if result.Error != nil {
t.Error(result.Error)
}
assertResult(t,
`version: 3
application: MyApp
`,
result.Output)
}

func TestReadMultiCmd(t *testing.T) {
cmd := getRootCommand()
result := runCmd(cmd, "read -d 1 examples/multiple_docs.yaml another.document")
Expand All @@ -113,6 +126,19 @@ func TestReadMultiCmd(t *testing.T) {
assertResult(t, "here\n", result.Output)
}

func TestReadMultiAllCmd(t *testing.T) {
cmd := getRootCommand()
result := runCmd(cmd, "read -d* examples/multiple_docs.yaml commonKey")
if result.Error != nil {
t.Error(result.Error)
}
assertResult(t,
`- first document
- second document
- third document
`, result.Output)
}

func TestReadCmd_ArrayYaml(t *testing.T) {
cmd := getRootCommand()
result := runCmd(cmd, "read examples/array.yaml [0].gather_facts")
Expand Down Expand Up @@ -192,7 +218,7 @@ func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) {
if result.Error == nil {
t.Error("Expected command to fail due to invalid path")
}
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
assertResult(t, expectedOutput, result.Error.Error())
}

Expand All @@ -202,7 +228,7 @@ func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) {
if result.Error == nil {
t.Error("Expected command to fail due to invalid path")
}
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
assertResult(t, expectedOutput, result.Error.Error())
}

Expand Down Expand Up @@ -254,7 +280,7 @@ func TestReadCmd_ErrorBadPath(t *testing.T) {
if result.Error == nil {
t.Fatal("Expected command to fail due to invalid path")
}
expectedOutput := `Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
expectedOutput := `Error reading path in document index 0: Error accessing array: strconv.ParseInt: parsing "x": invalid syntax`
assertResult(t, expectedOutput, result.Error.Error())
}

Expand Down
4 changes: 0 additions & 4 deletions examples/multiple_docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,3 @@ another:
commonKey: third document
wow:
- here is another
---
- 1
- 2
- 3
83 changes: 57 additions & 26 deletions yq.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ yq r things.yaml a.array[*].blah
Long: "Outputs the value of the given path in the yaml file to STDOUT",
RunE: readProperty,
}
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number, 0 based")
cmdRead.PersistentFlags().StringVarP(&docIndex, "doc", "d", "0", "process document index number (0 based, * for all documents)")
cmdRead.PersistentFlags().BoolVarP(&outputToJSON, "tojson", "j", false, "output as json")
return cmdRead
}
Expand Down Expand Up @@ -211,40 +211,71 @@ Note that if you set both flags only overwrite will take effect.
}

func readProperty(cmd *cobra.Command, args []string) error {
data, err := read(args)
if err != nil {
return err
}
dataStr, err := toString(data)
if err != nil {
return err
}
cmd.Println(dataStr)
return nil
}

func read(args []string) (interface{}, error) {
var path = ""

if len(args) < 1 {
return nil, errors.New("Must provide filename")
return errors.New("Must provide filename")
} else if len(args) > 1 {
path = args[1]
}
var generalData interface{}
var docIndexInt, errorParsingDocumentIndex = strconv.ParseInt(docIndex, 10, 32)
if errorParsingDocumentIndex != nil {
return nil, errors.Wrapf(errorParsingDocumentIndex, "Document index %v is not a integer", docIndex)

var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex()
if errorParsingDocIndex != nil {
return errorParsingDocIndex
}
var mappedDocs []interface{}
var dataBucket interface{}
var currentIndex = 0
var errorReadingStream = readStream(args[0], func(decoder *yaml.Decoder) error {
for {
errorReading := decoder.Decode(&dataBucket)
if errorReading == io.EOF {
log.Debugf("done %v / %v", currentIndex, docIndexInt)
if !updateAll && currentIndex <= docIndexInt {
return fmt.Errorf("Asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
}
return nil
}
log.Debugf("processing %v / %v", currentIndex, docIndexInt)
if updateAll || currentIndex == docIndexInt {
log.Debugf("reading %v in %v", path, currentIndex)
mappedDoc, errorParsing := readPath(dataBucket, path)
log.Debugf("%v", mappedDoc)
if errorParsing != nil {
return errors.Wrapf(errorParsing, "Error reading path in document index %v", currentIndex)
}
mappedDocs = append(mappedDocs, mappedDoc)
log.Debugf("%v", mappedDocs)
}
currentIndex = currentIndex + 1
}
})

if errorReadingStream != nil {
return errorReadingStream
}

if !updateAll {
dataBucket = mappedDocs[0]
} else {
dataBucket = mappedDocs
}
if err := readData(args[0], int(docIndexInt), &generalData); err != nil {
return nil, err

dataStr, err := toString(dataBucket)
if err != nil {
return err
}
cmd.Println(dataStr)
return nil
}

func readPath(dataBucket interface{}, path string) (interface{}, error) {
if path == "" {
return generalData, nil
log.Debug("no path")
return dataBucket, nil
}

var paths = parsePath(path)
return recurse(generalData, paths[0], paths[1:])
return recurse(dataBucket, paths[0], paths[1:])
}

func newProperty(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -316,8 +347,8 @@ func mapYamlDecoder(updateData updateDataFn, encoder *yaml.Encoder) yamlDecoderF
errorReading = decoder.Decode(&dataBucket)

if errorReading == io.EOF {
if !updateAll && currentIndex < docIndexInt {
return fmt.Errorf("Asked to process document %v but there are only %v document(s)", docIndex, currentIndex)
if !updateAll && currentIndex <= docIndexInt {
return fmt.Errorf("Asked to process document index %v but there are only %v document(s)", docIndex, currentIndex)
}
return nil
} else if errorReading != nil {
Expand Down
31 changes: 0 additions & 31 deletions yq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,6 @@ func TestParseValue(t *testing.T) {
}
}

func TestRead(t *testing.T) {
result, _ := read([]string{"examples/sample.yaml", "b.c"})
assertResult(t, 2, result)
}

func TestReadMulti(t *testing.T) {
docIndex = "1"
result, _ := read([]string{"examples/multiple_docs.yaml", "another.document"})
assertResult(t, "here", result)
docIndex = "0"
}

func TestReadArray(t *testing.T) {
result, _ := read([]string{"examples/sample_array.yaml", "[1]"})
assertResult(t, 2, result)
}

func TestReadString(t *testing.T) {
result, _ := read([]string{"examples/sample_text.yaml"})
assertResult(t, "hi", result)
}

func TestOrder(t *testing.T) {
result, _ := read([]string{"examples/order.yaml"})
formattedResult, _ := yamlToString(result)
assertResult(t,
`version: 3
application: MyApp`,
formattedResult)
}

func TestMultilineString(t *testing.T) {
testString := `
abcd
Expand Down

0 comments on commit 86b9fe3

Please sign in to comment.