Help us shape the future of Go! Take the 2026 Go Developer Survey

cli

package
v0.36.0 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package cli is the UI every command shares: where a command reads and writes, the problems it reports, the lines on stderr, the --json object, and the one place a run's problems become its exit code.

It imports no domain. A domain's errors are a sealed set of plain types carrying no exit code, rule ID or wording; cmd hands the UI one Classifier per domain, each turning that domain's failures into problems in one switch naming every kind. An error no classifier claims is the 100 of an unclassified bug, never a child process's status passed through.

Index

Constants

View Source
const (
	CodeNo             = 1   // a check said no
	CodeTemporary      = 75  // may pass when run again unchanged
	CodeUsage          = 80  // a usage or config error
	CodeUnknownCommand = 81  // a command or subcommand that is none
	CodeEnvironment    = 82  // a requirement not met: the environment lacks something
	CodeInternal       = 100 // an error nothing classified
	CodeInterrupted    = 130 // an interrupt stopped it (decision 38)
)

The exit codes, as docs/CLI.md's table gives them: square/exit's, with 75 kept for a failure that may pass when run again (decision 36).

View Source
const InterruptedMeaning = "interrupted by SIGINT or SIGTERM; on Linux and macOS it then ends by that signal, which a shell reads as 130 or 143"

InterruptedMeaning is what every command's help says of exit 130.

View Source
const Issues = "https://github.com/donvargax/itos-cc/issues"

Issues is where a person reports a bug.

Variables

View Source
var ErrInterrupted = errors.New("interrupted")

ErrInterrupted is the cause a command's context is cancelled with when an interrupt stops it (decision 38): SIGINT, Ctrl-C, or SIGTERM. A classifier maps a cancellation to the interrupted problem only when errors.Is reports this cause, so a fail-fast stop, a timeout or a parent's cancellation keeps its own classification. It names no domain.

