Skip to content

Commit

Permalink
fix slurp option with JSON file arguments (close #55)
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Dec 24, 2020
1 parent 7058a05 commit b6b82c8
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 41 deletions.
20 changes: 11 additions & 9 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ Synopsis:
}

func slurpFile(name string) (interface{}, error) {
iter := newFilesInputIter(newSlurpInputIter(newJSONInputIter), []string{name})
iter := newSlurpInputIter(newFilesInputIter(newJSONInputIter, []string{name}))
defer iter.Close()
val, _ := iter.Next()
if err, ok := val.(error); ok {
Expand All @@ -246,24 +246,26 @@ func slurpFile(name string) (interface{}, error) {
return val, nil
}

func (cli *cli) createInputIter(args []string) inputIter {
func (cli *cli) createInputIter(args []string) (iter inputIter) {
var newIter func(io.Reader, string) inputIter
switch {
case cli.inputRaw:
if cli.inputSlurp {
newIter = newReadAllInputIter
} else {
newIter = newRawInputIter
}
newIter = newRawInputIter
case cli.inputStream:
newIter = newStreamInputIter
case cli.inputYAML:
newIter = newYAMLInputIter
default:
newIter = newJSONInputIter
}
if cli.inputSlurp && !cli.inputRaw {
newIter = newSlurpInputIter(newIter)
if cli.inputSlurp {
defer func() {
if cli.inputRaw {
iter = newSlurpRawInputIter(iter)
} else {
iter = newSlurpInputIter(iter)
}
}()
}
if len(args) == 0 {
return newIter(cli.inStream, "<stdin>")
Expand Down
74 changes: 42 additions & 32 deletions cli/inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"os"
"strings"

"gopkg.in/yaml.v3"

Expand Down Expand Up @@ -156,33 +156,6 @@ func (i *rawInputIter) Close() error {
return nil
}

type readAllInputIter struct {
r io.Reader
err error
}

func newReadAllInputIter(r io.Reader, _ string) inputIter {
return &readAllInputIter{r: r}
}

func (i *readAllInputIter) Next() (interface{}, bool) {
if i.err != nil {
return nil, false
}
bs, err := ioutil.ReadAll(i.r)
if err != nil {
i.err = err
return err, true
}
i.err = io.EOF
return string(bs), true
}

func (i *readAllInputIter) Close() error {
i.err = io.EOF
return nil
}

type streamInputIter struct {
stream *jsonStream
buf *bytes.Buffer
Expand Down Expand Up @@ -260,10 +233,8 @@ type slurpInputIter struct {
err error
}

func newSlurpInputIter(newIter func(io.Reader, string) inputIter) func(io.Reader, string) inputIter {
return func(r io.Reader, fname string) inputIter {
return &slurpInputIter{iter: newIter(r, fname)}
}
func newSlurpInputIter(iter inputIter) inputIter {
return &slurpInputIter{iter: iter}
}

func (i *slurpInputIter) Next() (interface{}, bool) {
Expand Down Expand Up @@ -294,3 +265,42 @@ func (i *slurpInputIter) Close() error {
}
return nil
}

type slurpRawInputIter struct {
iter inputIter
err error
}

func newSlurpRawInputIter(iter inputIter) inputIter {
return &slurpRawInputIter{iter: iter}
}

func (i *slurpRawInputIter) Next() (interface{}, bool) {
if i.err != nil {
return nil, false
}
var s strings.Builder
var v interface{}
var ok bool
for {
v, ok = i.iter.Next()
if !ok {
i.err = io.EOF
return s.String(), true
}
if i.err, ok = v.(error); ok {
return i.err, true
}
s.WriteString(v.(string))
s.WriteByte('\n')
}
}

func (i *slurpRawInputIter) Close() error {
if i.iter != nil {
i.iter.Close()
i.iter = nil
i.err = io.EOF
}
return nil
}
28 changes: 28 additions & 0 deletions cli/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4934,6 +4934,34 @@
expected: |
null
- name: slurp option with multiple json files
args:
- -s
- '.'
- testdata/1.json
- testdata/2.json
expected: |
[
{
"foo": 10
},
[
{
"bar": []
}
]
]
- name: slurp and raw input option with multiple json files
args:
- -R
- -s
- '.'
- testdata/1.json
- testdata/2.json
expected: |
"{\"foo\":10}\n[{\n\"bar\"\n:\n[]\n}]\n"
- name: stream option
args:
- -c
Expand Down

0 comments on commit b6b82c8

Please sign in to comment.