Document application-owned alias contracts
This commit is contained in:
16
app.go
16
app.go
@@ -33,12 +33,18 @@ type commandNode struct {
|
||||
command Command
|
||||
}
|
||||
|
||||
// New creates an application with the supplied identity and initial
|
||||
// declarations.
|
||||
// New creates an application with the supplied identity and initial canonical
|
||||
// commands and routing rules. Use []Declaration to expand a mixed declaration
|
||||
// collection; []Command cannot be expanded as ...Declaration without
|
||||
// converting its elements.
|
||||
//
|
||||
// The identity name must not be empty. New installs its generated help and
|
||||
// version commands and caller declarations as one batch; an invalid declaration
|
||||
// returns an error without exposing an App. The root help and version names are
|
||||
// reserved for generated commands.
|
||||
// version commands and caller declarations as one batch; an invalid, nil, or
|
||||
// zero declaration returns an error without exposing an App. Factory issues
|
||||
// retained in Command and RoutingRule values are reported during installation.
|
||||
// Identical duplicate routing mappings are accepted; conflicting mappings
|
||||
// fail the batch. The root help and version names are reserved for generated
|
||||
// commands.
|
||||
func New(identity Identity, declarations ...Declaration) (*App, error) {
|
||||
if identity.Name == "" {
|
||||
return nil, fmt.Errorf("application identity name must not be empty")
|
||||
|
||||
74
command.go
74
command.go
@@ -10,21 +10,32 @@ import (
|
||||
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
||||
)
|
||||
|
||||
// Command is an opaque, reusable declaration captured by NewCommand, Group,
|
||||
// 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.
|
||||
// Command is an opaque, reusable declaration of canonical commands and groups.
|
||||
// NewCommand, Group, RootGroup, and integration command factories return
|
||||
// Command values. 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 }
|
||||
|
||||
// Declaration is a captured command or application routing rule accepted by
|
||||
// New and App.Register. Only CommandKit declaration types implement it.
|
||||
// Declaration is a captured canonical command or application routing rule
|
||||
// accepted by New and App.Register. Use []Declaration when collecting both
|
||||
// kinds. Group and RootGroup children remain Commands; install routing rules
|
||||
// alongside the completed command tree through New or Register. Only
|
||||
// CommandKit declaration types implement Declaration.
|
||||
//
|
||||
// A zero Command, zero RoutingRule, nil declaration, or typed nil declaration
|
||||
// pointer is invalid. Use NoCommand to represent an intentionally absent
|
||||
// optional command.
|
||||
type Declaration interface {
|
||||
commandkitDeclaration()
|
||||
}
|
||||
|
||||
func (Command) commandkitDeclaration() {}
|
||||
|
||||
// RoutingRule is an opaque, reusable command or flag alias declaration.
|
||||
// RoutingRule is an opaque, reusable command or flag alias declaration. Alias,
|
||||
// FlagAlias, and FlagAliasFor capture routing rules eagerly and retain any
|
||||
// construction issues for New or App.Register to report. Identical duplicate
|
||||
// mappings are accepted; competing targets for the same source are errors.
|
||||
type RoutingRule struct{ record *routingRuleRecord }
|
||||
|
||||
func (RoutingRule) commandkitDeclaration() {}
|
||||
@@ -236,9 +247,11 @@ func (c typedCommand[I]) prepare(flagValues, flagSpellings [][]string, operands
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NewCommand captures a typed canonical command declaration without
|
||||
// constructing its input or running callbacks. It copies the spec's flags,
|
||||
// arguments, and children slices. Construction issues are retained and
|
||||
// reported when the declaration is installed; NewCommand itself does not
|
||||
// return an error. The returned declaration can be reused across Apps.
|
||||
func NewCommand[I any](spec CommandSpec[I]) Command {
|
||||
return captureCommand(spec, nil)
|
||||
}
|
||||
@@ -260,25 +273,29 @@ func captureCommand[I any](spec CommandSpec[I], privateRun func(commandExecution
|
||||
return Command{record: record}
|
||||
}
|
||||
|
||||
// Group captures a non-runnable command group and a copy of its relative child
|
||||
// slice. Child declarations remain reusable and are not recursively copied.
|
||||
// Group captures a non-runnable canonical command group and a copy of its
|
||||
// relative Command child slice. Child declarations remain reusable and are not
|
||||
// recursively copied. Routing rules cannot be children; install them alongside
|
||||
// the root command tree through New or App.Register.
|
||||
func Group(name, summary string, children ...Command) Command {
|
||||
record := &commandRecord{name: name, summary: summary, children: append([]Command(nil), children...)}
|
||||
captureComposition(record)
|
||||
return Command{record: record}
|
||||
}
|
||||
|
||||
// RootGroup captures a group that may only be installed at the application root.
|
||||
// Installation rejects it below any other command, including through wrappers.
|
||||
// RootGroup captures a group that may only be installed at the application
|
||||
// root. Installation rejects it below any other command, including through
|
||||
// wrappers. Its children are canonical Commands; install routing rules at the
|
||||
// application root separately.
|
||||
func RootGroup(name, summary string, children ...Command) Command {
|
||||
command := Group(name, summary, children...)
|
||||
command.record.rootOnly = true
|
||||
return command
|
||||
}
|
||||
|
||||
// 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.
|
||||
// WithError returns a new Command 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
|
||||
@@ -294,14 +311,17 @@ func WithError(command Command, err error) Command {
|
||||
return Command{record: &record}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NoCommand explicitly represents an absent optional command declaration.
|
||||
// Installation skips it, but reports errors attached to it; a zero Command is
|
||||
// invalid and is not an absence marker. Routing rules have no absence marker.
|
||||
func NoCommand() Command { return Command{record: &commandRecord{absent: true}} }
|
||||
|
||||
// Alias captures a command-path alias from path to target. Paths are
|
||||
// whitespace-separated sequences of command names; construction issues are
|
||||
// retained for New or App.Register to report.
|
||||
// whitespace-separated sequences of command names relative to the application
|
||||
// root. The target must resolve to a canonical command or group; aliases do not
|
||||
// add operands or transform flag values. Construction issues are retained for
|
||||
// New or App.Register to report. Identical mappings are accepted, while
|
||||
// different targets for the same source path are installation errors.
|
||||
func Alias(path, target string) RoutingRule {
|
||||
record := &routingRuleRecord{
|
||||
kind: commandAliasRule,
|
||||
@@ -314,7 +334,10 @@ func Alias(path, target string) RoutingRule {
|
||||
}
|
||||
|
||||
// FlagAlias captures an application-wide flag spelling alias. Spellings must
|
||||
// be one long flag name or one individual short spelling.
|
||||
// be one long flag name or one individual short spelling. The mapping applies
|
||||
// wherever its canonical target flag is available and contributes nothing on
|
||||
// commands without that flag. Identical mappings are accepted; different
|
||||
// targets for the same source spelling in this scope are installation errors.
|
||||
func FlagAlias(spelling, target string) RoutingRule {
|
||||
record := &routingRuleRecord{
|
||||
kind: globalFlagAliasRule,
|
||||
@@ -327,7 +350,10 @@ func FlagAlias(spelling, target string) RoutingRule {
|
||||
}
|
||||
|
||||
// FlagAliasFor captures a flag spelling alias scoped to a canonical command
|
||||
// path.
|
||||
// path, not an alias path. The command and canonical target flag must be
|
||||
// available in the complete installation. Scoped mappings take precedence over
|
||||
// application-wide mappings with the same source spelling. Identical mappings
|
||||
// are accepted; competing targets in the same scope are installation errors.
|
||||
func FlagAliasFor(commandPath, spelling, target string) RoutingRule {
|
||||
record := &routingRuleRecord{
|
||||
kind: scopedFlagAliasRule,
|
||||
|
||||
6
doc.go
6
doc.go
@@ -1,5 +1,7 @@
|
||||
// Package commandkit provides the core instance-owned CLI dispatcher, typed
|
||||
// command declarations, input bindings, and invocation outcomes. Optional
|
||||
// integration modules provide ConfigKit and PromptKit-specific declarations;
|
||||
// command declarations, application-owned command and flag aliases, input
|
||||
// bindings, and invocation outcomes. New and App.Register accept canonical
|
||||
// Command declarations and RoutingRule declarations together. Optional
|
||||
// integration modules provide ConfigKit and PromptKit-specific commands;
|
||||
// importing those modules does not install their commands.
|
||||
package commandkit
|
||||
|
||||
68
docs/cli.md
68
docs/cli.md
@@ -83,6 +83,74 @@ Typed inputs keep supplied state separate from defaults. An explicit empty,
|
||||
false, or zero value is supplied. Help and version are available without
|
||||
constructing application command inputs.
|
||||
|
||||
## Application-owned aliases
|
||||
|
||||
Applications can install command and flag aliases alongside their canonical
|
||||
commands. Aliases route an invocation to existing behavior; they do not add
|
||||
handlers, commands, or flags to a canonical command family.
|
||||
|
||||
Command alias paths are sequences of command tokens relative to the application
|
||||
root. The executable name, flags, flag values, and operands are not part of an
|
||||
alias path. Matching uses complete tokens and chooses the longest matching
|
||||
path. A group alias preserves its remaining command tokens, and aliases can
|
||||
compose through chains. For example, `list collections` can route to
|
||||
`promptkit list collections`, while `pk` can route to the `promptkit` group.
|
||||
The target must resolve to a canonical command or group.
|
||||
|
||||
Aliases do not rewrite operands or supply arguments. In particular,
|
||||
`promptkit test KIND` remains one canonical command whose `KIND` is an operand;
|
||||
`all` is an operand value, not a child command. `smoke → promptkit test` is a
|
||||
valid shortcut because it preserves the caller's `KIND` value.
|
||||
|
||||
Flag aliases can be application-wide or scoped to a canonical command path.
|
||||
An application-wide alias is effective wherever its canonical target flag is
|
||||
available and is ignored elsewhere. A scoped alias requires its canonical
|
||||
command and target flag to be installed. The selected canonical command
|
||||
determines applicable scoped aliases, so the alias also works when that
|
||||
command is reached through another command path. A scoped mapping takes
|
||||
precedence over an application-wide mapping with the same spelling.
|
||||
|
||||
Only tokens parsed as flag names participate in flag aliasing. Values, operands,
|
||||
and tokens following `--` remain unchanged. This includes values that look like
|
||||
flags, such as `--message=--hlep`. Aliased flags use the target's canonical
|
||||
binding, conversion, default, required-value check, presence, and repetition
|
||||
behavior. Mixed spellings preserve occurrence order: singleton flags use the
|
||||
last successfully parsed occurrence, every supplied occurrence is converted,
|
||||
and repeatable flags accumulate values in order.
|
||||
|
||||
Flag aliases accept one long spelling or one individual short spelling. Short
|
||||
aliases use the canonical short-option cluster and attached-value grammar:
|
||||
|
||||
| Input | Interpretation |
|
||||
| --- | --- |
|
||||
| `-vq` | Two boolean flags, `--verbose` and `--quiet`. |
|
||||
| `-cblue` or `-c blue` | Value `blue` for a value-taking `-c` flag. |
|
||||
| `-vqcblue` | `-v`, `-q`, then `--color=blue`. |
|
||||
| `-cvq` | Value `vq` for a value-taking `-c` flag. |
|
||||
| `-v=false` | Explicit false for the boolean flag `-v`. |
|
||||
| `-c=` | An explicitly supplied empty string. |
|
||||
|
||||
Boolean flags use presence as true; an explicit boolean value requires `=`.
|
||||
The first value-taking short flag consumes the remaining cluster suffix or the
|
||||
next argument. A consumed value is never interpreted as an alias. The canonical
|
||||
short-option empty-value form `-c=` supplies an empty value, consistently with
|
||||
`--color=` and `-c ""`.
|
||||
|
||||
Help reached through an alias describes the canonical command's flags and
|
||||
operands while using the entered route in usage. It identifies the canonical
|
||||
target, lists applicable aliases separately, and supports global help aliases
|
||||
such as `--hlep → --help`. Help for an alias-only prefix lists its routes
|
||||
without creating a command group; the bare incomplete prefix points to that
|
||||
help. Help and alias registration do not construct command inputs or invoke
|
||||
acquisition callbacks.
|
||||
|
||||
Usage diagnostics preserve the command path and flag spelling the caller used.
|
||||
When a command alias resolved successfully, usage identifies its canonical
|
||||
target while retaining the entered path in the diagnostic. An unresolved route
|
||||
receives no invented canonical label. A flag conversion error identifies the
|
||||
entered flag spelling and the failing occurrence while preserving the original
|
||||
cause.
|
||||
|
||||
## Configuration scopes
|
||||
|
||||
An application installs the declaration returned by
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Consumer guide
|
||||
|
||||
CommandKit is distributed as three Go modules. Start with the core and add an
|
||||
integration module only when the application uses that library. Each module
|
||||
returns core `commandkit.Command` declarations, which the application installs
|
||||
through `commandkit.New` or `App.Register`.
|
||||
integration module only when the application uses that library. Core and
|
||||
integration command factories return canonical `commandkit.Command` values.
|
||||
Applications may install those alongside application-owned `RoutingRule`
|
||||
declarations through `commandkit.New` or `App.Register`; routing rules are
|
||||
installed at the application root, not as group children.
|
||||
|
||||
## Module selection
|
||||
|
||||
@@ -83,6 +85,45 @@ values convert before input construction. A command's `NewInput` creates input
|
||||
only when execution reaches it; help does not construct caller input or run
|
||||
provider callbacks.
|
||||
|
||||
## Application-owned aliases
|
||||
|
||||
Pass commands and aliases together as declarations. Integration factories can
|
||||
be called directly in the installation list, and command-scoped flag aliases
|
||||
name the canonical command path:
|
||||
|
||||
```go
|
||||
app, err := commandkit.New(
|
||||
identity,
|
||||
ckprompt.Command(suite),
|
||||
commandkit.Alias("pk", "promptkit"),
|
||||
commandkit.FlagAliasFor("promptkit show prompt", "--fmt", "--format"),
|
||||
)
|
||||
```
|
||||
|
||||
For a reusable collection, use `[]commandkit.Declaration`. Go does not expand a
|
||||
`[]commandkit.Command` into `...commandkit.Declaration`, so convert command-only
|
||||
slices when composing them with routing rules:
|
||||
|
||||
```go
|
||||
commands := []commandkit.Command{ckprompt.Command(suite)}
|
||||
declarations := make([]commandkit.Declaration, 0, len(commands)+1)
|
||||
for _, command := range commands {
|
||||
declarations = append(declarations, command)
|
||||
}
|
||||
declarations = append(declarations, commandkit.Alias("pk", "promptkit"))
|
||||
app, err := commandkit.New(identity, declarations...)
|
||||
```
|
||||
|
||||
New and Register validate each supplied batch before publishing its commands
|
||||
and routing rules. Factories capture their inputs eagerly; malformed or
|
||||
conflicting rules are reported at installation. Identical rules are safe to
|
||||
contribute from reusable helpers. The [core example](../../examples/core) and
|
||||
[composed consumer](../../integrations/ckprompt/examples/composed) show complete
|
||||
maintained wiring with ordinary command behavior alongside aliases. The
|
||||
[application-owned aliases roadmap](../roadmap/aliases.md) records the routing
|
||||
contract; the [CLI reference](../cli.md#application-owned-aliases) describes
|
||||
operator-visible behavior.
|
||||
|
||||
## ConfigKit scopes
|
||||
|
||||
For an application with one ordinary app configuration loader,
|
||||
|
||||
@@ -11,6 +11,12 @@ The [README](../README.md) provides project orientation; the
|
||||
[documentation policy](policy/documentation.md#canonical-ownership) assigns
|
||||
canonical documentation owners.
|
||||
|
||||
While application-owned alias work is active, use its
|
||||
[feature roadmap](roadmap/aliases.md), [implementation sequence](roadmap/implementation.md),
|
||||
and accepted [ADR 0013](adr/0013-application-alias-routing.md) for scope,
|
||||
progress, and architectural decisions. Keep deferred capabilities in
|
||||
[deferred work](roadmap/deferred.md).
|
||||
|
||||
## Initial orientation
|
||||
|
||||
1. Inspect the worktree and preserve unrelated staged and unstaged changes.
|
||||
@@ -47,6 +53,7 @@ canonical documentation owners.
|
||||
| Task | Read |
|
||||
| --- | --- |
|
||||
| Implemented CLI behavior | [CLI reference](cli.md) |
|
||||
| Application-owned aliases | [Feature roadmap](roadmap/aliases.md), [implementation plan](roadmap/implementation.md), and [ADR 0013](adr/0013-application-alias-routing.md) while this work is active |
|
||||
| Public API usage and standard-suite wiring | [Consumer guide](consumers/guide.md), [ckconfig package](../integrations/ckconfig/doc.go), [ckprompt package](../integrations/ckprompt/doc.go), and applicable ADRs |
|
||||
| Dispatcher, registration, or typed inputs | [Command declarations](../command.go), [bindings](../binding.go), [invocation](../execute.go), and [ADR 0001](adr/0001-command-dispatch-and-inputs.md), refined by [ADR 0011](adr/0011-captured-declarations-and-installation.md) |
|
||||
| Backend integration | [Internal overview](internal/overview.md), [adapter implementation](../internal/cobra/parse.go), and [ADR 0002](adr/0002-cobra-backend.md) |
|
||||
|
||||
@@ -8,18 +8,30 @@ this page inventories the implemented owners.
|
||||
|
||||
## Root `commandkit`
|
||||
|
||||
The root facade owns captured command declarations, binding conversion,
|
||||
invocation coordination, the per-App registry, standard help/version commands,
|
||||
and outcome/diagnostic delivery. Its dependency graph has no ConfigKit or
|
||||
PromptKit integration dependency. Applications provide typed callbacks and
|
||||
choose when to install declarations.
|
||||
The root facade owns captured canonical command declarations, application-owned
|
||||
routing rules, binding conversion, invocation coordination, the per-App
|
||||
registries, standard help/version commands, and outcome/diagnostic delivery.
|
||||
Its dependency graph has no ConfigKit or PromptKit integration dependency.
|
||||
Applications provide typed callbacks and install routing rules alongside the
|
||||
complete canonical command tree through the same batch API.
|
||||
|
||||
The shared command compiler prepares supplied values before constructing input.
|
||||
The batch installer validates retained issues, placement, and collisions before
|
||||
mutating the registry. Each invocation uses one routing snapshot and backend
|
||||
session; a successful registration invalidates the snapshot for a later
|
||||
invocation. The root package owns app input and callback execution, not provider
|
||||
configuration semantics.
|
||||
Canonical commands own handlers and parsing/help metadata; routing rules resolve
|
||||
entered command paths and flag spellings to those canonical records without
|
||||
adding command nodes or handlers. The shared command compiler prepares supplied
|
||||
values before constructing input. The batch installer validates retained
|
||||
issues, placement, and collisions across both registries before publishing
|
||||
either. Each invocation uses one routing snapshot and backend session; a
|
||||
successful registration invalidates the snapshot for a later invocation. The
|
||||
root package owns app input and callback execution, not provider configuration
|
||||
semantics.
|
||||
|
||||
## `internal/alias` and `internal/commandpath`
|
||||
|
||||
`internal/commandpath` provides shared path parsing and token operations used by
|
||||
declaration capture, routing, and backend selection. `internal/alias` compiles
|
||||
application routing rules, resolves command prefixes while retaining token
|
||||
provenance, and validates command-route termination. Neither package owns
|
||||
handlers, application factories, or backend types.
|
||||
|
||||
## `internal/commandmeta`
|
||||
|
||||
|
||||
@@ -83,18 +83,24 @@ describes the outcome and delivery model.
|
||||
|
||||
Use explicit instance construction and composable command registration, not
|
||||
package-global or import-time registries. Applications and integrations supply
|
||||
the same captured command declarations through the core installation API.
|
||||
captured canonical command declarations through the core installation API.
|
||||
Declaration factories capture metadata, bindings, and callback references eagerly;
|
||||
construction errors remain attached for installation to report. Capture the
|
||||
metadata collections needed to keep later edits to a source declaration from
|
||||
changing a returned command. Application callback objects retain their ownership.
|
||||
One definition supplies routing, parsing, and help metadata.
|
||||
Canonical command declarations own handlers, parsing metadata, and help
|
||||
metadata. Applications may provide separate routing rules in the same
|
||||
installation batch; these rules resolve invocations to canonical commands and
|
||||
do not add command nodes, handlers, or flags.
|
||||
|
||||
Validate each installation batch before mutating the instance registry. A failed
|
||||
construction yields no usable application; a failed later registration leaves the
|
||||
existing registry intact. Separate successful registration calls are not one
|
||||
transaction. Duplicate paths and attempts to replace reserved commands report
|
||||
errors rather than letting registration order select a winner.
|
||||
transaction. Duplicate canonical paths and attempts to replace reserved commands
|
||||
report errors rather than letting registration order select a winner. Identical
|
||||
routing rules are idempotent; competing targets for the same source and scope
|
||||
report an error. Command-scoped flag routing refers to an exact canonical
|
||||
command path.
|
||||
|
||||
Explicit absent-command declarations contribute no commands, help entries, or
|
||||
namespace claims; attached errors are reported before skipping absence. An invalid
|
||||
|
||||
@@ -694,6 +694,15 @@ all newly documented alias commands also ran successfully.
|
||||
canonical owner; no future alias APIs are described as existing before their
|
||||
implementation is present. Prose checks and relevant examples agree.
|
||||
|
||||
**Completed:** GoDoc now distinguishes canonical `Command` declarations from
|
||||
root-installed routing rules and documents captured errors, invalid nil/zero
|
||||
values, idempotent duplicates, canonical flag scopes, and invocation paths. The
|
||||
CLI reference, consumer guide, maintained example READMEs, internal overview,
|
||||
architecture policy, and active developer navigation describe the implemented
|
||||
contracts and integration wiring. Local Markdown links and fragments resolved;
|
||||
`git diff --check -- '*.md' COPYRIGHT` and the cached equivalent passed. The
|
||||
deferred-work record and accepted ADR were left unchanged.
|
||||
|
||||
## Stage 16: Record compatibility impact for the next core release
|
||||
|
||||
**Work**
|
||||
|
||||
@@ -16,6 +16,15 @@ alias. Its declaration slice mixes the canonical group and routing rules as
|
||||
`Invocation.CanonicalPath()` so the alternate route and its canonical target
|
||||
are visible in the output.
|
||||
|
||||
Integration factories also return `commandkit.Command` and can be passed
|
||||
directly to `New` beside `commandkit.Alias` or flag-alias declarations. For a
|
||||
command-only `[]commandkit.Command`, convert its elements into a
|
||||
`[]commandkit.Declaration` before appending routing rules; Go cannot expand the
|
||||
command slice as `...commandkit.Declaration`. The
|
||||
[consumer guide](../../docs/consumers/guide.md#application-owned-aliases)
|
||||
shows both forms, and the [composed consumer](../../integrations/ckprompt/examples/composed)
|
||||
is the maintained integration example.
|
||||
|
||||
These aliases use the current local CommandKit source. Published CommandKit
|
||||
v0.2.0 does not include alias declarations; consumers can use them after the
|
||||
next core release. Repository contributors can run its test with
|
||||
|
||||
15
identity.go
15
identity.go
@@ -28,7 +28,9 @@ type Streams struct {
|
||||
}
|
||||
|
||||
// Invocation provides execution context and output streams to a command
|
||||
// handler.
|
||||
// handler. For command aliases, EnteredPath and CanonicalPath expose the route
|
||||
// the caller used and the selected canonical command path. Both omit the
|
||||
// executable name, flags, and operands.
|
||||
type Invocation struct {
|
||||
// Context carries caller cancellation and request-scoped values.
|
||||
Context context.Context
|
||||
@@ -39,10 +41,13 @@ type Invocation struct {
|
||||
canonicalPath string
|
||||
}
|
||||
|
||||
// EnteredPath returns the command path used to invoke the selected command.
|
||||
// It is empty for an Invocation that was not created by command execution.
|
||||
// EnteredPath returns the command path used to invoke the selected command,
|
||||
// excluding the executable name, flags, and operands. It is empty for an
|
||||
// Invocation that was not created by command execution.
|
||||
func (inv Invocation) EnteredPath() string { return inv.enteredPath }
|
||||
|
||||
// CanonicalPath returns the selected command's canonical path.
|
||||
// It is empty for an Invocation that was not created by command execution.
|
||||
// CanonicalPath returns the selected command's canonical path after resolving
|
||||
// aliases, excluding the executable name, flags, and operands. It equals
|
||||
// EnteredPath for a direct canonical invocation and is empty for an Invocation
|
||||
// that was not created by command execution.
|
||||
func (inv Invocation) CanonicalPath() string { return inv.canonicalPath }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Package ckconfig provides CommandKit's optional ConfigKit integration. Its
|
||||
// declarations install the standard config command family through the core
|
||||
// commandkit package. Source reports preserve ConfigKit's destination,
|
||||
// placement, and version-check evidence; importing ckconfig alone installs no
|
||||
// commands.
|
||||
// canonical Command declaration installs the standard config command family
|
||||
// through the core commandkit package. Applications can install CommandKit
|
||||
// RoutingRule declarations alongside it through commandkit.New or
|
||||
// App.Register. Source reports preserve ConfigKit's destination, placement,
|
||||
// and version-check evidence; importing ckconfig alone installs no commands.
|
||||
package ckconfig
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Package ckprompt provides optional PromptKit configuration comparison,
|
||||
// prompt catalogs, named inspections, requirements discovery and validation,
|
||||
// and native smoke testing for CommandKit. Importing ckprompt installs neither
|
||||
// family; callers compose its declarations with core and ckconfig explicitly.
|
||||
// and native smoke testing for CommandKit. Its command factories return
|
||||
// canonical commandkit.Command declarations. Applications can install
|
||||
// commandkit.RoutingRule aliases alongside them through commandkit.New or
|
||||
// App.Register. Importing ckprompt installs neither family; callers compose its
|
||||
// declarations with core and ckconfig explicitly.
|
||||
package ckprompt
|
||||
|
||||
@@ -40,6 +40,14 @@ shortens the PromptKit group. `--fmt` is scoped to named prompt inspection and
|
||||
`--hlep` is available globally. The `smoke` shortcut retains the canonical
|
||||
`promptkit test KIND` operand, including the special `all` aggregate.
|
||||
|
||||
The composition calls `ckconfig.Command(suite)` and `ckprompt.Command(definitions)`
|
||||
directly in a `[]commandkit.Declaration` with root-installed routing rules.
|
||||
Group children remain canonical `Command` values. For command-only slices,
|
||||
convert each `Command` to `Declaration` before appending aliases. The
|
||||
[consumer guide](../../../../docs/consumers/guide.md#application-owned-aliases)
|
||||
includes minimal direct-call and slice-conversion examples; this README documents
|
||||
the maintained complete consumer.
|
||||
|
||||
The sources and session store are small in-memory fixtures. `--campaign` is a
|
||||
typed selector shared by the app and PromptKit configuration scopes. Their
|
||||
`ckconfig.Suite[*inspectionInput, *runCache]` uses `NewInput` to initialize each
|
||||
|
||||
11
registry.go
11
registry.go
@@ -9,10 +9,13 @@ import (
|
||||
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
||||
)
|
||||
|
||||
// Register adds a batch of declarations to the application. The complete batch
|
||||
// is validated before registry mutation; on error the registry and its derived
|
||||
// command metadata remain unchanged. A successful nonempty batch becomes
|
||||
// visible to later invocations. Declarations remain reusable.
|
||||
// Register adds a batch of canonical commands and routing rules to the
|
||||
// application. The complete batch is validated before registry mutation; on
|
||||
// error the registry and its derived command metadata remain unchanged. A
|
||||
// successful nonempty batch becomes visible to later invocations. Declarations
|
||||
// remain reusable. Identical duplicate routing mappings are accepted, while
|
||||
// competing targets for the same source are errors. Nil and zero declarations
|
||||
// are invalid; use NoCommand for an intentionally absent optional command.
|
||||
func (a *App) Register(declarations ...Declaration) error {
|
||||
return a.installBatch(declarations...)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user