63 lines
2.2 KiB
Go
63 lines
2.2 KiB
Go
package commandkit
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"gitea.maximumdirect.net/eric/CommandKit/internal/alias"
|
|
commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
|
|
)
|
|
|
|
// App owns one command registry and its application identity. Each App has an
|
|
// independent registry; command declarations may be reused across Apps.
|
|
type App struct {
|
|
identity Identity
|
|
commands map[string]*commandNode
|
|
routingRules []RoutingRule
|
|
aliases *alias.Resolver
|
|
flagAliases map[string]resolvedFlagAliases
|
|
discoveryFlags map[string]resolvedFlagAliases
|
|
snapshot *routingSnapshot
|
|
}
|
|
|
|
type routingSnapshot struct {
|
|
metadata *commandmeta.Command
|
|
runners map[commandmeta.Key]commandPayload
|
|
aliases *alias.Resolver
|
|
canonical map[string]*canonicalNode
|
|
commandAliases []commandmeta.CommandAlias
|
|
flagAliases map[string]resolvedFlagAliases
|
|
discoveryFlags map[string]resolvedFlagAliases
|
|
}
|
|
|
|
type commandNode struct {
|
|
command Command
|
|
}
|
|
|
|
// 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, 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")
|
|
}
|
|
|
|
app := &App{identity: identity, commands: make(map[string]*commandNode)}
|
|
builtins := app.builtinCommands()
|
|
all := make([]Declaration, 0, len(builtins)+len(declarations))
|
|
all = append(all, builtins...)
|
|
all = append(all, declarations...)
|
|
if err := app.installBatch(all...); err != nil {
|
|
return nil, err
|
|
}
|
|
return app, nil
|
|
}
|