Reconcile module docs and release materials
This commit is contained in:
38
command.go
38
command.go
@@ -10,7 +10,9 @@ import (
|
||||
)
|
||||
|
||||
// Command is an opaque, reusable declaration captured by NewCommand, Group,
|
||||
// RootGroup, or an integration.
|
||||
// RootGroup, or an integration. Capture copies declaration slices but retains
|
||||
// callback and caller-owned object references. Installation validates the
|
||||
// declaration before changing an App registry.
|
||||
type Command struct{ record *commandRecord }
|
||||
|
||||
type commandRecord struct {
|
||||
@@ -25,7 +27,8 @@ type commandRecord struct {
|
||||
invalid bool
|
||||
}
|
||||
|
||||
// Supplied carries a value and whether it was explicitly provided.
|
||||
// Supplied carries a value and whether it was explicitly provided. Defaults can
|
||||
// have Set=false; an explicitly supplied empty, false, or zero value has Set=true.
|
||||
type Supplied[T any] struct {
|
||||
// Value is the associated value.
|
||||
Value T
|
||||
@@ -33,7 +36,8 @@ type Supplied[T any] struct {
|
||||
Set bool
|
||||
}
|
||||
|
||||
// FlagMeta describes a command flag.
|
||||
// FlagMeta describes a command flag. Required applies when execution prepares
|
||||
// the selected command; help reports the metadata without requiring the value.
|
||||
type FlagMeta struct {
|
||||
// Name is the flag name without leading dashes.
|
||||
Name string
|
||||
@@ -45,7 +49,8 @@ type FlagMeta struct {
|
||||
Required bool
|
||||
}
|
||||
|
||||
// ArgumentMeta describes a positional command argument.
|
||||
// ArgumentMeta describes a positional command argument. Its name and usage are
|
||||
// used in generated help.
|
||||
type ArgumentMeta struct {
|
||||
// Name is the argument name shown in command help.
|
||||
Name string
|
||||
@@ -53,7 +58,9 @@ type ArgumentMeta struct {
|
||||
Usage string
|
||||
}
|
||||
|
||||
// Flag represents a typed binding for a command flag.
|
||||
// Flag represents a typed binding for a command flag. Copies retain binding
|
||||
// identity; separately constructed flags are distinct even when their metadata
|
||||
// and callbacks are equivalent.
|
||||
type Flag[I any] struct {
|
||||
binding flagBinding[I]
|
||||
}
|
||||
@@ -93,6 +100,10 @@ type argumentBinding[I any] struct {
|
||||
}
|
||||
|
||||
// CommandSpec declares one command using typed input and handler callbacks.
|
||||
// Capture copies its Flags, Arguments, and Children slices. NewInput runs only
|
||||
// when execution reaches input construction; a nil factory yields a fresh zero
|
||||
// value. CheckInput runs after supplied values are converted and applied, before
|
||||
// Run. Run may be nil for a parent that only groups child commands.
|
||||
type CommandSpec[I any] struct {
|
||||
// Name is one command path component.
|
||||
Name string
|
||||
@@ -186,8 +197,9 @@ func (c typedCommand[I]) prepare(flagValues [][]string, operands []string, enfor
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewCommand captures a typed command declaration. Construction issues are
|
||||
// retained and reported when the declaration is installed.
|
||||
// NewCommand captures a typed command declaration without constructing its
|
||||
// input or running callbacks. Construction issues are retained and reported
|
||||
// when the declaration is installed. The returned declaration can be reused.
|
||||
func NewCommand[I any](spec CommandSpec[I]) Command {
|
||||
return captureCommand(spec, nil)
|
||||
}
|
||||
@@ -209,7 +221,8 @@ func captureCommand[I any](spec CommandSpec[I], privateRun func(commandExecution
|
||||
return Command{record: record}
|
||||
}
|
||||
|
||||
// Group captures a non-runnable command group and its relative children.
|
||||
// Group captures a non-runnable command group and a copy of its relative child
|
||||
// slice. Child declarations remain reusable and are not recursively copied.
|
||||
func Group(name, summary string, children ...Command) Command {
|
||||
record := &commandRecord{name: name, summary: summary, children: append([]Command(nil), children...)}
|
||||
captureComposition(record)
|
||||
@@ -217,13 +230,16 @@ func Group(name, summary string, children ...Command) Command {
|
||||
}
|
||||
|
||||
// RootGroup captures a group that may only be installed at the application root.
|
||||
// Installation rejects it below any other command, including through wrappers.
|
||||
func RootGroup(name, summary string, children ...Command) Command {
|
||||
command := Group(name, summary, children...)
|
||||
command.record.rootOnly = true
|
||||
return command
|
||||
}
|
||||
|
||||
// WithError returns a declaration that also retains err for installation.
|
||||
// WithError returns a new declaration that also retains a non-nil err for
|
||||
// installation. Earlier declaration and child errors remain available, and
|
||||
// wrapped error identity is preserved. A nil err returns command unchanged.
|
||||
func WithError(command Command, err error) Command {
|
||||
if err == nil {
|
||||
return command
|
||||
@@ -239,7 +255,9 @@ func WithError(command Command, err error) Command {
|
||||
return Command{record: &record}
|
||||
}
|
||||
|
||||
// NoCommand explicitly represents an absent optional declaration.
|
||||
// NoCommand explicitly represents an absent optional declaration. Installation
|
||||
// skips it, but reports errors attached to it; a zero Command is invalid and is
|
||||
// not an absence marker.
|
||||
func NoCommand() Command { return Command{record: &commandRecord{absent: true}} }
|
||||
|
||||
func captureComposition(record *commandRecord) {
|
||||
|
||||
Reference in New Issue
Block a user