From 26abe3eb6d0deec405acf171d4d1d659287c0a2d Mon Sep 17 00:00:00 2001 From: Neil O'Toole Date: Fri, 7 Aug 2020 21:06:56 -0600 Subject: [PATCH] refactor cli.writers (#51) --- cli/cli.go | 124 ++++++++++++++++++++----------------------- cli/cmd_add.go | 8 +-- cli/cmd_drivers.go | 4 +- cli/cmd_inspect.go | 6 +-- cli/cmd_list.go | 2 +- cli/cmd_notify.go | 4 +- cli/cmd_ping.go | 2 +- cli/cmd_remove.go | 2 +- cli/cmd_scratch.go | 4 +- cli/cmd_slq.go | 10 ++-- cli/cmd_sql.go | 6 +-- cli/cmd_sql_test.go | 1 - cli/cmd_src.go | 4 +- cli/cmd_tbl.go | 10 ++-- cli/cmd_version.go | 6 +-- cli/config/config.go | 7 ++- cli/consts.go | 2 +- cli/source.go | 5 +- main.go | 1 + 19 files changed, 98 insertions(+), 110 deletions(-) diff --git a/cli/cli.go b/cli/cli.go index 4e86b962..36090334 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -271,11 +271,14 @@ type RunContext struct { // Log is the run's logger. Log lg.Log - wrtr *writers - reg *driver.Registry - files *source.Files - dbases *driver.Databases - clnup *cleanup.Cleanup + // writers holds the various writer types that + // the CLI uses to print output. + writers *writers + + registry *driver.Registry + files *source.Files + databases *driver.Databases + clnup *cleanup.Cleanup } // newDefaultRunContext returns a RunContext configured @@ -331,6 +334,9 @@ func (rc *RunContext) preRunE() error { rc.clnup = cleanup.New() log, cfg := rc.Log, rc.Config + // If the --output=/some/file flag is set, then we need to + // override rc.Out (which is typically stdout) to point it at + // the output destination file. if cmdFlagChanged(rc.Cmd, flagOutput) { fpath, _ := rc.Cmd.Flags().GetString(flagOutput) fpath, err := filepath.Abs(fpath) @@ -347,9 +353,7 @@ func (rc *RunContext) preRunE() error { rc.Out = f } - rc.wrtr = newWriters(rc.Log, rc.Cmd, rc.Config.Options, rc.Out, rc.ErrOut) - rc.Out = rc.wrtr.out - rc.ErrOut = rc.wrtr.errOut + rc.writers, rc.Out, rc.ErrOut = newWriters(rc.Log, rc.Cmd, rc.Config.Options, rc.Out, rc.ErrOut) var scratchSrcFunc driver.ScratchSrcFunc @@ -363,9 +367,9 @@ func (rc *RunContext) preRunE() error { } } - rc.reg = driver.NewRegistry(log) - rc.dbases = driver.NewDatabases(log, rc.reg, scratchSrcFunc) - rc.clnup.AddC(rc.dbases) + rc.registry = driver.NewRegistry(log) + rc.databases = driver.NewDatabases(log, rc.registry, scratchSrcFunc) + rc.clnup.AddC(rc.databases) var err error rc.files, err = source.NewFiles(log) @@ -374,16 +378,16 @@ func (rc *RunContext) preRunE() error { } rc.files.AddTypeDetectors(source.DetectMagicNumber) - rc.reg.AddProvider(sqlite3.Type, &sqlite3.Provider{Log: log}) - rc.reg.AddProvider(postgres.Type, &postgres.Provider{Log: log}) - rc.reg.AddProvider(sqlserver.Type, &sqlserver.Provider{Log: log}) - rc.reg.AddProvider(mysql.Type, &mysql.Provider{Log: log}) - csvp := &csv.Provider{Log: log, Scratcher: rc.dbases, Files: rc.files} - rc.reg.AddProvider(csv.TypeCSV, csvp) - rc.reg.AddProvider(csv.TypeTSV, csvp) + rc.registry.AddProvider(sqlite3.Type, &sqlite3.Provider{Log: log}) + rc.registry.AddProvider(postgres.Type, &postgres.Provider{Log: log}) + rc.registry.AddProvider(sqlserver.Type, &sqlserver.Provider{Log: log}) + rc.registry.AddProvider(mysql.Type, &mysql.Provider{Log: log}) + csvp := &csv.Provider{Log: log, Scratcher: rc.databases, Files: rc.files} + rc.registry.AddProvider(csv.TypeCSV, csvp) + rc.registry.AddProvider(csv.TypeTSV, csvp) rc.files.AddTypeDetectors(csv.DetectCSV, csv.DetectTSV) - rc.reg.AddProvider(xlsx.Type, &xlsx.Provider{Log: log, Scratcher: rc.dbases, Files: rc.files}) + rc.registry.AddProvider(xlsx.Type, &xlsx.Provider{Log: log, Scratcher: rc.databases, Files: rc.files}) rc.files.AddTypeDetectors(xlsx.DetectXLSX) // One day we may have more supported user driver genres. userDriverImporters := map[string]userdriver.ImportFunc{ @@ -413,11 +417,11 @@ func (rc *RunContext) preRunE() error { Log: log, DriverDef: userDriverDef, ImportFn: importFn, - Scratcher: rc.dbases, + Scratcher: rc.databases, Files: rc.files, } - rc.reg.AddProvider(source.Type(userDriverDef.Name), udp) + rc.registry.AddProvider(source.Type(userDriverDef.Name), udp) rc.files.AddTypeDetectors(udp.TypeDetectors()...) } @@ -441,26 +445,10 @@ func (rc *RunContext) Close() error { return err } -// writers returns this run context's writers instance. -func (rc *RunContext) writers() *writers { - return rc.wrtr -} - -// registry returns rc's Registry instance. -func (rc *RunContext) registry() *driver.Registry { - return rc.reg -} - -// registry returns rc's Databases instance. -func (rc *RunContext) databases() *driver.Databases { - return rc.dbases -} - -// writers is a container for the various output writer types. +// writers is a container for the various output writers. type writers struct { - out io.Writer - errOut io.Writer - fmt *output.Formatting + fmt *output.Formatting + recordw output.RecordWriter metaw output.MetadataWriter srcw output.SourceWriter @@ -469,8 +457,12 @@ type writers struct { pingw output.PingWriter } -func newWriters(log lg.Log, cmd *cobra.Command, opts config.Options, out, errOut io.Writer) *writers { - fm, out, errOut := getWriterFormatting(cmd, out, errOut) +// newWriters returns a writers instance configured per opts and/or +// flags from cmd. The returned out2/errOut2 values may differ +// from the out/errOut args (e.g. decorated to support colorization). +func newWriters(log lg.Log, cmd *cobra.Command, opts config.Options, out, errOut io.Writer) (w *writers, out2, errOut2 io.Writer) { + var fm *output.Formatting + fm, out2, errOut2 = getWriterFormatting(cmd, out, errOut) // we need to determine --header here because the writer/format // constructor functions, e.g. table.NewRecordWriter, require it. @@ -494,16 +486,14 @@ func newWriters(log lg.Log, cmd *cobra.Command, opts config.Options, out, errOut // so we use its writers as the baseline. Later we check the format // flags and set the various writer fields depending upon which // writers the format implements. - w := &writers{ - out: out, - errOut: errOut, + w = &writers{ fmt: fm, - recordw: tablew.NewRecordWriter(out, fm, hasHeader), - metaw: tablew.NewMetadataWriter(out, fm), - srcw: tablew.NewSourceWriter(out, fm, hasHeader, verbose), - pingw: tablew.NewPingWriter(out, fm), - notifyw: tablew.NewNotifyWriter(out, fm, hasHeader), - errw: tablew.NewErrorWriter(errOut, fm), + recordw: tablew.NewRecordWriter(out2, fm, hasHeader), + metaw: tablew.NewMetadataWriter(out2, fm), + srcw: tablew.NewSourceWriter(out2, fm, hasHeader, verbose), + pingw: tablew.NewPingWriter(out2, fm), + notifyw: tablew.NewNotifyWriter(out2, fm, hasHeader), + errw: tablew.NewErrorWriter(errOut2, fm), } // Invoke getFormat to see if the format was specified @@ -513,44 +503,44 @@ func newWriters(log lg.Log, cmd *cobra.Command, opts config.Options, out, errOut switch format { default: // No format specified, use JSON - w.recordw = jsonw.NewStdRecordWriter(out, fm) - w.metaw = jsonw.NewMetadataWriter(out, fm) - w.errw = jsonw.NewErrorWriter(log, errOut, fm) + w.recordw = jsonw.NewStdRecordWriter(out2, fm) + w.metaw = jsonw.NewMetadataWriter(out2, fm) + w.errw = jsonw.NewErrorWriter(log, errOut2, fm) case config.FormatTable: // Table is the base format, already set above, no need to do anything. case config.FormatTSV: - w.recordw = csvw.NewRecordWriter(out, hasHeader, csvw.Tab) - w.pingw = csvw.NewPingWriter(out, csvw.Tab) + w.recordw = csvw.NewRecordWriter(out2, hasHeader, csvw.Tab) + w.pingw = csvw.NewPingWriter(out2, csvw.Tab) case config.FormatCSV: - w.recordw = csvw.NewRecordWriter(out, hasHeader, csvw.Comma) - w.pingw = csvw.NewPingWriter(out, csvw.Comma) + w.recordw = csvw.NewRecordWriter(out2, hasHeader, csvw.Comma) + w.pingw = csvw.NewPingWriter(out2, csvw.Comma) case config.FormatXML: - w.recordw = xmlw.NewRecordWriter(out, fm) + w.recordw = xmlw.NewRecordWriter(out2, fm) case config.FormatXLSX: - w.recordw = xlsxw.NewRecordWriter(out, hasHeader) + w.recordw = xlsxw.NewRecordWriter(out2, hasHeader) case config.FormatRaw: - w.recordw = raww.NewRecordWriter(out) + w.recordw = raww.NewRecordWriter(out2) case config.FormatHTML: - w.recordw = htmlw.NewRecordWriter(out) + w.recordw = htmlw.NewRecordWriter(out2) case config.FormatMarkdown: - w.recordw = markdownw.NewRecordWriter(out) + w.recordw = markdownw.NewRecordWriter(out2) case config.FormatJSONA: - w.recordw = jsonw.NewArrayRecordWriter(out, fm) + w.recordw = jsonw.NewArrayRecordWriter(out2, fm) case config.FormatJSONL: - w.recordw = jsonw.NewObjectRecordWriter(out, fm) + w.recordw = jsonw.NewObjectRecordWriter(out2, fm) } - return w + return w, out2, errOut2 } // getWriterFormatting returns a Formatting instance and @@ -749,7 +739,7 @@ func printError(rc *RunContext, err error) { } log.Errorf("%s [%T] %+v", cmdName, err, err) - wrtrs := rc.writers() + wrtrs := rc.writers if wrtrs != nil && wrtrs.errw != nil { // If we have an errorWriter, we print to it // and return. diff --git a/cli/cmd_add.go b/cli/cmd_add.go index 1550d7b7..9279bc8f 100644 --- a/cli/cmd_add.go +++ b/cli/cmd_add.go @@ -95,7 +95,7 @@ func execSrcAdd(rc *RunContext, cmd *cobra.Command, args []string) error { if cmd.Flags().Changed(flagDriver) { val, _ := cmd.Flags().GetString(flagDriver) typ = source.Type(strings.TrimSpace(val)) - if !rc.reg.HasProviderFor(typ) { + if !rc.registry.HasProviderFor(typ) { return errz.Errorf("unsupported source driver type %q", val) } } else { @@ -154,7 +154,7 @@ func execSrcAdd(rc *RunContext, cmd *cobra.Command, args []string) error { } } - src, err := newSource(rc.Log, rc.registry(), typ, handle, loc, opts) + src, err := newSource(rc.Log, rc.registry, typ, handle, loc, opts) if err != nil { return err } @@ -172,7 +172,7 @@ func execSrcAdd(rc *RunContext, cmd *cobra.Command, args []string) error { } } - drvr, err := rc.registry().DriverFor(src.Type) + drvr, err := rc.registry.DriverFor(src.Type) if err != nil { return err } @@ -188,5 +188,5 @@ func execSrcAdd(rc *RunContext, cmd *cobra.Command, args []string) error { return err } - return rc.writers().srcw.Source(src) + return rc.writers.srcw.Source(src) } diff --git a/cli/cmd_drivers.go b/cli/cmd_drivers.go index 3127764d..543ac666 100644 --- a/cli/cmd_drivers.go +++ b/cli/cmd_drivers.go @@ -26,6 +26,6 @@ func execDrivers(rc *RunContext, cmd *cobra.Command, args []string) error { return errz.Errorf("invalid arguments: zero arguments expected") } - drvrs := rc.registry().DriversMetadata() - return rc.writers().metaw.DriverMetadata(drvrs) + drvrs := rc.registry.DriversMetadata() + return rc.writers.metaw.DriverMetadata(drvrs) } diff --git a/cli/cmd_inspect.go b/cli/cmd_inspect.go index 10bfa413..d7cc0b2b 100644 --- a/cli/cmd_inspect.go +++ b/cli/cmd_inspect.go @@ -106,7 +106,7 @@ func execInspect(rc *RunContext, cmd *cobra.Command, args []string) error { } } - dbase, err := rc.databases().Open(rc.Context, src) + dbase, err := rc.databases.Open(rc.Context, src) if err != nil { return errz.Wrapf(err, "failed to inspect %s", src.Handle) } @@ -119,7 +119,7 @@ func execInspect(rc *RunContext, cmd *cobra.Command, args []string) error { return err } - return rc.writers().metaw.TableMetadata(tblMeta) + return rc.writers.metaw.TableMetadata(tblMeta) } meta, err := dbase.SourceMetadata(rc.Context) @@ -133,5 +133,5 @@ func execInspect(rc *RunContext, cmd *cobra.Command, args []string) error { meta.DBVars = nil } - return rc.writers().metaw.SourceMetadata(meta) + return rc.writers.metaw.SourceMetadata(meta) } diff --git a/cli/cmd_list.go b/cli/cmd_list.go index 18d8ccf2..f6fbb6bf 100644 --- a/cli/cmd_list.go +++ b/cli/cmd_list.go @@ -23,5 +23,5 @@ func execSrcList(rc *RunContext, cmd *cobra.Command, args []string) error { return errz.Errorf(msgInvalidArgs) } - return rc.writers().srcw.SourceSet(rc.Config.Sources) + return rc.writers.srcw.SourceSet(rc.Config.Sources) } diff --git a/cli/cmd_notify.go b/cli/cmd_notify.go index 03dc829d..93ff2ad4 100644 --- a/cli/cmd_notify.go +++ b/cli/cmd_notify.go @@ -38,7 +38,7 @@ func newNotifyListCmd() (*cobra.Command, runFunc) { } func execNotifyList(rc *RunContext, cmd *cobra.Command, args []string) error { - return rc.writers().notifyw.NotifyDestinations(rc.Config.Notification.Destinations) + return rc.writers.notifyw.NotifyDestinations(rc.Config.Notification.Destinations) } func newNotifyRemoveCmd() (*cobra.Command, runFunc) { @@ -165,7 +165,7 @@ func execNotifyAddSlack(rc *RunContext, cmd *cobra.Command, args []string) error return err } - return rc.writers().notifyw.NotifyDestinations([]notify.Destination{*dest}) + return rc.writers.notifyw.NotifyDestinations([]notify.Destination{*dest}) } func newNotifyAddHipChatCmd() (*cobra.Command, runFunc) { diff --git a/cli/cmd_ping.go b/cli/cmd_ping.go index 3dd406e3..037a047c 100644 --- a/cli/cmd_ping.go +++ b/cli/cmd_ping.go @@ -100,7 +100,7 @@ func execPing(rc *RunContext, cmd *cobra.Command, args []string) error { rc.Log.Debugf("Using timeout value: %s", timeout) - return pingSources(rc.Context, rc.Log, rc.registry(), srcs, rc.writers().pingw, timeout) + return pingSources(rc.Context, rc.Log, rc.registry, srcs, rc.writers.pingw, timeout) } // pingSources pings each of the sources in srcs, and prints results diff --git a/cli/cmd_remove.go b/cli/cmd_remove.go index 33c83ea0..c5bd8c2e 100644 --- a/cli/cmd_remove.go +++ b/cli/cmd_remove.go @@ -41,7 +41,7 @@ func execSrcRemove(rc *RunContext, cmd *cobra.Command, args []string) error { } fmt.Fprintf(rc.Out, "Removed data source ") - _, _ = rc.wrtr.fmt.Hilite.Fprintf(rc.Out, "%s", src.Handle) + _, _ = rc.writers.fmt.Hilite.Fprintf(rc.Out, "%s", src.Handle) fmt.Fprintln(rc.Out) return nil diff --git a/cli/cmd_scratch.go b/cli/cmd_scratch.go index 8e8900a4..1b4eb808 100644 --- a/cli/cmd_scratch.go +++ b/cli/cmd_scratch.go @@ -57,7 +57,7 @@ func execScratch(rc *RunContext, cmd *cobra.Command, args []string) error { src = defaultScratch } - return rc.writers().srcw.Source(src) + return rc.writers.srcw.Source(src) } // Set the scratch src @@ -79,5 +79,5 @@ func execScratch(rc *RunContext, cmd *cobra.Command, args []string) error { return err } - return rc.writers().srcw.Source(src) + return rc.writers.srcw.Source(src) } diff --git a/cli/cmd_slq.go b/cli/cmd_slq.go index 707c0bb7..e45c2f42 100644 --- a/cli/cmd_slq.go +++ b/cli/cmd_slq.go @@ -93,7 +93,7 @@ func execSLQ(rc *RunContext, cmd *cobra.Command, args []string) error { // execSQLInsert executes the SQL and inserts resulting records // into destTbl in destSrc. func execSLQInsert(rc *RunContext, destSrc *source.Source, destTbl string) error { - args, srcs, dbases := rc.Args, rc.Config.Sources, rc.databases() + args, srcs, dbases := rc.Args, rc.Config.Sources, rc.databases slq, err := preprocessUserSLQ(rc, args) if err != nil { return err @@ -113,7 +113,7 @@ func execSLQInsert(rc *RunContext, destSrc *source.Source, destTbl string) error // stack. inserter := libsq.NewDBWriter(rc.Log, destDB, destTbl, libsq.DefaultRecordChSize) - err = libsq.ExecuteSLQ(ctx, rc.Log, rc.dbases, rc.dbases, srcs, slq, inserter) + err = libsq.ExecuteSLQ(ctx, rc.Log, rc.databases, rc.databases, srcs, slq, inserter) if err != nil { return errz.Wrapf(err, "insert %s.%s failed", destSrc.Handle, destTbl) } @@ -133,8 +133,8 @@ func execSLQPrint(rc *RunContext) error { return err } - recw := output.NewRecordWriterAdapter(rc.writers().recordw) - err = libsq.ExecuteSLQ(rc.Context, rc.Log, rc.dbases, rc.dbases, rc.Config.Sources, slq, recw) + recw := output.NewRecordWriterAdapter(rc.writers.recordw) + err = libsq.ExecuteSLQ(rc.Context, rc.Log, rc.databases, rc.databases, rc.Config.Sources, slq, recw) if err != nil { return err } @@ -172,7 +172,7 @@ func execSLQPrint(rc *RunContext) error { // // $ sq '.person' --> sq '@active.person' func preprocessUserSLQ(rc *RunContext, args []string) (string, error) { - log, reg, dbases, srcs := rc.Log, rc.registry(), rc.databases(), rc.Config.Sources + log, reg, dbases, srcs := rc.Log, rc.registry, rc.databases, rc.Config.Sources activeSrc := srcs.Active() if len(args) == 0 { diff --git a/cli/cmd_sql.go b/cli/cmd_sql.go index 150add27..36ece785 100644 --- a/cli/cmd_sql.go +++ b/cli/cmd_sql.go @@ -103,12 +103,12 @@ func execSQL(rc *RunContext, cmd *cobra.Command, args []string) error { // to the configured writer. func execSQLPrint(rc *RunContext, fromSrc *source.Source) error { args := rc.Args - dbase, err := rc.databases().Open(rc.Context, fromSrc) + dbase, err := rc.databases.Open(rc.Context, fromSrc) if err != nil { return err } - recw := output.NewRecordWriterAdapter(rc.writers().recordw) + recw := output.NewRecordWriterAdapter(rc.writers.recordw) err = libsq.QuerySQL(rc.Context, rc.Log, dbase, recw, args[0]) if err != nil { return err @@ -121,7 +121,7 @@ func execSQLPrint(rc *RunContext, fromSrc *source.Source) error { // into destTbl in destSrc. func execSQLInsert(rc *RunContext, fromSrc, destSrc *source.Source, destTbl string) error { args := rc.Args - dbases := rc.databases() + dbases := rc.databases ctx, cancelFn := context.WithCancel(rc.Context) defer cancelFn() diff --git a/cli/cmd_sql_test.go b/cli/cmd_sql_test.go index 82224bdb..dce4f8e5 100644 --- a/cli/cmd_sql_test.go +++ b/cli/cmd_sql_test.go @@ -132,7 +132,6 @@ func TestCmdSQL_StdinQuery(t *testing.T) { require.NoError(t, err) ru := newRun(t).hush() - //ru := newRun(t) ru.rc.Stdin = f err = ru.exec("sql", "--no-header", "SELECT * FROM "+tc.tbl) diff --git a/cli/cmd_src.go b/cli/cmd_src.go index 9ff80619..0bab49a1 100644 --- a/cli/cmd_src.go +++ b/cli/cmd_src.go @@ -42,7 +42,7 @@ func execSrc(rc *RunContext, cmd *cobra.Command, args []string) error { return nil } - return rc.writers().srcw.Source(src) + return rc.writers.srcw.Source(src) } src, err := cfg.Sources.SetActive(args[0]) @@ -55,5 +55,5 @@ func execSrc(rc *RunContext, cmd *cobra.Command, args []string) error { return err } - return rc.writers().srcw.Source(src) + return rc.writers.srcw.Source(src) } diff --git a/cli/cmd_tbl.go b/cli/cmd_tbl.go index cb821a5e..f55232a4 100644 --- a/cli/cmd_tbl.go +++ b/cli/cmd_tbl.go @@ -61,7 +61,7 @@ func execTblCopy(rc *RunContext, cmd *cobra.Command, args []string) error { return errz.New("one or two table args required") } - tblHandles, err := parseTableHandleArgs(rc.reg, rc.Config.Sources, args) + tblHandles, err := parseTableHandleArgs(rc.registry, rc.Config.Sources, args) if err != nil { return err } @@ -108,7 +108,7 @@ func execTblCopy(rc *RunContext, cmd *cobra.Command, args []string) error { } var dbase driver.Database - dbase, err = rc.databases().Open(rc.Context, tblHandles[0].src) + dbase, err = rc.databases.Open(rc.Context, tblHandles[0].src) if err != nil { return err } @@ -160,7 +160,7 @@ func newTblTruncateCmd() (*cobra.Command, runFunc) { func execTblTruncate(rc *RunContext, cmd *cobra.Command, args []string) (err error) { var tblHandles []tblHandle - tblHandles, err = parseTableHandleArgs(rc.reg, rc.Config.Sources, args) + tblHandles, err = parseTableHandleArgs(rc.registry, rc.Config.Sources, args) if err != nil { return err } @@ -200,7 +200,7 @@ func newTblDropCmd() (*cobra.Command, runFunc) { func execTblDrop(rc *RunContext, cmd *cobra.Command, args []string) (err error) { var tblHandles []tblHandle - tblHandles, err = parseTableHandleArgs(rc.reg, rc.Config.Sources, args) + tblHandles, err = parseTableHandleArgs(rc.registry, rc.Config.Sources, args) if err != nil { return err } @@ -212,7 +212,7 @@ func execTblDrop(rc *RunContext, cmd *cobra.Command, args []string) (err error) } var dbase driver.Database - dbase, err = rc.databases().Open(rc.Context, tblH.src) + dbase, err = rc.databases.Open(rc.Context, tblH.src) if err != nil { return err } diff --git a/cli/cmd_version.go b/cli/cmd_version.go index 5de7422d..ec9df88c 100644 --- a/cli/cmd_version.go +++ b/cli/cmd_version.go @@ -26,16 +26,16 @@ func execVersion(rc *RunContext, cmd *cobra.Command, args []string) error { version = "0.0.0-dev" } - rc.wrtr.fmt.Hilite.Fprintf(rc.Out, "sq %s", version) + rc.writers.fmt.Hilite.Fprintf(rc.Out, "sq %s", version) if len(buildinfo.Commit) > 0 { fmt.Fprint(rc.Out, " ") - rc.wrtr.fmt.Faint.Fprint(rc.Out, "#"+buildinfo.Commit) + rc.writers.fmt.Faint.Fprint(rc.Out, "#"+buildinfo.Commit) } if len(buildinfo.Timestamp) > 0 { fmt.Fprint(rc.Out, " ") - rc.wrtr.fmt.Faint.Fprint(rc.Out, buildinfo.Timestamp) + rc.writers.fmt.Faint.Fprint(rc.Out, buildinfo.Timestamp) } fmt.Fprintln(rc.Out) diff --git a/cli/config/config.go b/cli/config/config.go index 998b67d2..2d540cb7 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -84,7 +84,7 @@ func (f *Format) UnmarshalText(text []byte) error { switch Format(text) { default: return errz.Errorf("unknown output format %q", string(text)) - case FormatJSON, FormatJSONA, FormatJSONL, FormatTable, FormatGrid, FormatRaw, + case FormatJSON, FormatJSONA, FormatJSONL, FormatTable, FormatRaw, FormatHTML, FormatMarkdown, FormatXLSX, FormatXML, FormatCSV, FormatTSV: } @@ -92,13 +92,12 @@ func (f *Format) UnmarshalText(text []byte) error { return nil } -// Constants +// Output format values. const ( FormatJSON Format = "json" FormatJSONL Format = "jsonl" FormatJSONA Format = "jsona" - FormatTable Format = "table" // FIXME: rename to FormatText - FormatGrid Format = "grid" + FormatTable Format = "table" FormatRaw Format = "raw" FormatHTML Format = "html" FormatMarkdown Format = "markdown" diff --git a/cli/consts.go b/cli/consts.go index 52cdb99b..2fb44b9f 100644 --- a/cli/consts.go +++ b/cli/consts.go @@ -37,7 +37,7 @@ const ( flagJSONShort = "j" flagJSONA = "jsona" flagJSONAShort = "A" - flagJSONAUsage = "JSON: output each record's values as JSON array on its own line" + flagJSONAUsage = "JSON: output each record's values as a JSON array on its own line" flagJSONL = "jsonl" flagJSONLShort = "l" flagJSONLUsage = "JSON: output each record as a JSON object on its own line" diff --git a/cli/source.go b/cli/source.go index a95e3b43..6877cdc6 100644 --- a/cli/source.go +++ b/cli/source.go @@ -97,7 +97,6 @@ func activeSrcFromFlagsOrConfig(cmd *cobra.Command, srcs *source.Set) (*source.S // and returned. func checkStdinSource(rc *RunContext) (*source.Source, error) { cmd := rc.Cmd - reg := rc.registry() f := rc.Stdin info, err := f.Stat() @@ -130,7 +129,7 @@ func checkStdinSource(rc *RunContext) (*source.Source, error) { if cmd.Flags().Changed(flagDriver) { val, _ := cmd.Flags().GetString(flagDriver) typ = source.Type(val) - if !reg.HasProviderFor(typ) { + if !rc.registry.HasProviderFor(typ) { return nil, errz.Errorf("unknown driver type: %s", typ) } } @@ -150,7 +149,7 @@ func checkStdinSource(rc *RunContext) (*source.Source, error) { } } - return newSource(rc.Log, reg, typ, source.StdinHandle, source.StdinHandle, opts) + return newSource(rc.Log, rc.registry, typ, source.StdinHandle, source.StdinHandle, opts) } // newSource creates a new Source instance where the diff --git a/main.go b/main.go index f5c21972..985549ff 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ func main() { err := cli.Execute(ctx, os.Stdin, os.Stdout, os.Stderr, os.Args) if err != nil { + cancelFn() os.Exit(1) } }