Read now handles multiple documents

This commit is contained in:
Mike Farah 2018-06-12 15:33:59 +10:00
parent ebdc092688
commit 06a843e9b2
5 changed files with 58 additions and 14 deletions

View File

@ -0,0 +1,15 @@
a: Easy! as one two three
b:
c: 2
d: [3, 4]
e:
- name: fred
value: 3
- name: sam
value: 4
---
another:
document: here
---
wow:
- here is another

6
vendor/vendor.json vendored
View File

@ -33,10 +33,10 @@
"revisionTime": "2017-08-24T17:57:12Z" "revisionTime": "2017-08-24T17:57:12Z"
}, },
{ {
"checksumSHA1": "RDJpJQwkF012L6m/2BJizyOksNw=", "checksumSHA1": "ZSWoOPUNRr5+3dhkLK3C4cZAQPk=",
"path": "gopkg.in/yaml.v2", "path": "gopkg.in/yaml.v2",
"revision": "eb3733d160e74a9c7e442f435eb3bea458e1d19f", "revision": "5420a8b6744d3b0345ab293f6fcba19c978f1183",
"revisionTime": "2017-08-12T16:00:11Z" "revisionTime": "2018-03-28T19:50:20Z"
} }
], ],
"rootPath": "github.com/mikefarah/yq" "rootPath": "github.com/mikefarah/yq"

42
yq.go
View File

@ -1,8 +1,10 @@
package main package main
import ( import (
"bufio"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"strconv" "strconv"
@ -20,6 +22,7 @@ var outputToJSON = false
var overwriteFlag = false var overwriteFlag = false
var verbose = false var verbose = false
var version = false var version = false
var docIndex = 0
var log = logging.MustGetLogger("yq") var log = logging.MustGetLogger("yq")
func main() { func main() {
@ -77,10 +80,10 @@ func newCommandCLI() *cobra.Command {
} }
func createReadCmd() *cobra.Command { func createReadCmd() *cobra.Command {
return &cobra.Command{ var cmdRead = &cobra.Command{
Use: "read [yaml_file] [path]", Use: "read [yaml_file] [path]",
Aliases: []string{"r"}, Aliases: []string{"r"},
Short: "yq r sample.yaml a.b.c", Short: "yq r [--doc/-d document_index] sample.yaml a.b.c",
Example: ` Example: `
yq read things.yaml a.b.c yq read things.yaml a.b.c
yq r - a.b.c (reads from stdin) yq r - a.b.c (reads from stdin)
@ -91,6 +94,8 @@ yq r things.yaml a.array[*].blah
Long: "Outputs the value of the given path in the yaml file to STDOUT", Long: "Outputs the value of the given path in the yaml file to STDOUT",
RunE: readProperty, RunE: readProperty,
} }
cmdRead.PersistentFlags().IntVarP(&docIndex, "doc", "d", 0, "process document index number (0 based)")
return cmdRead
} }
func createWriteCmd() *cobra.Command { func createWriteCmd() *cobra.Command {
@ -499,22 +504,39 @@ func marshalContext(context interface{}) (string, error) {
return outStr, nil return outStr, nil
} }
func safelyCloseFile(file *os.File) {
err := file.Close()
if err != nil {
fmt.Println("Error closing file!")
fmt.Println(err.Error())
}
}
func readData(filename string, parsedData interface{}) error { func readData(filename string, parsedData interface{}) error {
if filename == "" { if filename == "" {
return errors.New("Must provide filename") return errors.New("Must provide filename")
} }
var rawData []byte var stream io.Reader
var err error
if filename == "-" { if filename == "-" {
rawData, err = ioutil.ReadAll(os.Stdin) stream = bufio.NewReader(os.Stdin)
} else { } else {
rawData, err = ioutil.ReadFile(filename) file, err := os.Open(filename)
}
if err != nil { if err != nil {
return err return err
} }
defer safelyCloseFile(file)
return yaml.Unmarshal(rawData, parsedData) stream = file
}
var decoder = yaml.NewDecoder(stream)
// naive implementation of document indexing, decodes all the yaml documents
// before the docIndex and throws them away.
for currentIndex := 0; currentIndex < docIndex; currentIndex++ {
errorSkipping := decoder.Decode(parsedData)
if errorSkipping != nil {
return fmt.Errorf("Error processing document at index %v, %v", currentIndex, errorSkipping)
}
}
return decoder.Decode(parsedData)
} }

View File

@ -28,6 +28,13 @@ func TestRead(t *testing.T) {
assertResult(t, 2, result) 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) { func TestReadArray(t *testing.T) {
result, _ := read([]string{"examples/sample_array.yaml", "[1]"}) result, _ := read([]string{"examples/sample_array.yaml", "[1]"})
assertResult(t, 2, result) assertResult(t, 2, result)