cli

package
v0.47.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2024 License: MIT Imports: 85 Imported by: 0

Documentation

Overview

Package cli implements sq's CLI. The spf13/cobra library provides the core command processing.

Although cobra provides excellent functionality, it has some issues. Most prominently, its documentation suggests reliance upon package-level constructs for initializing the command tree (bad for testing).

Thus, this cmd package deviates from cobra's suggested usage pattern by eliminating all pkg-level constructs (which makes testing easier).

All interaction with cobra should happen inside this package, or via the utility cli/cobraz package. That is to say, the spf13/cobra package should not be imported anywhere outside this package and cli/cobraz.

The entry point to this pkg is the Execute function.

Index

Constants

This section is empty.

Variables

View Source
var (
	OptLogEnabled = options.NewBool(
		"log",
		"",
		false,
		0,
		false,
		"Enable logging",
		"Enable logging.",
	)

	OptLogFile = options.NewString(
		"log.file",
		"",
		0,
		getDefaultLogFilePath(),
		nil,
		"Log file path",
		`Path to log file. Empty value disables logging.`,
	)

	OptLogLevel = NewLogLevelOpt(
		"log.level",
		slog.LevelDebug,
		`Log level, one of: DEBUG, INFO, WARN, ERROR`,
		"Log level, one of: DEBUG, INFO, WARN, ERROR.",
	)

	OptLogFormat = format.NewOpt(
		"log.format",
		"",
		0,
		format.Text,
		func(f format.Format) error {
			if f == format.Text || f == format.JSON {
				return nil
			}

			return errz.Errorf("option {log.format} allows only %q or %q", format.Text, format.JSON)
		},
		"Log output format",
		fmt.Sprintf(
			`Log output format. Allowed formats are %q (human-friendly) or %q.`, format.Text, format.JSON),
	)
)
View Source
var (
	OptPrintHeader = options.NewBool(
		"header",
		"",
		false,
		0,
		true,
		"Print header row",
		`Controls whether a header row is printed. This applies only to certain formats,
such as "text" or "csv".`,
		options.TagOutput,
	)

	OptFormat = format.NewOpt(
		"format",
		"format",
		'f',
		format.Text,
		nil,
		"Specify output format",
		`Specify the output format. Some formats are only implemented for a subset of
sq's commands. If the specified format is not available for a particular
command, sq falls back to "text". Available formats:

  text, csv, tsv, xlsx,
  json, jsona, jsonl,
  markdown, html, xlsx, xml, yaml, raw`,
	)

	OptErrorFormat = format.NewOpt(
		"error.format",
		"",
		0,
		format.Text,
		func(f format.Format) error {
			if f == format.Text || f == format.JSON {
				return nil
			}

			return errz.Errorf("option {error.format} allows only %q or %q", format.Text, format.JSON)
		},
		"Error output format",
		fmt.Sprintf(`The format to output errors in. Allowed formats are %q or %q.`, format.Text, format.JSON),
	)

	OptVerbose = options.NewBool(
		"verbose",
		"",
		false,
		'v',
		false,
		"Print verbose output",
		`Print verbose output.`,
		options.TagOutput,
	)

	OptMonochrome = options.NewBool(
		"monochrome",
		"",
		false,
		'M',
		false,
		"Don't print color output",
		`Don't print color output.`,
		options.TagOutput,
	)

	OptProgress = options.NewBool(
		"progress",
		"no-progress",
		true,
		0,
		true,
		"Progress bar for long-running operations",
		`Progress bar for long-running operations.`,
		options.TagOutput,
	)

	OptProgressDelay = options.NewDuration(
		"progress.delay",
		"",
		0,
		time.Second*2,
		"Progress bar render delay",
		`Delay before showing a progress bar.`,
	)

	OptDebugTrackMemory = options.NewDuration(
		"debug.stats.frequency",
		"",
		0,
		0,
		"Memory usage sampling interval.",
		`Memory usage sampling interval. If non-zero, peak memory usage is periodically
sampled, and reported on exit. If zero, memory usage sampling is disabled.`,
	)

	OptCompact = options.NewBool(
		"compact",
		"",
		false,
		'c',
		false,
		"Compact instead of pretty-printed output",
		`Compact instead of pretty-printed output.`,
		options.TagOutput,
	)

	OptTuningFlushThreshold = options.NewInt(
		"tuning.flush-threshold",
		"",
		0,
		1000,
		"Output writer buffer flush threshold in bytes",
		`Size in bytes after which output writers should flush any internal buffer.
Generally, it is not necessary to fiddle this knob.`,
		options.TagTuning,
	)

	OptDatetimeFormat = options.NewString(
		"format.datetime",
		"",
		0,
		"RFC3339",
		nil,
		"Timestamp format: constant such as RFC3339 or a strftime format",
		`Timestamp format. This can be one of several predefined constants such as
"RFC3339" or "Unix", or a strftime format such as "%Y-%m-%d %H:%M:%S".

`+timeLayoutsList,
		options.TagOutput,
	)

	OptDatetimeFormatAsNumber = options.NewBool(
		"format.datetime.number",
		"",
		false,
		0,
		true,
		"Render numeric datetime value as number instead of string",
		`Render numeric datetime value as number instead of string, if possible. If
format.datetime renders a numeric value (e.g. a Unix timestamp such as
"1591843854"), that value is typically rendered as a string. For some output
formats, such as JSON, it can be useful to instead render the value as a naked
number instead of a string. Note that this option is no-op if the rendered value
is not an integer.

  format.datetime.number=false
  [{"first_name":"PENELOPE","last_update":"1591843854"}]
  format.datetime.number=true
  [{"first_name":"PENELOPE","last_update":1591843854}]
`,
		options.TagOutput,
	)

	OptDateFormat = options.NewString(
		"format.date",
		"",
		0,
		"DateOnly",
		nil,
		"Date format: constant such as DateOnly or a strftime format",
		`Date format. This can be one of several predefined constants such as "DateOnly"
or "Unix", or a strftime format such as "%Y-%m-%d". Note that date values are
sometimes programmatically indistinguishable from datetime values. In that
situation, use format.datetime instead.

`+timeLayoutsList,
		options.TagOutput,
	)

	OptDateFormatAsNumber = options.NewBool(
		"format.date.number",
		"",
		false,
		0,
		true,
		"Render numeric date value as number instead of string",
		`Render numeric date value as number instead of string, if possible. If
format.date renders a numeric value (e.g. a year such as "1979"), that value is
typically rendered as a string. For some output formats, such as JSON, it can be
useful to instead render the value as a naked number instead of a string. Note
that this option is no-op if the rendered value is not an integer.

  format.date.number=false
  [{"first_name":"PENELOPE","birth_year":"1979"}]
  format.date.number=true
  [{"first_name":"PENELOPE","birth_year":1979}]
`,
		options.TagOutput,
	)

	OptTimeFormat = options.NewString(
		"format.time",
		"",
		0,
		"TimeOnly",
		nil,
		"Time format: constant such as TimeOnly or a strftime format",
		`Time format. This can be one of several predefined constants such as "TimeOnly"
or "Unix", or a strftime format such as "%Y-%m-%d". Note that time values are
sometimes programmatically indistinguishable from datetime values. In that
situation, use format.datetime instead.

`+timeLayoutsList,
		options.TagOutput,
	)

	OptTimeFormatAsNumber = options.NewBool(
		"format.time.number",
		"",
		false,
		0,
		true,
		"Render numeric time value as number instead of string",
		`
Render numeric time value as number instead of string, if possible. If format.time
renders a numeric value (e.g. "59"), that value is typically rendered as a string.
For some output formats, such as JSON, it can be useful to instead render the
value as a naked number instead of a string. Note that this option is no-op if
the rendered value is not an integer.

  format.time.number=false
  [{"first_name":"PENELOPE","favorite_minute":"59"}]
  format.time.number=true
  [{"first_name":"PENELOPE","favorite_minute":59}]
`,
		options.TagOutput,
	)
)
View Source
var OptDiffDataFormat = format.NewOpt(
	"diff.data.format",
	"format",
	'f',
	format.Text,
	func(f format.Format) error {
		switch f {
		case format.Text, format.CSV, format.TSV,
			format.JSON, format.JSONA, format.JSONL,
			format.Markdown, format.HTML, format.XML, format.YAML:
			return nil
		default:
			return errz.Errorf("diff does not support output format {%s}", f)
		}
	},
	"Output format (json, csv…) when comparing data",
	`Specify the output format to use when comparing table data.

Available formats:

  text, csv, tsv,
  json, jsona, jsonl,
  markdown, html, xml, yaml`,
)
View Source
var OptDiffNumLines = options.NewInt(
	"diff.lines",
	"unified",
	'U',
	3,
	"Generate diffs with <n> lines of context",
	`Generate diffs with <n> lines of context, where n >= 0.`,
	options.TagOutput,
)
View Source
var OptPingCmdTimeout = options.NewDuration(
	"ping.timeout",
	"",
	0,
	time.Second*10,
	"ping command timeout duration",
	"How long the ping command waits before timeout occurs. Example: 500ms or 2m10s.",
)

