mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-19 22:21:56 +03:00
db55986980
- Support for ingest cache, download cache, and progress bars.
237 lines
4.9 KiB
Go
237 lines
4.9 KiB
Go
package tablew
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/samber/lo"
|
|
|
|
"github.com/neilotoole/sq/cli/output"
|
|
"github.com/neilotoole/sq/libsq/core/errz"
|
|
"github.com/neilotoole/sq/libsq/core/options"
|
|
"github.com/neilotoole/sq/libsq/core/stringz"
|
|
)
|
|
|
|
var _ output.ConfigWriter = (*configWriter)(nil)
|
|
|
|
// configWriter implements output.ConfigWriter.
|
|
type configWriter struct {
|
|
tbl *table
|
|
}
|
|
|
|
// NewConfigWriter returns a new output.ConfigWriter.
|
|
func NewConfigWriter(out io.Writer, pr *output.Printing) output.ConfigWriter {
|
|
tbl := &table{out: out, pr: pr, header: pr.ShowHeader}
|
|
tbl.reset()
|
|
return &configWriter{tbl: tbl}
|
|
}
|
|
|
|
// Location implements output.ConfigWriter.
|
|
func (w *configWriter) Location(path, origin string) error {
|
|
fmt.Fprintln(w.tbl.out, path)
|
|
if w.tbl.pr.Verbose && origin != "" {
|
|
w.tbl.pr.Faint.Fprint(w.tbl.out, "Origin: ")
|
|
w.tbl.pr.String.Fprintln(w.tbl.out, origin)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CacheLocation implements output.ConfigWriter.
|
|
func (w *configWriter) CacheLocation(loc string) error {
|
|
_, err := fmt.Fprintln(w.tbl.out, loc)
|
|
return errz.Err(err)
|
|
}
|
|
|
|
// CacheStat implements output.ConfigWriter.
|
|
func (w *configWriter) CacheStat(loc string, enabled bool, size int64) error {
|
|
const sp = " "
|
|
s := loc + sp
|
|
if enabled {
|
|
s += w.tbl.pr.Enabled.Sprint("enabled") + sp
|
|
} else {
|
|
s += w.tbl.pr.Disabled.Sprint("disabled") + sp
|
|
}
|
|
if size == -1 {
|
|
s += w.tbl.pr.Warning.Sprint("(size unavailable)")
|
|
} else {
|
|
s += w.tbl.pr.Faint.Sprintf("(%s)", stringz.ByteSized(size, 1, ""))
|
|
}
|
|
_, err := fmt.Fprintln(w.tbl.out, s)
|
|
return err
|
|
}
|
|
|
|
// Opt implements output.ConfigWriter.
|
|
func (w *configWriter) Opt(o options.Options, opt options.Opt) error {
|
|
if o == nil || opt == nil {
|
|
return nil
|
|
}
|
|
|
|
if !w.tbl.pr.Verbose {
|
|
if !o.IsSet(opt) {
|
|
return nil
|
|
}
|
|
clr := getOptColor(w.tbl.pr, opt)
|
|
clr.Fprintln(w.tbl.out, opt.GetAny(o))
|
|
return nil
|
|
}
|
|
|
|
o2 := options.Options{opt.Key(): o[opt.Key()]}
|
|
reg2 := &options.Registry{}
|
|
reg2.Add(opt)
|
|
return w.Options(reg2, o2)
|
|
}
|
|
|
|
// Options implements output.ConfigWriter.
|
|
func (w *configWriter) Options(reg *options.Registry, o options.Options) error {
|
|
if o == nil {
|
|
return nil
|
|
}
|
|
|
|
if w.tbl.pr.Verbose {
|
|
w.tbl.pr.ShowHeader = true
|
|
} else {
|
|
w.tbl.pr.ShowHeader = false
|
|
}
|
|
|
|
return w.doPrintOptions(reg, o, true)
|
|
}
|
|
|
|
// Options implements output.ConfigWriter.
|
|
// If printUnset is true and we're in verbose mode, unset options
|
|
// are also printed.
|
|
func (w *configWriter) doPrintOptions(reg *options.Registry, o options.Options, printUnset bool) error {
|
|
if o == nil {
|
|
return nil
|
|
}
|
|
|
|
t, pr, verbose := w.tbl.tblImpl, w.tbl.pr, w.tbl.pr.Verbose
|
|
|
|
if pr.ShowHeader {
|
|
headers := []string{"KEY", "VALUE"}
|
|
if verbose {
|
|
headers = []string{"KEY", "VALUE", "DEFAULT"}
|
|
}
|
|
|
|
t.SetHeader(headers)
|
|
}
|
|
t.SetColTrans(0, pr.Key.SprintFunc())
|
|
|
|
var rows [][]string
|
|
|
|
keys := o.Keys()
|
|
for _, k := range keys {
|
|
opt := reg.Get(k)
|
|
if opt == nil {
|
|
// Shouldn't happen, but print anyway just in case
|
|
row := []string{
|
|
k,
|
|
pr.Error.Sprintf("%v", o[k]),
|
|
}
|
|
if verbose {
|
|
// Can't know default in this situation.
|
|
row = append(row, "")
|
|
}
|
|
|
|
rows = append(rows, row)
|
|
continue
|
|
}
|
|
|
|
clr := getOptColor(pr, opt)
|
|
|
|
val, ok := o[k]
|
|
if !ok || val == nil {
|
|
if verbose {
|
|
val = ""
|
|
} else {
|
|
val = "NULL"
|
|
}
|
|
clr = pr.Null
|
|
}
|
|
|
|
row := []string{
|
|
k,
|
|
clr.Sprintf("%v", val),
|
|
}
|
|
|
|
if verbose {
|
|
defaultVal := pr.Faint.Sprintf("%v", opt.GetAny(nil))
|
|
row = append(row, defaultVal)
|
|
}
|
|
|
|
rows = append(rows, row)
|
|
}
|
|
|
|
if !printUnset || !verbose {
|
|
return w.tbl.appendRowsAndRenderAll(context.TODO(), rows)
|
|
}
|
|
|
|
// Also print the unset opts
|
|
allKeys := reg.Keys()
|
|
setKeys := o.Keys()
|
|
unsetKeys, _ := lo.Difference(allKeys, setKeys)
|
|
|
|
for _, k := range unsetKeys {
|
|
opt := reg.Get(k)
|
|
row := []string{
|
|
pr.Faint.Sprintf("%v", k),
|
|
"", // opt is unset, so it doesn't have a value
|
|
pr.Faint.Sprintf("%v", opt.GetAny(nil)),
|
|
}
|
|
|
|
rows = append(rows, row)
|
|
}
|
|
|
|
return w.tbl.appendRowsAndRenderAll(context.TODO(), rows)
|
|
}
|
|
|
|
// SetOption implements output.ConfigWriter.
|
|
func (w *configWriter) SetOption(o options.Options, opt options.Opt) error {
|
|
if !w.tbl.pr.Verbose {
|
|
// No output unless verbose
|
|
return nil
|
|
}
|
|
|
|
reg2 := &options.Registry{}
|
|
reg2.Add(opt)
|
|
o = options.Options{opt.Key(): opt.GetAny(o)}
|
|
|
|
// It's verbose
|
|
o = options.Effective(o, opt)
|
|
w.tbl.pr.ShowHeader = true
|
|
return w.doPrintOptions(reg2, o, false)
|
|
}
|
|
|
|
// UnsetOption implements output.ConfigWriter.
|
|
func (w *configWriter) UnsetOption(opt options.Opt) error {
|
|
if !w.tbl.pr.Verbose {
|
|
// No output unless verbose
|
|
return nil
|
|
}
|
|
|
|
reg := &options.Registry{}
|
|
reg.Add(opt)
|
|
o := options.Options{}
|
|
|
|
return w.doPrintOptions(reg, o, true)
|
|
}
|
|
|
|
func getOptColor(pr *output.Printing, opt options.Opt) *color.Color {
|
|
if opt == nil {
|
|
return pr.Null
|
|
}
|
|
|
|
clr := pr.String
|
|
switch opt.(type) {
|
|
case options.Bool:
|
|
clr = pr.Bool
|
|
case options.Int:
|
|
clr = pr.Number
|
|
default:
|
|
}
|
|
|
|
return clr
|
|
}
|