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 }