cli

package
v0.0.0-...-f61b284 Latest Latest
Warning

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

Go to latest
Published: Jan 15, 2024 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CommandArg ArgName = "command"
	HelpArg    ArgName = "help"
	Indent     string  = "  "
)

Variables

View Source
var (
	ErrOptionAfterArgs    = serr.New("option found after args").ValidArgs("options", "args")
	ErrNoCommandSpecified = serr.New("no command specified")
	ErrCommandNotValid    = serr.New("command is not valid").ValidArgs("command")
	ErrNoExecFuncFound    = serr.New("no exec func found")

	ErrTooFewArgsPassed  = serr.New("too few arguments passed").ValidArgs("expected", "got")
	ErrTooManyArgsPassed = serr.New("too many arguments passed").ValidArgs("expected", "got")

	ErrAlreadyExists   = serr.New("already exists").ValidArgs("arg_name", "value")
	ErrDoesNotExist    = serr.New("does not exist").ValidArgs("arg_name", "value")
	ErrDoesNotValidate = serr.New("does not validate").ValidArgs("arg_name", "value")

	ErrEmptyStateNotSatisfied = serr.New("not satisfied").ValidArgs("arg_name", "value")

	// ErrTokenValueCannotBeEmpty omits the word "token" to display a message "value
	// cannot be empty" and omits in order to differentiate from a potential generic
	// `ErrValueCannotBeEmpty` error.
	ErrTokenValueCannotBeEmpty = serr.New("value cannot be empty").ValidArgs(string(ArgType), string(FlagType))
	// ErrTokenValueMustBeEmpty omits the word "token" to display a message "value
	// must be empty" and omits in order to differentiate from a potential generic
	// `ErrValueMustBeEmpty` error.
	ErrTokenValueMustBeEmpty = serr.New("value must be empty").ValidArgs(string(ArgType), string(FlagType))

	// ErrHelpSentinel is used to trigger help.Usage() in main() by just checking for err==nil when returned from an app.Main().
	ErrHelpSentinel = serr.New(string(HelpArg))
)
View Source
var CmdHelp = AddCommandWithFunc(Token(HelpArg), ExecHelp).
	AddArg(Arg{
		Name:     CommandArg,
		Usage:    "Specifies the command to show help for",
		Optional: true,
		Variadic: true,
	}.EmptyOk())
View Source
var MatchSpaces = regexp.MustCompile(`\s+`)
View Source
var RootCmd = NewCommand("", nil)

RootCmd is parent of all top level command and is where global flags will be attached.

View Source
var StderrWriter io.Writer = os.Stderr
View Source
var StdoutWriter io.Writer = os.Stderr

StderrWriter is the writer used to direct output to StdErr, but can be set to a bytes.Buffer to capture output during tests.

Functions

func CheckExistence

func CheckExistence[S ~[]RM, RM RequirementsMeeter](ctx Context, rms S) (err error)

func CheckURL

func CheckURL(url string) (err error)

func Close

func Close(c io.Closer, f func(err error))

func CommandString

func CommandString(rootCmd *Command, tokens Tokens) (cs string, cnt int, err error)

CommandString returns the full list of commands minus the flags

func EmptyStateSatisfied

func EmptyStateSatisfied[S ~[]RM, RM RequirementsMeeter](ctx Context, tt TokenType, rms S) (err error)

func ExecHelp

func ExecHelp(Context, *CommandInvoker) (err error)

ExecHelp "implements" the help command by simply delegating to help.Usage() by returning an sentinel error which help.Usage() will recognize and generate the appropriate output.

func ExecutableFilepath

func ExecutableFilepath(name string) string

func MeetsRequirements

func MeetsRequirements[S ~[]RM, RM RequirementsMeeter](ctx Context, tt TokenType, rms S) (err error)

func StdErr

func StdErr(msg string, args ...any)

func StdOut

func StdOut(msg string, args ...any)

