Add captured alias declaration types

This commit is contained in:
2026-10-19 17:23:32 +00:00
parent 854426a0c9
commit 7a4efddab8
9 changed files with 297 additions and 21 deletions

View File

@@ -1,19 +1,46 @@
package commandkit
import "fmt"
import (
"errors"
"fmt"
)
// Register adds a batch of root commands to the application. The complete batch
// 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. Command declarations remain reusable.
func (a *App) Register(commands ...Command) error {
return a.installBatch(commands...)
// visible to later invocations. Declarations remain reusable.
func (a *App) Register(declarations ...Declaration) error {
return a.installBatch(declarations...)
}
func (a *App) installBatch(commands ...Command) error {
func (a *App) installBatch(declarations ...Declaration) error {
if a == nil {
return fmt.Errorf("cannot register commands on a nil app")
}
commands := make([]Command, 0, len(declarations))
rules := make([]RoutingRule, 0)
for _, declaration := range declarations {
switch value := declaration.(type) {
case Command:
commands = append(commands, value)
case *Command:
if value == nil {
return fmt.Errorf("nil *Command declaration")
}
commands = append(commands, *value)
case RoutingRule:
rules = append(rules, value)
case *RoutingRule:
if value == nil {
return fmt.Errorf("nil *RoutingRule declaration")
}
rules = append(rules, *value)
case nil:
return fmt.Errorf("nil declaration")
default:
return fmt.Errorf("unsupported declaration type %T", declaration)
}
}
pending := make(map[string]*commandNode, len(commands))
for _, command := range commands {
@@ -32,7 +59,15 @@ func (a *App) installBatch(commands ...Command) error {
}
pending[name] = &commandNode{command: command}
}
if len(pending) == 0 {
for _, rule := range rules {
if rule.record == nil {
return fmt.Errorf("invalid zero routing rule declaration")
}
if len(rule.record.issues) > 0 {
return fmt.Errorf("routing rule: %w", errors.Join(rule.record.issues...))
}
}
if len(pending) == 0 && len(rules) == 0 {
return nil
}
if a.commands == nil {
@@ -41,6 +76,9 @@ func (a *App) installBatch(commands ...Command) error {
for name, node := range pending {
a.commands[name] = node
}
a.snapshot = nil
a.routingRules = append(a.routingRules, rules...)
if len(pending) > 0 {
a.snapshot = nil
}
return nil
}