cli

package
v0.0.41 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2022 License: BSD-3-Clause Imports: 11 Imported by: 0

README

cli

This package implements the command-line interface for Thelma. It provides some additional functionality on top of Cobra.

Why?

Cobra's awesome, but it has a few missing features.

Dependency Injection

For tools with many subcommands, it's likely that most commands will share some central dependencies (eg. configuration, logging, API clients). Cobra provides no mechanism for injecting dependencies into subcommands; users must roll their own DI in a way that is adaptable to testing.

Accessing Options Structs in Tests

Most Cobra commands use BindFlags to associate CLI flags with a custom options struct. It's useful to be able to access and verify these structs in tests, especially for commands that have complex options, but Cobra provides no mechanism for this.

Guaranteed Hook Execution

Cobra's PreRun and PostRun hook implementation are missing some key features:

  • Hooks are not inherited by child commands. (PersistentPreRun and PersistentPostRun are inherited, but not transitively). In an ideal world, we would be able to configure pre- and post- hooks on the root command, an arbitrary set of intermediate commands, and finally the leaf/child command, and have all hooks be executed in order.

  • PostRun hooks won't be executed if the main Run() hook fails. This is limiting, because often it is useful to do some initialization in a PreRun hook and cleanup in a corresponding PostRun hook.

Documentation

Overview

Package cli contains code for Thelma's command-line interface

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HookError added in v0.0.23

type HookError struct {
	CommandName string // CommandName key of the Thelma command the hook belongs to
	Err         error  // Err underlying error returned by the hook
	// contains filtered or unexported fields
}

HookError is an error returned from the execution of a single ThelmaCommand hook

func (*HookError) Cause added in v0.0.23

func (e *HookError) Cause() error

Cause implement the pkg/errors causer interface for stacktraces

func (*HookError) Error added in v0.0.23

func (e *HookError) Error() string

type Option added in v0.0.23

type Option func(*Options)

Option configuration option for a ThelmaCLI

type Options added in v0.0.23

type Options struct {
	// contains filtered or unexported fields
}

Options configuration options for a ThelmaCLI

func DefaultOptions added in v0.0.23

func DefaultOptions() *Options

DefaultOptions default options

func (*Options) AddCommand added in v0.0.23

func (opts *Options) AddCommand(name string, cmd ThelmaCommand)

AddCommand add a subcommand to the ThelmaCLI

func (*Options) ConfigureThelma added in v0.0.23

func (opts *Options) ConfigureThelma(hook func(builder.ThelmaBuilder))

ConfigureThelma add a configration hook for Thelma

func (*Options) SetArgs added in v0.0.23

func (opts *Options) SetArgs(args []string)

SetArgs set CLI args to the given list instead of os.Args

func (*Options) SetOut added in v0.0.23

func (opts *Options) SetOut(writer io.Writer)

SetOut write output to the given writer instead of os.Stdout

func (*Options) SkipRun added in v0.0.23

func (opts *Options) SkipRun(skipRun bool)

SkipRun if true, skip run phase and only execute pre/post run hooks

type RunContext added in v0.0.23

type RunContext interface {
	// Args returns user-supplied positional arguments for the leaf command.
	Args() []string

	// CobraCommand returns the Cobra command associated with the Thelma command that is currently executing.
	CobraCommand() *cobra.Command

	// Parent returns the parent of the Thelma command that is currently executing.
	Parent() ThelmaCommand

	// SetOutput sets the output for this command (will be converted to YAML, JSON, dump, or raw based on user-supplied arguments, and printed to stdout)
	SetOutput(data interface{})

	// HasOutput returns true if output has been set for this command
	HasOutput() bool

	// Output returns output for this command, or nil if none has been set
	Output() interface{}

	// CommandName returns the name components for this command. Eg. ["render"] for `thelma render`, ["bee", "list"] for `thelma bee list`
	CommandName() []string
}

RunContext provides information about the current Thelma execution to PreRun, Run, and PostRun hooks

type RunError added in v0.0.23

type RunError struct {
	CommandName   string       // CommandName key of the Thelma command that was executed
	PreRunError   *HookError   // PreRunError error returned by PreRun hook
	RunError      *HookError   // RunError error returned by Run hook
	PostRunErrors []*HookError // PostRunErrors all errors returned by PostRun hooks
	Count         int          // Count number of errors wrapped by this error
}

RunError aggregates errors that can occur during execution of a ThelmaCommand

func (*RunError) Cause added in v0.0.23

func (e *RunError) Cause() error

Cause implement the pkg/errors causer interface.

func (*RunError) Error added in v0.0.23

func (e *RunError) Error() string

Error returns a summary of all errors that occurred during command execution

type ThelmaCLI

type ThelmaCLI interface {
	// Execute is the main entry point for Thelma execution. It can only be called once for a given ThelmaCLI.
	Execute() error
}

func New added in v0.0.23

func New(options ...Option) ThelmaCLI

func NewWithOptions added in v0.0.23

func NewWithOptions(options *Options) ThelmaCLI

type ThelmaCommand added in v0.0.23

type ThelmaCommand interface {
	// ConfigureCobra is a hook for adding flags, description, and other configuration to the Cobra command associated with this Thelma subcommand
	ConfigureCobra(cobraCommand *cobra.Command)

	// PreRun is a hook for running some code before Run is called. Conventionally, flag and argumnent validation are
	// performed here. Note that:
	// * PreRun hooks are inherited by child commands, and run in order of inheritance. Eg.
	//   for the command "thelma charts import", the root command's PreRun will be run first,
	//   then the `chart` command's PreRun, and finally the `import` command's PreRun.
	//   If an error occurs in a prent PreRun hook, it will be returned; child/descendant PreRun hooks will not be executed.
	// * If any PreRun hook returns an error, the command's Run hook will not be executed, but its PostRun hooks will be.
	PreRun(app app.ThelmaApp, ctx RunContext) error

	// Run is where the main body of a subcommand should be implemented. Note that:
	// * For commands with subcommands (eg. the "charts" command in "thelma charts import"), the Run hook is ignored.
	// * If PreRun returns an error, Run is not called but PostRun is.
	Run(app app.ThelmaApp, ctx RunContext) error

	// PostRun is a hook for running some code after Run is called. Conventionally, cleanup goes here.
	// Note that:
	// * PostRun hooks are inherited by child commands, and run in reverse order of inheritance. Eg.
	//	 for the command "thelma charts import", the `import` command's PostRun will be run first,
	//	 then the `chart` command's PostRun, and finally the root command's PostRun.
	// * Unlike PreRun hooks, PostRun hooks are guaranteed to run, even if an earlier PostRun, PreRun, or Run hook fails.
	// * PostRun hooks should be written carefully to avoid errors in the event of an earlier failure (check pointers for nil, etc).
	PostRun(app app.ThelmaApp, ctx RunContext) error
}

ThelmaCommand must be implemented by all Thelma subcommands.

Jump to

Keyboard shortcuts

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