Files
commandkit/app.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
}