diff --git a/pkg/input/record_reader_json.go b/pkg/input/record_reader_json.go index 80ce17440..aaa49a178 100644 --- a/pkg/input/record_reader_json.go +++ b/pkg/input/record_reader_json.go @@ -17,6 +17,8 @@ import ( type RecordReaderJSON struct { readerOptions *cli.TReaderOptions recordsPerBatch int64 // distinct from readerOptions.RecordsPerBatch for join/repl + // XXX 1513 + sawBrackets bool } func NewRecordReaderJSON( @@ -65,6 +67,7 @@ func (reader *RecordReaderJSON) Read( } } } + context.JSONHadBrackets = reader.sawBrackets readerChannel <- types.NewEndOfStreamMarkerList(&context) } @@ -137,6 +140,9 @@ func (reader *RecordReaderJSON) processHandle( } } else if mlrval.IsArray() { + + reader.sawBrackets = true + records := mlrval.GetArray() if records == nil { errorChannel <- fmt.Errorf("internal coding error detected in JSON record-reader") diff --git a/pkg/output/channel_writer.go b/pkg/output/channel_writer.go index e7b0e802e..3eb8b1338 100644 --- a/pkg/output/channel_writer.go +++ b/pkg/output/channel_writer.go @@ -66,6 +66,7 @@ func channelWriterHandleBatch( if !recordAndContext.EndOfStream { record := recordAndContext.Record + context := &recordAndContext.Context // XXX more // XXX also make sure this results in exit 1 & goroutine cleanup @@ -94,7 +95,7 @@ func channelWriterHandleBatch( } if record != nil { - err := recordWriter.Write(record, bufferedOutputStream, outputIsStdout) + err := recordWriter.Write(record, context, bufferedOutputStream, outputIsStdout) if err != nil { fmt.Fprintf(os.Stderr, "mlr: %v\n", err) return true, true @@ -115,7 +116,8 @@ func channelWriterHandleBatch( // queued up. For example, PPRINT needs to see all same-schema // records before printing any, since it needs to compute max width // down columns. - err := recordWriter.Write(nil, bufferedOutputStream, outputIsStdout) + context := &recordAndContext.Context + err := recordWriter.Write(nil, context, bufferedOutputStream, outputIsStdout) if err != nil { fmt.Fprintf(os.Stderr, "mlr: %v\n", err) return true, true diff --git a/pkg/output/record_writer.go b/pkg/output/record_writer.go index 3ce49743d..ceb7522d2 100644 --- a/pkg/output/record_writer.go +++ b/pkg/output/record_writer.go @@ -4,6 +4,7 @@ import ( "bufio" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) // IRecordWriter is the abstract interface for all record-writers. They are @@ -18,6 +19,7 @@ import ( type IRecordWriter interface { Write( outrec *mlrval.Mlrmap, + context *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error diff --git a/pkg/output/record_writer_csv.go b/pkg/output/record_writer_csv.go index b71af63d2..032a57f03 100644 --- a/pkg/output/record_writer_csv.go +++ b/pkg/output/record_writer_csv.go @@ -9,6 +9,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterCSV struct { @@ -41,6 +42,7 @@ func NewRecordWriterCSV(writerOptions *cli.TWriterOptions) (*RecordWriterCSV, er func (writer *RecordWriterCSV) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_csvlite.go b/pkg/output/record_writer_csvlite.go index c59556b30..e3ecf9196 100644 --- a/pkg/output/record_writer_csvlite.go +++ b/pkg/output/record_writer_csvlite.go @@ -7,6 +7,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterCSVLite struct { @@ -27,6 +28,7 @@ func NewRecordWriterCSVLite(writerOptions *cli.TWriterOptions) (*RecordWriterCSV func (writer *RecordWriterCSVLite) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_dkvp.go b/pkg/output/record_writer_dkvp.go index d27420ede..d7a516955 100644 --- a/pkg/output/record_writer_dkvp.go +++ b/pkg/output/record_writer_dkvp.go @@ -6,6 +6,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterDKVP struct { @@ -20,6 +21,7 @@ func NewRecordWriterDKVP(writerOptions *cli.TWriterOptions) (*RecordWriterDKVP, func (writer *RecordWriterDKVP) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_json.go b/pkg/output/record_writer_json.go index e832f169e..1a1e7ed58 100644 --- a/pkg/output/record_writer_json.go +++ b/pkg/output/record_writer_json.go @@ -7,6 +7,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) // ---------------------------------------------------------------- @@ -17,7 +18,7 @@ type RecordWriterJSON struct { jvQuoteAll bool // State: - onFirst bool + wroteAnyRecords bool } // ---------------------------------------------------------------- @@ -27,16 +28,17 @@ func NewRecordWriterJSON(writerOptions *cli.TWriterOptions) (*RecordWriterJSON, jsonFormatting = mlrval.JSON_MULTILINE } return &RecordWriterJSON{ - writerOptions: writerOptions, - jsonFormatting: jsonFormatting, - jvQuoteAll: writerOptions.JVQuoteAll, - onFirst: true, + writerOptions: writerOptions, + jsonFormatting: jsonFormatting, + jvQuoteAll: writerOptions.JVQuoteAll, + wroteAnyRecords: false, }, nil } // ---------------------------------------------------------------- func (writer *RecordWriterJSON) Write( outrec *mlrval.Mlrmap, + context *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { @@ -45,9 +47,9 @@ func (writer *RecordWriterJSON) Write( } if writer.writerOptions.WrapJSONOutputInOuterList { - writer.writeWithListWrap(outrec, bufferedOutputStream, outputIsStdout) + writer.writeWithListWrap(outrec, context, bufferedOutputStream, outputIsStdout) } else { - writer.writeWithoutListWrap(outrec, bufferedOutputStream, outputIsStdout) + writer.writeWithoutListWrap(outrec, context, bufferedOutputStream, outputIsStdout) } return nil } @@ -55,11 +57,12 @@ func (writer *RecordWriterJSON) Write( // ---------------------------------------------------------------- func (writer *RecordWriterJSON) writeWithListWrap( outrec *mlrval.Mlrmap, + context *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) { if outrec != nil { // Not end of record stream - if writer.onFirst { + if !writer.wroteAnyRecords { bufferedOutputStream.WriteString("[\n") } @@ -71,25 +74,32 @@ func (writer *RecordWriterJSON) writeWithListWrap( os.Exit(1) } - if !writer.onFirst { + if writer.wroteAnyRecords { bufferedOutputStream.WriteString(",\n") } bufferedOutputStream.WriteString(s) - writer.onFirst = false + writer.wroteAnyRecords = true } else { // End of record stream - if writer.onFirst { // zero records in the entire output stream - bufferedOutputStream.WriteString("[") + + if !writer.wroteAnyRecords { + if context.JSONHadBrackets { + bufferedOutputStream.WriteString("[") + bufferedOutputStream.WriteString("\n]\n") + } + } else { + bufferedOutputStream.WriteString("\n]\n") } - bufferedOutputStream.WriteString("\n]\n") + } } // ---------------------------------------------------------------- func (writer *RecordWriterJSON) writeWithoutListWrap( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) { diff --git a/pkg/output/record_writer_markdown.go b/pkg/output/record_writer_markdown.go index 6c2983a59..94137822d 100644 --- a/pkg/output/record_writer_markdown.go +++ b/pkg/output/record_writer_markdown.go @@ -7,6 +7,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterMarkdown struct { @@ -29,6 +30,7 @@ func NewRecordWriterMarkdown(writerOptions *cli.TWriterOptions) (*RecordWriterMa // ---------------------------------------------------------------- func (writer *RecordWriterMarkdown) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_nidx.go b/pkg/output/record_writer_nidx.go index 551fe47aa..b8a5573c1 100644 --- a/pkg/output/record_writer_nidx.go +++ b/pkg/output/record_writer_nidx.go @@ -5,6 +5,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterNIDX struct { @@ -19,6 +20,7 @@ func NewRecordWriterNIDX(writerOptions *cli.TWriterOptions) (*RecordWriterNIDX, func (writer *RecordWriterNIDX) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_pprint.go b/pkg/output/record_writer_pprint.go index b9f48cd93..6b2f92f1f 100644 --- a/pkg/output/record_writer_pprint.go +++ b/pkg/output/record_writer_pprint.go @@ -10,6 +10,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterPPRINT struct { @@ -35,6 +36,7 @@ func NewRecordWriterPPRINT(writerOptions *cli.TWriterOptions) (*RecordWriterPPRI // ---------------------------------------------------------------- func (writer *RecordWriterPPRINT) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_tsv.go b/pkg/output/record_writer_tsv.go index 2a79793b2..40f89350a 100644 --- a/pkg/output/record_writer_tsv.go +++ b/pkg/output/record_writer_tsv.go @@ -9,6 +9,7 @@ import ( "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/lib" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) type RecordWriterTSV struct { @@ -35,6 +36,7 @@ func NewRecordWriterTSV(writerOptions *cli.TWriterOptions) (*RecordWriterTSV, er func (writer *RecordWriterTSV) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/output/record_writer_xtab.go b/pkg/output/record_writer_xtab.go index 27f3b1bcb..cd014ddce 100644 --- a/pkg/output/record_writer_xtab.go +++ b/pkg/output/record_writer_xtab.go @@ -8,6 +8,7 @@ import ( "github.com/johnkerl/miller/pkg/cli" "github.com/johnkerl/miller/pkg/colorizer" "github.com/johnkerl/miller/pkg/mlrval" + "github.com/johnkerl/miller/pkg/types" ) // ---------------------------------------------------------------- @@ -43,6 +44,7 @@ func NewRecordWriterXTAB(writerOptions *cli.TWriterOptions) (*RecordWriterXTAB, func (writer *RecordWriterXTAB) Write( outrec *mlrval.Mlrmap, + _ *types.Context, bufferedOutputStream *bufio.Writer, outputIsStdout bool, ) error { diff --git a/pkg/terminals/repl/verbs.go b/pkg/terminals/repl/verbs.go index 92d9046ff..ac5440ffd 100644 --- a/pkg/terminals/repl/verbs.go +++ b/pkg/terminals/repl/verbs.go @@ -639,7 +639,8 @@ func writeRecord(repl *Repl, outrec *mlrval.Mlrmap) { outrec.Unflatten(repl.options.WriterOptions.FLATSEP) } } - repl.recordWriter.Write(outrec, repl.bufferedRecordOutputStream, true /*outputIsStdout*/) + // XXX TEMP + repl.recordWriter.Write(outrec, nil, repl.bufferedRecordOutputStream, true /*outputIsStdout*/) repl.bufferedRecordOutputStream.Flush() } diff --git a/pkg/types/context.go b/pkg/types/context.go index 08ba3cbb6..a3da4f71a 100644 --- a/pkg/types/context.go +++ b/pkg/types/context.go @@ -99,6 +99,9 @@ type Context struct { // NF int NR int64 FNR int64 + + // XXX 1513 + JSONHadBrackets bool } // TODO: comment: Remember command-line values to pass along to CST evaluators. diff --git a/test/cases/dsl-functional-tests/0051/expout b/test/cases/dsl-functional-tests/0051/expout index d14a2c4d2..97353ee3a 100644 --- a/test/cases/dsl-functional-tests/0051/expout +++ b/test/cases/dsl-functional-tests/0051/expout @@ -60,5 +60,3 @@ "zsgnt": "int" } ] -[ -] diff --git a/test/cases/dsl-output-redirects/0071/expout b/test/cases/dsl-output-redirects/0071/expout index 4a1435f7c..eed189aad 100644 --- a/test/cases/dsl-output-redirects/0071/expout +++ b/test/cases/dsl-output-redirects/0071/expout @@ -9,5 +9,3 @@ x 8 9 10 -[ -] diff --git a/test/cases/dsl-sorts/sorta-natural/expout b/test/cases/dsl-sorts/sorta-natural/expout index 01349be34..05972250a 100644 --- a/test/cases/dsl-sorts/sorta-natural/expout +++ b/test/cases/dsl-sorts/sorta-natural/expout @@ -2,5 +2,3 @@ ["X200", "X20", "X2", "X100", "X10", "X1"] ["X1", "X2", "X10", "X20", "X100", "X200"] ["X200", "X100", "X20", "X10", "X2", "X1"] -[ -] diff --git a/test/cases/dsl-sorts/sortmf-within/expout b/test/cases/dsl-sorts/sortmf-within/expout index c683738c5..acb15cce5 100644 --- a/test/cases/dsl-sorts/sortmf-within/expout +++ b/test/cases/dsl-sorts/sortmf-within/expout @@ -18,5 +18,3 @@ "b": 2, "c": 1 } -[ -] diff --git a/test/cases/io-multi/0053/expout b/test/cases/io-multi/0053/expout index 0d4f101c7..e69de29bb 100644 --- a/test/cases/io-multi/0053/expout +++ b/test/cases/io-multi/0053/expout @@ -1,2 +0,0 @@ -[ -] diff --git a/test/cases/io-multi/0057/expout b/test/cases/io-multi/0057/expout index 0d4f101c7..e69de29bb 100644 --- a/test/cases/io-multi/0057/expout +++ b/test/cases/io-multi/0057/expout @@ -1,2 +0,0 @@ -[ -]