OptPingCmdTimeout controls timeout for the ping command. This timeout applies only to the "sq ping" command: this is a different value from driver.OptConnOpenTimeout, which applies to generic ping operations.

View Source
var OptShellCompletionLog = options.NewBool(
	"shell-completion.log",
	"",
	false,
	0,
	false,
	"Enable logging of shell completion activity",
	`Enable logging of shell completion activity. This is really only useful for
debugging shell completion functionality. It's disabled by default, because it's
frequently the case that shell completion handlers will trigger work (such as
inspecting the schema) that doesn't complete by the shell completion timeout.
This can result in the logs being filled with uninteresting junk when the
timeout triggers logging of errors.`,
)
View Source
var OptShellCompletionTimeout = options.NewDuration(
	"shell-completion.timeout",
	"",
	0,
	time.Millisecond*500,
	"Shell completion timeout",
	`How long shell completion should wait before giving up. This can become relevant
when shell completion inspects a source's metadata, e.g. to offer a list of
tables in a source.`,
)

Functions

func Execute

func Execute(ctx context.Context, stdin *os.File, stdout, stderr io.Writer, args []string) error

Execute builds a Run using ctx and default settings, and invokes ExecuteWith.

func ExecuteWith

func ExecuteWith(ctx context.Context, ru *run.Run, args []string) error

