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

cli

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package cli declares typed commands, parses invocations before service startup and runs them through Foundry's shared application lifecycle. It never changes process globals, installs tools or calls os.Exit.

Index

Constants

View Source
const DuringMaintenance = "--during-maintenance"

DuringMaintenance is the explicit operator flag, placed before the command name, that runs one invocation while application maintenance is paused. Draining (shutdown) still rejects every invocation.

View Source
const MaxArgumentBytes = 1 << 20
View Source
const MaxArguments = 256
View Source
const MaxCommands = 1024

Variables

View Source
var ErrNotConfirmed = safeerror.New("operation was not confirmed; rerun with --force to proceed")

ErrNotConfirmed reports that an operator declined, or could not be asked to confirm, a destructive command. It is an ordinary failure (exit status 1).

Functions

func Confirm

func Confirm(ctx context.Context, streams Streams, prompt string, force bool) error

Confirm writes prompt to Err and reads one answer line from In. Only "y" or "yes" (any case) confirms. force proceeds without prompting. An input that is an *os.File but not a terminal (a pipe, file or /dev/null) is non-interactive and refuses without reading. Reading is synchronous: a blocked terminal read is not interrupted by ctx, which is checked before and after the answer.

func ConfirmInProduction

func ConfirmInProduction(ctx context.Context, streams Streams, production bool, prompt string, force bool) error

ConfirmInProduction confirms only when production is true, typically from the application's configured environment. Other environments proceed silently.

func ExactArgs

func ExactArgs[A any](count int, assign func(*A, []string) error) func(*A, []string) error

ExactArgs binds exactly count positional values through assign, a helper for FlagsWithArgs. Values are validated text; assign converts them to typed fields.

func InvalidArguments

func InvalidArguments(err error) error

InvalidArguments retains a custom parser/validator's cause with usage status. A clean help result remains clean help; an output failure should be returned directly rather than wrapped as an argument problem.

func Module

func Module(name foundation.ProviderID, key foundation.Key[*Registry], registry *Registry, invocation Invocation, streams Streams, requires ...foundation.ProviderID) foundation.Module

Module installs the parsed invocation as the application's CLI kernel. Parse it using registry before building/starting the application, then reuse that registry here. The selected handler receives the same typed services as every other kernel, after providers boot, and normal shutdown follows its completion.

func ParseFlags

func ParseFlags(flags *flag.FlagSet, args []string) error

ParseFlags shares usage classification and help-output error handling with development commands using an existing FlagSet. It does not change defaults or flag ownership; use a fresh FlagSet for each invocation.

func Usage

func Usage(message string) error

Usage creates a usage error with the supplied message.

func WriteTable

func WriteTable(output io.Writer, header []string, rows [][]string) error

WriteTable writes aligned, tab-separated columns. Every row must have the header's column count. Tabs, newlines and other control characters inside cells become spaces, so application data cannot forge extra rows or columns.

Types

type Command

type Command[A any] struct {
	// contains filtered or unexported fields
}

Command pairs a command description with its typed argument decoder.

func Define

func Define[A any](name Name, summary string, decode Decoder[A]) Command[A]

Define keeps the concrete argument type through parsing and handler binding. Names are semantic identifiers; subcommands may use a typed custom decoder.

func (Command[A]) AllowDuringMaintenance

func (c Command[A]) AllowDuringMaintenance() Command[A]

AllowDuringMaintenance declares an operational command, such as a migration or the maintenance toggles themselves, that runs while maintenance is paused. Draining (shutdown) still rejects it. Other commands require the explicit DuringMaintenance flag for one invocation.

func (Command[A]) Declare

func (c Command[A]) Declare(construct func(foundation.Resolver) (Handler[A], error)) (Declaration, error)

Declare binds the command to a typed handler constructor after validating both.

func (Command[A]) Name

func (c Command[A]) Name() Name

Name returns the command name.

func (Command[A]) Validate

func (c Command[A]) Validate() error

Validate checks the command name, summary, and decoder.

type Declaration

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

Declaration is the heterogeneous registration boundary. Factories resolve concrete services only for the selected command, after application startup. Plugins can export declarations for explicit inclusion in the same registry.

func (Declaration) Format

func (Declaration) Format(state fmt.State, _ rune)

Format writes a fixed label without exposing the declaration.

type Decoder

type Decoder[A any] func([]string, io.Writer) (A, error)

Decoder performs pure argument parsing. It must return an owned value and leave resource acquisition to the command handler. Help returns flag.ErrHelp.

func Flags

func Flags[A any](configure func(*flag.FlagSet, *A), validate func(A) error) Decoder[A]

Flags adapts Go's ordinary typed flag bindings to an owned argument struct. Configure runs for every parse against a fresh A and FlagSet; bind defaults there rather than retaining pointers or using global flags. Validation runs after parsing, before command construction. Positional arguments are rejected; use FlagsWithArgs, or a custom Decoder for subcommand behavior.

func FlagsWithArgs

func FlagsWithArgs[A any](configure func(*flag.FlagSet, *A), positional func(*A, []string) error, validate func(A) error) Decoder[A]

FlagsWithArgs also binds the positional arguments remaining after flags (and after a "--" terminator) into the same owned argument struct. The positional callback receives an owned slice; return an error for a wrong count or format, which becomes a usage error. A nil callback rejects positional arguments exactly like Flags.

type Description

type Description struct {
	Name      Name   `json:"name"`
	Summary   string `json:"summary"`
	Arguments string `json:"arguments"`
	// Maintenance reports that the command runs while maintenance is paused.
	Maintenance bool `json:"maintenance,omitempty"`
}

Description describes a command's name, summary, arguments, and maintenance policy.

type ExitCode

type ExitCode int

ExitCode is a process exit status.

const (
	Success      ExitCode = 0
	Failure      ExitCode = 1
	InvalidUsage ExitCode = 2
	TimedOut     ExitCode = 124
	Interrupted  ExitCode = 130
)

func Report

func Report(output io.Writer, err error) ExitCode

Report writes an execution error once and returns its process exit code. The application's main function owns os.Exit and signal handling. A write failure or a misbehaving custom Error method is itself a failed report. Report is an intentional operator-facing presentation boundary: it calls the supplied error's Error method inside callback isolation. It does not promise runtime report redaction; callers choose the error text they present.

func Status

func Status(err error) ExitCode

Status treats only a clean help result as success. A joined help/write error remains a failure. Classifying a custom error is isolated from panic/Goexit; cyclic or excessively large/deep error graphs return Failure. Custom error methods must return and perform shallow Is/As comparisons.

type Handler

type Handler[A any] func(context.Context, A, Streams) error

Handler handles decoded command arguments using explicit streams.

type Invocation

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

Invocation owns one parsed command. Copies share its execution claim: an invocation runs at most once, including on failure, avoiding accidental retry of a partially completed mutation. Parse again for an intentional new run.

func (Invocation) Format

func (Invocation) Format(state fmt.State, _ rune)

Format writes a fixed label without exposing parsed arguments.

func (Invocation) Name

func (i Invocation) Name() Name

Name returns the parsed command name, or an empty name for a zero invocation.

func (Invocation) Run

func (i Invocation) Run(ctx context.Context, resolver foundation.Resolver, streams Streams) error

Run runs the invocation at most once after validating context and streams, with maintenance admission and callback isolation.

type Name

type Name string

Name identifies a CLI command.

type Registry

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

Registry freezes explicit declarations. New, Describe and Parse perform no service construction, kernel startup or external I/O beyond the help writer.

func New

func New(declarations ...Declaration) (*Registry, error)

New constructs a command registry, rejecting invalid, duplicate, or excessive declarations.

func (*Registry) Describe

func (r *Registry) Describe() []Description

Describe returns command descriptions sorted by name; a nil registry returns nil.

func (*Registry) Parse

func (r *Registry) Parse(args []string, help io.Writer) (Invocation, error)

Parse parses command arguments without constructing the handler. Help requests write help and return flag.ErrHelp.

type Streams

type Streams struct {
	In       io.Reader
	Out, Err io.Writer
}

Streams holds the command's input, output, and error streams.

func (Streams) Validate

func (s Streams) Validate() error

Validate checks that all three streams are supplied.

type UsageError

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

UsageError distinguishes malformed input from an execution failure. Error causes are retained; a parser must avoid embedding credentials in messages.

func (*UsageError) Error

func (e *UsageError) Error() string

Error returns the underlying message, or a default message for an empty error.

func (*UsageError) Unwrap

func (e *UsageError) Unwrap() error

Unwrap returns the underlying cause, or nil for a nil receiver.

Jump to

Keyboard shortcuts

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