Files
commandkit/parser.go

67 lines
2.0 KiB
Go

package commandkit
import (
"sort"
internalcobra "gitea.maximumdirect.net/eric/CommandKit/internal/cobra"
commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
)
func (a *App) parse(args []string, options commandmeta.ParseOptions) commandmeta.Result {
if a == nil {
return commandmeta.Result{Failure: &commandmeta.Failure{Message: "cannot parse commands on a nil app"}}
}
return internalcobra.Parse(a.routeSnapshot().metadata, args, options)
}
func (a *App) routeSnapshot() *routingSnapshot {
if a == nil {
return nil
}
if a.snapshot == nil {
a.snapshot = a.buildRoutingSnapshot()
}
return a.snapshot
}
func (a *App) buildRoutingSnapshot() *routingSnapshot {
root := &commandmeta.Command{Name: a.identity.Name}
snapshot := &routingSnapshot{metadata: root, runners: make(map[commandmeta.Key]commandPayload)}
names := make([]string, 0, len(a.commands))
for name := range a.commands {
names = append(names, name)
}
sort.Strings(names)
var key commandmeta.Key
for _, name := range names {
root.Children = append(root.Children, bridgeCommand(a.commands[name].command, snapshot, &key))
}
return snapshot
}
func bridgeCommand(command Command, snapshot *routingSnapshot, next *commandmeta.Key) *commandmeta.Command {
record := command.record
*next = *next + 1
declaration := &commandmeta.Command{
Key: *next,
Name: record.name,
Summary: record.summary,
Description: record.description,
}
if record.payload != nil {
snapshot.runners[declaration.Key] = record.payload
declaration.Runnable = record.payload.hasRun()
declaration.Flags = record.payload.bridgeFlags()
declaration.Arguments = record.payload.bridgeArguments()
}
children := append([]Command(nil), record.children...)
sort.Slice(children, func(i, j int) bool { return children[i].record.name < children[j].record.name })
for _, child := range children {
if child.record == nil || child.record.absent {
continue
}
declaration.Children = append(declaration.Children, bridgeCommand(child, snapshot, next))
}
return declaration
}