func ValidateByFunc

func ValidateByFunc[S ~[]RM, RM RequirementsMeeter](ctx Context, rms S) (err error)

func WarnOnError

func WarnOnError(err error)

Types

type Arg

type Arg struct {
	Name         ArgName
	Parent       *Command
	Usage        string
	Default      interface{}
	Optional     bool
	Variadic     bool
	ExistsFunc   func(Context, any, *Arg) error
	ValidateFunc func(Context, any, *Arg) error
	Type         reflect.Kind
	SetValueFunc func(*Value)
	Value        *Value
	Requires     ArgRequires
	SuccessMsg   string
}

func NewArg

func NewArg(arg Arg) Arg

func (Arg) Check

func (arg Arg) Check(requires ArgRequires) bool

func (Arg) CheckExistence

func (arg Arg) CheckExistence(ctx Context) (err error)

func (Arg) ClearCheckFunc

func (arg Arg) ClearCheckFunc() Arg

func (Arg) DefaultHelp

func (arg Arg) DefaultHelp(opts HelpOpts) (help string)

func (Arg) EmptyOk

func (arg Arg) EmptyOk() Arg

func (Arg) EmptyStateSatisfied

func (arg Arg) EmptyStateSatisfied(ctx Context, tt TokenType) (err error)

EmptyStateSatisfied ensures that values of .Requires for .Args are satisfied

func (Arg) Help

func (arg Arg) Help(opts HelpOpts) (help string)

func (Arg) IgnoreExists

func (arg Arg) IgnoreExists() Arg

func (Arg) IsZero

func (arg Arg) IsZero() bool

func (Arg) MustBeEmpty

func (arg Arg) MustBeEmpty() Arg

func (Arg) MustExist

func (arg Arg) MustExist() Arg

func (Arg) MustValidate

func (arg Arg) MustValidate() Arg

func (Arg) NotEmpty

func (arg Arg) NotEmpty() Arg

func (Arg) NotExist

func (arg Arg) NotExist() Arg

func (Arg) SignatureHelp

func (arg Arg) SignatureHelp() (s string)

func (Arg) String

func (arg Arg) String() string

func (Arg) Unique

func (arg Arg) Unique() string

func (Arg) ValidateByFunc

func (arg Arg) ValidateByFunc(ctx Context) (err error)

type ArgName

type ArgName string

type ArgRequires

type ArgRequires int
const (
	MustExist ArgRequires = 1 << iota
	IgnoreExists
	NotExist
	EmptyOk
	MustBeEmpty
	NotEmpty
	MustValidate
)

func AndRequires

func AndRequires(requires ...ArgRequires) (ar ArgRequires)

func ArgEmptiness

func ArgEmptiness(requires ArgRequires) ArgRequires

ArgEmptiness will return only one of the three emptiness modes, so it can be checked with case statement or simple equals (=).

func ArgExistence

func ArgExistence(requires ArgRequires) ArgRequires

ArgExistence will return only one of the three existence modes, so it can be checked with case statement or simple equals (=).

func ArgValidation

func ArgValidation(requires ArgRequires) ArgRequires

ArgValidation ArgEmptiness will return MustValidate if set, otherwise 0, so it can be checked with simple equals (=).

type Args

type Args []Arg

func (Args) DisplayWidth

func (args Args) DisplayWidth(minWidth int) (width int)

func (Args) Helpers

func (args Args) Helpers() (helpers []helper)

func (Args) Len

func (args Args) Len() int

func (Args) SignatureHelp

func (args Args) SignatureHelp() (help string)

func (Args) String

func (args Args) String() (s string)

type ArgsMap

type ArgsMap map[ArgName]*Arg

type Command

type Command struct {
	Name        Token
	Parent      *Command
	ExecFunc    ExecFunc
	Flags       Flags
	Args        Args
	SubCommands CommandMap
	// contains filtered or unexported fields
}

func AddCommand

func AddCommand(name Token) (cmd *Command)

func AddCommandWithFunc

func AddCommandWithFunc(name Token, ef ExecFunc) (cmd *Command)

func CommandByName

func CommandByName(rootCmd *Command, name string) (cmd *Command, depth int)

func InvokedCommand

func InvokedCommand(rootCmd *Command, tokens Tokens) (_ *Command, _ int, err error)

func NewCommand

func NewCommand(name Token, ef ExecFunc) *Command

func (*Command) AddArg

func (c *Command) AddArg(arg Arg) (cmd *Command)

func (*Command) AddFlag

func (c *Command) AddFlag(flg Flag) (cmd *Command)

func (*Command) AddSubCommand

func (c *Command) AddSubCommand(name Token, ef ExecFunc) (cmd *Command)

func (*Command) DeclaredArgsCount

func (c *Command) DeclaredArgsCount() (cnt int)

DeclaredArgsCount returns the number of total args; required and optional

func (*Command) FullName

func (c *Command) FullName() (name string)

func (*Command) Help

func (c *Command) Help() string

func (*Command) InvokedFlags

func (c *Command) InvokedFlags() (flags Flags)

InvokedFlags returns all the flags for th invoked command, including all parent flags including the root flags.

func (*Command) IsLeaf

func (c *Command) IsLeaf() bool

func (*Command) MeetsRequirements

func (c *Command) MeetsRequirements(ctx Context, tokenCnt int) (err error)

MeetsRequirements validates args and options passed on the CLI for full command path.

func (*Command) OptionalArgsCount

func (c *Command) OptionalArgsCount() (cnt int)

OptionalArgsCount returns the number of optional args

func (*Command) ReceivedArgsCount

func (c *Command) ReceivedArgsCount(tokenCnt int) int

ReceivedArgsCount returns number of args received on command line. Example: If the command is "make widget" and the os.Args has:

"/path/to/maker make widget -v -n foo bar baz"

then ReceivedArgsCount returns 3 for "foo bar baz."

func (*Command) RequiredArgsCount

func (c *Command) RequiredArgsCount() (cnt int)

RequiredArgsCount returns the number of required args

func (*Command) SetFlagDefault

func (c *Command) SetFlagDefault(name, value string)

func (*Command) SetFlags

func (c *Command) SetFlags(flags Flags) Flags

func (*Command) SignatureHelp

func (c *Command) SignatureHelp() string

func (*Command) String

func (c *Command) String() string

func (*Command) Unique

func (c *Command) Unique() (s string)

Unique returns the unique name for a command which includes its ancestor commands, e.g.:

  • `help`
  • `add codebase`
  • `add project`
  • `map`
  • `foo bar baz`

type CommandInvoker

type CommandInvoker struct {
	Tokens    Tokens
	AppName   string
	EnvPrefix string
	Command   *Command
}

func Initialize

func Initialize(ctx Context, params Params) (invoker *CommandInvoker, err error)

func NewCommandInvoker

func NewCommandInvoker(params Params) *CommandInvoker

func (*CommandInvoker) ArgInt

func (i *CommandInvoker) ArgInt(name ArgName) (n int)

func (*CommandInvoker) ArgString

func (i *CommandInvoker) ArgString(name ArgName) (s string)

func (*CommandInvoker) ArgValue

func (i *CommandInvoker) ArgValue(name ArgName) (value *Value)

func (*CommandInvoker) Args

func (i *CommandInvoker) Args() Args

func (*CommandInvoker) InvokeCommand

func (i *CommandInvoker) InvokeCommand(ctx Context) (err error)

func (*CommandInvoker) MeetsRequirements

func (i *CommandInvoker) MeetsRequirements(ctx Context) (err error)

MeetsRequirements validates args and options passed on the CLI

func (*CommandInvoker) SubCommands

func (i *CommandInvoker) SubCommands() CommandMap