Precedence picks the exit code of a run with problems of several codes: the first of these it has, not the highest, the one that says the most about why nothing else could be trusted (q-54, decision 36, docs/CLI.md's exit codes). The interrupt is first.

Functions

func Closest added in v0.14.4

func Closest(word string, candidates []string) string

Closest is the candidate nearest to word, or "" when none is near enough to be what was meant: fewer than three edits away, the first of the nearest in candidates' order. A word that only ends differently, such as mutate for mutation, is near too: all but its last letter, four letters at least, begin exactly one candidate. An unknown command and an unknown flag name the one meant by it.

func Complete

func Complete(root *kong.Application, words []string) []string

Complete returns one candidate per line followed by the shell's fallback instruction. words contains the arguments after __complete; its last word is the partial word, including an empty word for a new token.

func ExitCode added in v0.14.3

func ExitCode(problems []*Problem) int

ExitCode is the exit code of a run with problems: 0 with none, else the first code of Precedence one of them has. A problem of a code the list lacks is a defect of ours, so with no listed code it is 100.

func Flags

func Flags() []kong.Option

Flags are the kong options that hold the command line's flags to the rules above, each parser given its own.

func GroupHelp added in v0.15.9

func GroupHelp(node *kong.Node) (string, error)

GroupHelp preserves a group's help layout, using the same parser model as its children. A group describes itself through the usual Contract.

func Help added in v0.14.4

func Help(_ kong.HelpOptions, ctx *kong.Context) error

Help is kong's help printer, kong.Help(cli.Help): the page of the command kong selected, from its model and its Contract, on kong's stdout. kong's own printer is replaced so every command's help keeps one layout.

func Parse added in v0.14.4

func Parse(parser *kong.Kong, args []string) (*kong.Context, error)

Parse parses args, a command line naming a command of the parser's model (units --changed src), with parser, which has parsed nothing before: Flags holds the state of one parse, so a parser parses once. It reads the line as every command does, where kong would not:

  • A word of one dash before -- is a mistyped long flag (MistypedFlagError), unless what comes before it fails first.
  • Arguments may stand between flags: kong reads a command's arguments in one run, so they are moved behind its flags, after a --, keeping what each word is.

func Rel added in v0.19.0

func Rel(dir, path string) string

Rel is path named from dir, the working directory, when it is in it, and as it is otherwise or when dir is "", not known: the one copy of how a person reads a path, which the UI names paths by and cmd gives the slices whose handlers name files, from the same directory.

func Scripts

func Scripts() map[string]string

Scripts are short shell integrations that ask this executable for each completion request.

func Usage added in v0.15.9

func Usage(app *kong.Application) string

Usage is the top-level help of app, kong's model of every command: each command a line, sorted by name, a group's subcommands each a line in its place in the group's order, then the options every command takes, the exit codes and examples.

func WriteFlags added in v0.14.4

func WriteFlags(w io.Writer, flags []HelpFlag)

WriteFlags lists flags as help does, one a line, its description in a column of its own, or on the next line when the flag is too long for it.

Types

type Choice added in v0.15.2

type Choice string

Choice is the choice a switch of choices took, a *Choice field nil when the switch is not given.

type ChoiceError added in v0.15.2

type ChoiceError struct {
	Flag  *kong.Flag
	Value string
}

ChoiceError is a switch of choices given a value, Value as it was written after the =, that is none of its choices.

func (*ChoiceError) Choices added in v0.15.2

func (e *ChoiceError) Choices() string

Choices names the switch's choices as the hand parser named them: =a or =b.

func (*ChoiceError) Error added in v0.15.2

func (e *ChoiceError) Error() string

type Classifier added in v0.14.3

type Classifier func(err error) ([]*Problem, bool)

Classifier turns err, a failure of one domain's sealed set, into its problems, each with its code, and says whether err was of that set. A classifier names every kind of its set in one switch, so gochecksumtype refuses it when a kind is added and left out.

type Completion

type Completion struct {
	Shell string `arg:"" enum:"bash,zsh,fish,powershell" help:"The shell: bash, zsh, fish or powershell."`
}

Completion is the public command that prints a shell's completion stub.

func (Completion) Run

func (c Completion) Run(ui *UI) int

Run prints the requested shell stub, or reports an unsupported shell as a usage error.

type Contract added in v0.14.4

type Contract struct {
	About    string
	JSON     string
	Rules    []string
	Exits    []Exit
	Examples []string
}

Contract is what a command's help says beyond its flags and arguments, which kong's model holds: what it does, the keys --json adds beside schema, ok and problems, the problem rules it reports ("rule: meaning"), its exit codes (0 and 80 among them; 100 and 130 are every command's), and examples.

type Declaration added in v0.18.3

type Declaration struct {
	Name string
	Help string
	New  func() any
}

Declaration is what a slice declares its command by, which cmd assembles the one model of every command from (ADR-0051): Name, the word that runs it, Help, the line the top-level help lists it by, and New, which makes a fresh value of its kong struct, a pointer, for each parser cmd builds, so no parse shares the state of another. The handler a command's Run is handed is built in cmd from the ports the slice declares beside it, its Ports, which cmd's adapters satisfy; a declaration holds no port and reads nothing, so declaring a command costs help and version nothing.

type Documented added in v0.14.4

type Documented interface {
	Contract() Contract
}

Documented is a command whose help gives its contract: a slice's kong struct implements it, and Help prints it.

type Exit added in v0.14.4

type Exit struct {
	Code    int
	Meaning string
}

Exit is an exit code a command can return, and when.

type HelpFlag added in v0.14.4

type HelpFlag struct {
	Name    string
	Short   rune
	Arg     string
	Default string
	Choices []string
	Repeat  bool
	Help    string
}

HelpFlag is one flag as help lists it: its name, its one-letter form, the placeholder of its value, its default, the values a switch may take after =, and whether it may be given again.

type Interrupts added in v0.16.0

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

Interrupts is how one run of itos-cc stops on an interrupt (decision 38): the first cancels the command's work with ErrInterrupted, so whatever waits on its context ends and the command reports the interrupt itself, exit CodeInterrupted, saying so once; a later one ends the command at once, unless the process groups the run owns are being killed then (ADR-0021), which finish first so none outlives it. cmd makes one per run and binds Cleaning to what kills those groups, so no registry holds it.

func (*Interrupts) Cleaning added in v0.16.0

func (i *Interrupts) Cleaning() (release func())

Cleaning marks owned process groups being killed and joined until the release it returns is called, which a later interrupt waits for. It may be called from any goroutine, and its release once.

func (*Interrupts) Signal added in v0.16.0

func (i *Interrupts) Signal() os.Signal

Signal is the interrupt that stopped the run, nil when none came.

func (*Interrupts) Stop added in v0.16.0

func (i *Interrupts) Stop(interrupts <-chan os.Signal, cancel context.CancelCauseFunc, end func(os.Signal))

Stop stops a command on the interrupts it reads, until interrupts is closed or end returns, which cmd's never does. The first cancels the work through cancel, with ErrInterrupted as the cause. A later one calls end with the first interrupt, to end the process at once; one that comes while owned process groups are being killed waits for them instead and is spent there, the command then ending on its own once their cleanup is done, so the report it writes is not cut short. cmd reads interrupts from signal.Notify, the one line that differs by system, so a test feeds it interrupts of its own and sees what each does.

type Line added in v0.14.4

type Line struct {
	JSON, Help bool
}

Line is what a command line asks for before kong reads it: the --json object, even for a usage error, and help, which -h or --help anywhere before -- asks for whatever else the line holds.

func Read added in v0.14.4

func Read(args []string) Line

Read is what args ask for, read up to --.

type MistypedFlagError added in v0.14.4

type MistypedFlagError struct {
	Word string
	// Command is the command whose flags the word is weighed against.
	Command *kong.Node
}

MistypedFlagError is a word of one dash before --, other than - and -h: a long flag written with one dash, such as -changed, since -h is the only short flag. kong would read it as short flags, -c first, so Parse finds it first, against kong's model.

func (*MistypedFlagError) Error added in v0.14.4

func (e *MistypedFlagError) Error() string

type NumberError added in v0.15.0

type NumberError struct {
	Flag  *kong.Flag
	Value string
	Whole bool
}

NumberError is a number flag given a value, Value as it was written, that is not a number, or with Whole not a whole number.

func (*NumberError) Error added in v0.15.0

func (e *NumberError) Error() string

func (NumberError) What added in v0.15.0

func (e NumberError) What() string

What is the kind of number the flag needs, as a person reads it.

type Page added in v0.14.4

type Page struct {
	Program, Command, Synopsis string
	Flags                      []HelpFlag
	Contract
}

Page is one command's help: the program and the command, the words after them in its usage line, its flags and its contract.

func PageOf added in v0.14.4

func PageOf(node *kong.Node) (Page, error)

PageOf is the help page of node, a command of kong's model: its flags, its own first and then those of the commands above it, its arguments, and the Contract its struct gives.

func (Page) String added in v0.14.4

func (p Page) String() string

String is the page as the command prints it.

type Problem

type Problem struct {
	Code    int
	Rule    string
	Message string
	Fix     string
	// Shown is set when plain output already shows the problem, so it is
	// not repeated on stderr.
	Shown bool
	// contains filtered or unexported fields
}

Problem is one reason a run did not succeed. Code is its exit code; Rule is a stable, dotted lower-case ID scripts switch on; Message and Fix are sentences for people. Its subject holds what the problem is about, such as file, line and function, as keys of their own beside rule, message and fix in --json, so no script parses a message.

func CommandNeedsReport added in v0.15.2

func CommandNeedsReport() *Problem

CommandNeedsReport is the problem of --coverage-command given without --coverage-report, which says where the report it writes lands: a usage error. Every command that measures coverage takes both flags, crap and mutation run, so the problem is the UI's to word once.

func GroupLine added in v0.15.9

func GroupLine(node *kong.Node, args []string) (child []string, help bool, problem *Problem)

GroupLine admits the words before a group's child, before its flags are parsed. Only the common JSON/help switches are accepted there. The selected child is always resolved from this parser's model; its options are parsed once by Parse. Help after an unknown child cannot hide it.

func Internal added in v0.14.3

func Internal(err error) *Problem

Internal is err as an internal problem, a defect of ours: exit 100.

func Interrupted added in v0.14.3

func Interrupted() *Problem

Interrupted is the problem of a command an interrupt cancelled: exit 130, what shells report for Ctrl-C (128 and SIGINT's 2), on every system, SIGTERM's included. A domain's classifier gives it for its kind of a cancelled failure whose cause is ErrInterrupted.

func NewProblem added in v0.14.3

func NewProblem(code int, rule, message, fix string) *Problem

NewProblem is a problem of its code, rule, message and fix, about nothing yet.

func ParseProblem added in v0.14.4

func ParseProblem(err error, args []string) *Problem

ParseProblem is err, Parse's failure to parse args, as the problem docs/CLI.md names it, each kind told by its type:

  • flags.unknown: kong's UnknownFlagError, or a MistypedFlagError, naming the flag as written and the one meant when it can guess it.
  • flags.switch-value, flags.value-missing and flags.repeated: Flags' own refusals, and kong's MissingValueError of a flag.
  • flags.value-invalid: a number flag's value that is no number of its kind (NumberError), or a switch's value that is none of its choices (ChoiceError), in the hand parser's words; a value kong's own mapper refused, or not of its enum, in kong's words until a command meets one.
  • command.unknown, args.unexpected and command.missing: kong's UnexpectedArgumentError, for a command or an argument, and its MissingCommandError.

Another failure of the command line, which no command can meet yet, is a usage problem in kong's words; any other error, such as a model kong refuses, is internal, a bug.

func UnknownCommand added in v0.15.9

func UnknownCommand(node *kong.Node, word string) *Problem

UnknownCommand is the problem of word, no command of node's: the one meant, when one is near enough to guess.

func (*Problem) Error added in v0.14.3

func (p *Problem) Error() string

Error is the problem's message.

func (*Problem) MarshalJSON added in v0.14.3

func (p *Problem) MarshalJSON() ([]byte, error)

MarshalJSON is the problem as --json gives it: rule, message, fix when there is one, its own exit code, as RFC 9457's status gives each problem its own (q-54), and the subject's keys beside them.

func (*Problem) Subject added in v0.14.3

func (p *Problem) Subject(key string) any

Subject is the value of the subject key, or nil.

func (*Problem) With added in v0.14.3

func (p *Problem) With(key string, value any) *Problem

With sets the subject key to value and returns p. A reserved key is a defect of ours, so it panics rather than let a subject hide the problem's own keys.

type RepeatedFlagError added in v0.14.4

type RepeatedFlagError struct{ Flag *kong.Flag }

RepeatedFlagError is a flag that is not cumulative given more than once.

func (*RepeatedFlagError) Error added in v0.14.4

func (e *RepeatedFlagError) Error() string

type Route added in v0.15.9

type Route struct {
	// JSON is whether --json came before the command, which the route's
	// problem is printed by.
	JSON bool
	// Problem, when set, is the usage problem the line is.
	Problem *Problem
	// Usage is whether the line asks for the top-level help.
	Usage bool
	// Help, when set, is the command whose help 'help' asks for: its name,
	// and a group's subcommand after it, each known to the model.
	Help []string
	// Line, when set, is the command line of the command named: its name,
	// then the words after it, --json last when it came before the command.
	Line []string
}

Route is what a whole command line asks for, as Dispatch reads it: a problem, the top-level help, a command's help, or a command to run.

func Dispatch added in v0.15.9

func Dispatch(app *kong.Application, args []string) Route

Dispatch reads args, a whole command line after the program's name, against app, kong's model of every command. The flags before a command are read in turn: --json asks for the object, -h or --help for the top-level help, at once, --version for the version command, before whatever command follows, and any other is a usage problem. No command is the top-level help, or with --json a usage problem; help is a command's help, or the top level's; any other word must name one of app's commands, and the one meant is guessed when it does not.

type Selection added in v0.15.2

type Selection struct {
	Changed bool     `help:"only files git reports as added or modified"`
	Paths   []string `arg:"" optional:"" name:"path" help:"files, directories, or fragments of a path under the working directory"`
}

Selection is the command line every command selects its files by: the files git reports as changed, and the paths, files, directories or fragments of one, given as its arguments. A command's kong struct embeds it as its first field, so --changed leads its help's options as it always has and the command's own flags follow; the arguments end the usage line wherever the struct holds them. Its tags need no import of kong. A slice copies its values into its own Query, which keeps its own Changed and Paths.

type SwitchValueError added in v0.14.4

type SwitchValueError struct {
	Flag  *kong.Flag
	Value string
}

SwitchValueError is a switch the command line gave a value, Value, as it was written after the =.

func (*SwitchValueError) Error added in v0.14.4

func (e *SwitchValueError) Error() string

type UI

type UI struct {
	In     io.Reader
	Stdout io.Writer
	Stderr io.Writer
	// Classifiers are cmd's, one per domain, tried in turn.
	Classifiers []Classifier
	// Dir is the working directory, which the paths a person reads are
	// named from; "" when it is not known.
	Dir string
}

UI is a command's ends: what it reads and where it writes, and the classifiers that turn its domains' failures into problems. Nothing here asks a question, so there is no terminal to know of.

func (*UI) Emit added in v0.14.3

func (u *UI) Emit(asJSON bool, data any, problems []*Problem) int

Emit prints a run's outcome and returns its exit code: with asJSON the object {"schema": 1, "ok": …, data's keys…, "problems": […]} on stdout, "problems" there only when ok is false; otherwise each problem plain output has not shown already on stderr, as "itos-cc: <message>. <fix>".

func (*UI) Fail

func (u *UI) Fail(err error, withJSON bool) int

Fail reports err, a command failing, and returns its exit code: with withJSON the failure's object on stdout, otherwise each problem a line on stderr.

func (*UI) JSON

func (u *UI) JSON(v any)

JSON writes v on stdout as --json prints it, one object indented by two spaces; a failure to is a line on stderr.

func (*UI) Line

func (u *UI) Line(message string)

Line writes message on stderr as a line for people, itos-cc: first. A stderr that cannot be written leaves nowhere else to say so.

func (*UI) Problems added in v0.14.3

func (u *UI) Problems(err error) []*Problem

Problems is err as the problems it reports. A problem is itself; a failure a classifier claims is that classifier's problems; a cause no classifier claims that an interrupt gave, ErrInterrupted, is the interrupt; anything else is one internal problem, err whole. Errors joined (errors.Join) are each their own problems once one of them is claimed, so one never hides another.

func (*UI) Rel added in v0.14.4

func (u *UI) Rel(path string) string

Rel is path as a person reads it: from the working directory when it is in it, and as it is otherwise, so output reads like the command line that produced it (Rel, from u.Dir).

func (*UI) Usage

func (u *UI) Usage(command string, err error, withJSON bool) int

Usage reports err, a command line kong could not parse, as Fail does: a usage error, exit 80, in the words of the person who wrote the line. The command is named as it was written, so the sentence says what was read, never kong's own such as "EOL".

type ValueMissingError added in v0.14.4

type ValueMissingError struct {
	Flag *kong.Flag
	Next string
}

ValueMissingError is a flag that takes a value given none: the command line ended after it, or Next, a flag, came next.

func (*ValueMissingError) Error added in v0.14.4

func (e *ValueMissingError) Error() string

type Written added in v0.19.0

type Written map[string][]string

Written is the flags a validated command line gave, by name, each with its values as written, which Provided reads. cmd binds it once for every command, so a Run that quotes a value back as the person wrote it asks for it, and converts it to its own.

func Provided added in v0.15.9

func Provided(ctx *kong.Context) Written

Provided returns only the flags on the validated Kong path, retaining their original value spellings. Defaults are deliberately absent: an explicit empty string or zero is different from an omitted flag. This reads provenance after Parse; Kong alone validates and decodes options. It supports the long flags held by Flags, whose only short form is help.

Jump to

Keyboard shortcuts

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