2020-08-06 20:58:47 +03:00
|
|
|
// Package config holds CLI configuration.
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/drivers/userdriver"
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/errz"
|
|
|
|
"github.com/neilotoole/sq/libsq/core/stringz"
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/source"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Config holds application config/session data.
|
|
|
|
type Config struct {
|
2020-08-09 16:46:46 +03:00
|
|
|
// Version is the config version. This will allow sq to
|
|
|
|
// upgrade config files if needed.
|
|
|
|
Version string `yaml:"version" json:"version"`
|
|
|
|
|
|
|
|
// Defaults contains default settings, such as output format.
|
|
|
|
Defaults Defaults `yaml:"defaults" json:"defaults"`
|
|
|
|
|
|
|
|
// Sources is the set of data sources.
|
|
|
|
Sources *source.Set `yaml:"sources" json:"sources"`
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
// Ext holds sq config extensions, such as user driver config.
|
|
|
|
Ext Ext `yaml:"-" json:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) String() string {
|
|
|
|
return stringz.SprintJSON(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ext holds additional config (extensions) loaded from other
|
|
|
|
// config files, e.g. ~/.config/sq/ext/*.sq.yml
|
|
|
|
type Ext struct {
|
|
|
|
UserDrivers []*userdriver.DriverDef `yaml:"user_drivers" json:"user_drivers"`
|
|
|
|
}
|
|
|
|
|
2021-02-22 10:37:00 +03:00
|
|
|
// Defaults contains default config values.
|
2020-08-09 16:46:46 +03:00
|
|
|
type Defaults struct {
|
2021-02-22 10:37:00 +03:00
|
|
|
// Format is the default output format: json, table, etc.
|
|
|
|
Format Format `yaml:"output_format" json:"output_format"`
|
|
|
|
|
|
|
|
// Header determines if a header should be printed (if relevant
|
|
|
|
// for the output format).
|
|
|
|
Header bool `yaml:"output_header" json:"output_header"`
|
|
|
|
|
|
|
|
// PingTimeout is the allowed time for a ping.
|
|
|
|
PingTimeout time.Duration `yaml:"ping_timeout" json:"ping_timeout"`
|
|
|
|
|
|
|
|
// ShellCompletionTimeout is the time allowed for the shell
|
|
|
|
// completion callback to execute.
|
|
|
|
ShellCompletionTimeout time.Duration `yaml:"shell_completion_timeout" json:"shell_completion_timeout"`
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// New returns a config instance with default options set.
|
|
|
|
func New() *Config {
|
|
|
|
cfg := &Config{}
|
|
|
|
|
|
|
|
// By default, we want header to be true; this is
|
2020-08-09 16:46:46 +03:00
|
|
|
// ugly wrt initCfg, as the zero value of a bool
|
2020-08-06 20:58:47 +03:00
|
|
|
// is false, but we actually want it to be true for Header.
|
2020-08-09 16:46:46 +03:00
|
|
|
cfg.Defaults.Header = true
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2020-08-09 16:46:46 +03:00
|
|
|
initCfg(cfg)
|
2020-08-06 20:58:47 +03:00
|
|
|
return cfg
|
|
|
|
}
|
|
|
|
|
2020-08-09 16:46:46 +03:00
|
|
|
// initCfg checks if required values are present, and if not, sets them.
|
|
|
|
func initCfg(cfg *Config) {
|
2020-08-06 20:58:47 +03:00
|
|
|
if cfg.Sources == nil {
|
|
|
|
cfg.Sources = &source.Set{}
|
|
|
|
}
|
|
|
|
|
2020-08-09 16:46:46 +03:00
|
|
|
if cfg.Defaults.Format == "" {
|
|
|
|
cfg.Defaults.Format = FormatTable
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2021-02-22 10:37:00 +03:00
|
|
|
if cfg.Defaults.PingTimeout == 0 {
|
2020-08-09 16:46:46 +03:00
|
|
|
// Probably should be setting this in the New function,
|
|
|
|
// but we haven't yet defined cli's behavior wrt
|
|
|
|
// a zero timeout. Does it mean no timeout?
|
2021-02-22 10:37:00 +03:00
|
|
|
cfg.Defaults.PingTimeout = 10 * time.Second
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.Defaults.ShellCompletionTimeout == 0 {
|
|
|
|
cfg.Defaults.ShellCompletionTimeout = time.Millisecond * 500
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Format is a sq output format such as json or xml.
|
|
|
|
type Format string
|
|
|
|
|
|
|
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
|
|
|
func (f *Format) UnmarshalText(text []byte) error {
|
|
|
|
switch Format(text) {
|
|
|
|
default:
|
|
|
|
return errz.Errorf("unknown output format %q", string(text))
|
2020-08-08 06:06:56 +03:00
|
|
|
case FormatJSON, FormatJSONA, FormatJSONL, FormatTable, FormatRaw,
|
2020-08-06 20:58:47 +03:00
|
|
|
FormatHTML, FormatMarkdown, FormatXLSX, FormatXML, FormatCSV, FormatTSV:
|
|
|
|
}
|
|
|
|
|
|
|
|
*f = Format(text)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-08 06:06:56 +03:00
|
|
|
// Output format values.
|
2020-08-06 20:58:47 +03:00
|
|
|
const (
|
|
|
|
FormatJSON Format = "json"
|
|
|
|
FormatJSONL Format = "jsonl"
|
|
|
|
FormatJSONA Format = "jsona"
|
2020-08-08 06:06:56 +03:00
|
|
|
FormatTable Format = "table"
|
2020-08-06 20:58:47 +03:00
|
|
|
FormatRaw Format = "raw"
|
|
|
|
FormatHTML Format = "html"
|
|
|
|
FormatMarkdown Format = "markdown"
|
|
|
|
FormatXLSX Format = "xlsx"
|
|
|
|
FormatXML Format = "xml"
|
|
|
|
FormatCSV Format = "csv"
|
|
|
|
FormatTSV Format = "tsv"
|
|
|
|
)
|