type CommandMap

type CommandMap map[Token]*Command

func Commands

func Commands() CommandMap

type CommandType

type CommandType int
const (
	Undefined CommandType = iota
	RootCommand
	BranchCommand
	LeafCommand
	HelpCommand
)

type Context

type Context = context.Context

type ExecFunc

type ExecFunc func(Context, *CommandInvoker) error

type Flag

type Flag struct {
	Switch string
	Arg
}

func (Flag) Help

func (f Flag) Help(opts HelpOpts) (help string)

func (Flag) Initialize

func (f Flag) Initialize(ctx Context) Flag

func (Flag) SignatureHelp

func (f Flag) SignatureHelp() string

func (Flag) String

func (f Flag) String() string

func (Flag) Unique

func (f Flag) Unique() string

Unique returns a string that uniquely identifies a flag for its command

type Flags

type Flags []Flag

func (Flags) DisplayWidth

func (flags Flags) DisplayWidth(minWidth int) (width int)

func (Flags) Helpers

func (flags Flags) Helpers() (helpers []helper)

func (Flags) Index

func (flags Flags) Index(name ArgName) (n int)

func (Flags) Initialize

func (flags Flags) Initialize(ctx Context) Flags

Initialize initializes the flag package flags by calling the flag package's flag.<Type>Var() function on a pointer to f.Arg.Value.<type> so that this flag 'f' will get the values passed on the command line, or the defaults if not passed.

func (Flags) Len

func (flags Flags) Len() int

func (Flags) Remove

func (flags Flags) Remove(n int) Flags

func (Flags) SignatureHelp

func (flags Flags) SignatureHelp() (s string)

type FlagsMap

type FlagsMap map[string]Value

type Help

type Help struct {
	SetStderrWriterFunc func(io.Writer)
	// contains filtered or unexported fields
}

func NewHelp

func NewHelp(invoker *CommandInvoker) Help

func (Help) AppName

func (h Help) AppName() string

func (Help) GetUsage

func (h Help) GetUsage(err error) (help string)

func (Help) Usage

func (h Help) Usage(err error, w io.Writer)

type HelpOpts

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

type Params

type Params struct {
	AppName   string
	EnvPrefix string
	OSArgs    []string
	// contains filtered or unexported fields
}

func (Params) Args

func (p Params) Args() (Tokens, error)

func (Params) Options

func (p Params) Options() Tokens

func (Params) Tokens

func (p Params) Tokens() Tokens

type RequirementsMeeter

type RequirementsMeeter interface {
	EmptyStateSatisfied(Context, TokenType) error
	CheckExistence(Context) error
	ValidateByFunc(Context) error
}

type RequirementsMeeters

type RequirementsMeeters []RequirementsMeeter

type StringMap

type StringMap map[string]string

type Token

type Token string

type TokenType

type TokenType string
const (
	ArgType  TokenType = "arg"
	FlagType TokenType = "option"
)

type Tokens

type Tokens []Token

func (Tokens) Args

func (tt Tokens) Args() (_ Tokens, err error)

Args returns the tokens from os.Args that are not a `-flag` ot its value

func (Tokens) Count

func (tt Tokens) Count() int

func (Tokens) Join

func (tt Tokens) Join(sep string) string

Join joins a slice of Tokens into a strings. It is a copy of strings.Join() with small changes for tokens.

func (Tokens) Options

func (tt Tokens) Options() Tokens

func (Tokens) StringSlice

func (tt Tokens) StringSlice() (ss []string)

type Value

type Value struct {
	Type reflect.Kind
	// contains filtered or unexported fields
}

func NewValue

func NewValue(t reflect.Kind, value any) (v *Value)

func (Value) Int

func (v Value) Int() int

func (Value) IsZero

func (v Value) IsZero() (zero bool)

func (Value) String

func (v Value) String() string

Jump to

Keyboard shortcuts

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