ExecuteWith invokes the cobra CLI framework, ultimately resulting in a command being executed. This function always closes ru.

func FinishRunInit added in v0.37.0

func FinishRunInit(ctx context.Context, ru *run.Run) error

FinishRunInit finishes setting up ru.

TODO: This run.Run initialization mechanism is a bit of a mess. There's logic in newRun, preRun, FinishRunInit, as well as testh.Helper.init. Surely the init logic can be consolidated.

func PrintError added in v0.47.0

func PrintError(ctx context.Context, ru *run.Run, err error)

PrintError is the centralized function for printing and logging errors. This func has a lot of (possibly needless) redundancy; ultimately err will print if non-nil (even if ctx, or ru, or any of ru's fields are nil).

func RegisterDefaultOpts added in v0.34.0

func RegisterDefaultOpts(reg *options.Registry)

RegisterDefaultOpts registers the options.Opt instances that the CLI knows about.

Types

type LogLevelOpt added in v0.34.0

type LogLevelOpt struct {
	options.BaseOpt
	// contains filtered or unexported fields
}

LogLevelOpt is an options.Opt for slog.Level.

func NewLogLevelOpt added in v0.34.0

func NewLogLevelOpt(key string, defaultVal slog.Level, usage, help string) LogLevelOpt

NewLogLevelOpt returns a new LogLevelOpt instance.

func (LogLevelOpt) DefaultAny added in v0.34.0

func (op LogLevelOpt) DefaultAny() any

DefaultAny implements options.Opt.

func (LogLevelOpt) Get added in v0.34.0

func (op LogLevelOpt) Get(o options.Options) slog.Level

Get returns op's value in o. If o is nil, or no value is set, op's default value is returned.

func (LogLevelOpt) GetAny added in v0.34.0

func (op LogLevelOpt) GetAny(o options.Options) any

GetAny implements options.Opt.

func (LogLevelOpt) Process added in v0.34.0

func (op LogLevelOpt) Process(o options.Options) (options.Options, error)

Process implements options.Processor. It converts matching string values in o into slog.Level. If no match found, the input arg is returned unchanged. Otherwise, a clone is returned.

Directories

Path Synopsis
Package buildinfo hosts build info variables populated via ldflags.
Package buildinfo hosts build info variables populated via ldflags.
Package cobraz contains supplemental logic for dealing with spf13/cobra.
Package cobraz contains supplemental logic for dealing with spf13/cobra.
Package config holds CLI configuration.
Package config holds CLI configuration.
yamlstore
Package yamlstore contains an implementation of config.Store that uses YAML files for persistence.
Package yamlstore contains an implementation of config.Store that uses YAML files for persistence.
yamlstore/upgrades/v0.34.0
Package v0_34_0 upgrades YAML config to v0.34.0.
Package v0_34_0 upgrades YAML config to v0.34.0.
Package diff contains the CLI's diff implementation.
Package diff contains the CLI's diff implementation.
internal/go-udiff
Package udiff computes differences between text files or strings.
Package udiff computes differences between text files or strings.
internal/go-udiff/difftest
Package difftest supplies a set of tests that will operate on any implementation of a diff algorithm as exposed by diff "github.com/neilotoole/sq/cli/diff/internal/go-udiff"
Package difftest supplies a set of tests that will operate on any implementation of a diff algorithm as exposed by diff "github.com/neilotoole/sq/cli/diff/internal/go-udiff"
internal/go-udiff/lcs
package lcs contains code to find longest-common-subsequences (and diffs)
package lcs contains code to find longest-common-subsequences (and diffs)
internal/go-udiff/myers
Package myers implements the Myers diff algorithm.
Package myers implements the Myers diff algorithm.
Package flag holds CLI flags.
Package flag holds CLI flags.
Package hostinfo provides high-level details about the runtime OS.
Package hostinfo provides high-level details about the runtime OS.
Package output provides interfaces and implementations for outputting data and messages.
Package output provides interfaces and implementations for outputting data and messages.
csvw
Package csvw implements writers for CSV.
Package csvw implements writers for CSV.
htmlw
Package htmlw implements a RecordWriter for HTML.
Package htmlw implements a RecordWriter for HTML.
jsonw
Package jsonw implements output writers for JSON.
Package jsonw implements output writers for JSON.
markdownw
Package markdownw implements writers for Markdown.
Package markdownw implements writers for Markdown.
outputx
Package outputx contains extensions to pkg output, and helpers for implementing output writers.
Package outputx contains extensions to pkg output, and helpers for implementing output writers.
tablew
Package tablew implements text table output writers.
Package tablew implements text table output writers.
tablew/internal
Package tablewriter creates & generates text based table
Package tablewriter creates & generates text based table
xlsxw
Package xlsxw implements output writers for Microsoft Excel.
Package xlsxw implements output writers for Microsoft Excel.
xmlw
Package xmlw implements output writers for XML.
Package xmlw implements output writers for XML.
yamlw
Package yamlw implements output writers for YAML.
Package yamlw implements output writers for YAML.
Package run holds the run.Run construct, which encapsulates CLI state for a command execution.
Package run holds the run.Run construct, which encapsulates CLI state for a command execution.
Package testrun contains helper functionality for executing CLI tests.
Package testrun contains helper functionality for executing CLI tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL