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
- Variables
- func Confirm(ctx context.Context, streams Streams, prompt string, force bool) error
- func ConfirmInProduction(ctx context.Context, streams Streams, production bool, prompt string, ...) error
- func ExactArgs[A any](count int, assign func(*A, []string) error) func(*A, []string) error
- func InvalidArguments(err error) error
- func Module(name foundation.ProviderID, key foundation.Key[*Registry], registry *Registry, ...) foundation.Module
- func ParseFlags(flags *flag.FlagSet, args []string) error
- func Usage(message string) error
- func WriteTable(output io.Writer, header []string, rows [][]string) error
- type Command
- type Declaration
- type Decoder
- type Description
- type ExitCode
- type Handler
- type Invocation
- type Name
- type Registry
- type Streams
- type UsageError
Constants ¶
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.
const MaxArgumentBytes = 1 << 20
const MaxArguments = 256
const MaxCommands = 1024
Variables ¶
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 ¶
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 ¶
ExactArgs binds exactly count positional values through assign, a helper for FlagsWithArgs. Values are validated text; assign converts them to typed fields.
func InvalidArguments ¶
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 ¶
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 WriteTable ¶
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 ¶
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 ¶
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.
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.
type Decoder ¶
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 ¶
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.
func Report ¶
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 ¶
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 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 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.
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.