diff --git a/cli/cli.go b/cli/cli.go index 4bfc4273..f4f70797 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -260,7 +260,9 @@ Synopsis: } func slurpFile(name string) (interface{}, error) { - iter := newSlurpInputIter(newFilesInputIter(newJSONInputIter, []string{name})) + iter := newSlurpInputIter( + newFilesInputIter(newJSONInputIter, []string{name}, nil), + ) defer iter.Close() val, _ := iter.Next() if err, ok := val.(error); ok { @@ -293,7 +295,7 @@ func (cli *cli) createInputIter(args []string) (iter inputIter) { if len(args) == 0 { return newIter(cli.inStream, "") } - return newFilesInputIter(newIter, args) + return newFilesInputIter(newIter, args, cli.inStream) } func (cli *cli) process(iter inputIter, code *gojq.Code) error { diff --git a/cli/inputs.go b/cli/inputs.go index 8ba5e47d..8bfe6e12 100644 --- a/cli/inputs.go +++ b/cli/inputs.go @@ -147,13 +147,16 @@ func (i *nullInputIter) Name() string { type filesInputIter struct { newIter func(io.Reader, string) inputIter fnames []string + stdin io.Reader iter inputIter - file *os.File + file io.Reader err error } -func newFilesInputIter(newIter func(io.Reader, string) inputIter, fnames []string) inputIter { - return &filesInputIter{newIter: newIter, fnames: fnames} +func newFilesInputIter( + newIter func(io.Reader, string) inputIter, fnames []string, stdin io.Reader, +) inputIter { + return &filesInputIter{newIter: newIter, fnames: fnames, stdin: stdin} } func (i *filesInputIter) Next() (interface{}, bool) { @@ -168,11 +171,15 @@ func (i *filesInputIter) Next() (interface{}, bool) { } fname := i.fnames[0] i.fnames = i.fnames[1:] - file, err := os.Open(fname) - if err != nil { - return err, true + if fname == "-" && i.stdin != nil { + i.file, fname = i.stdin, "" + } else { + file, err := os.Open(fname) + if err != nil { + return err, true + } + i.file = file } - i.file = file if i.iter != nil { i.iter.Close() } @@ -181,14 +188,18 @@ func (i *filesInputIter) Next() (interface{}, bool) { if v, ok := i.iter.Next(); ok { return v, ok } - i.file.Close() + if r, ok := i.file.(io.Closer); ok && i.file != i.stdin { + r.Close() + } i.file = nil } } func (i *filesInputIter) Close() error { if i.file != nil { - i.file.Close() + if r, ok := i.file.(io.Closer); ok && i.file != i.stdin { + r.Close() + } i.file = nil i.err = io.EOF } @@ -196,8 +207,8 @@ func (i *filesInputIter) Close() error { } func (i *filesInputIter) Name() string { - if i.file != nil { - return i.file.Name() + if i.iter != nil { + return i.iter.Name() } return "" } diff --git a/cli/test.yaml b/cli/test.yaml index a0f6c896..c1ea3dbe 100644 --- a/cli/test.yaml +++ b/cli/test.yaml @@ -4197,6 +4197,20 @@ "testdata/1.json" "testdata/2.json" +- name: input_filename function with hyphen for stdin + args: + - 'input_filename' + - '-' + - 'testdata/1.json' + - '-' + - 'testdata/2.json' + - '-' + input: '0' + expected: | + "" + "testdata/1.json" + "testdata/2.json" + - name: input_filename function with yaml input option args: - --yaml-input @@ -5566,6 +5580,18 @@ "bar" ] +- name: yaml input option with hyphen for stdin + args: + - --yaml-input + - '.' + - '-' + input: | + foo: 1 + expected: | + { + "foo": 1 + } + - name: yaml input option error args: - --yaml-input @@ -5915,6 +5941,14 @@ "bar": [] } +- name: hyphen for stdin + args: + - '.' + - '-' + input: '{}' + expected: | + {} + - name: json file arguments args: - '.' @@ -6324,6 +6358,16 @@ .foo.bar ^ invalid character '.' looking for beginning of value +- name: slurpfile option error + args: + - --slurpfile + - 'foo' + - '-' + - '{ $foo }' + input: 'null' + error: | + open -: no such file or directory + - name: rawfile option args: - --rawfile