package commandkit import ( "strings" "gitea.maximumdirect.net/eric/CommandKit/internal/commandpath" ) type routeKind uint8 const ( routeUnknown routeKind = iota routeCanonical routeDiscovery ) type routeResult struct { kind routeKind args []string enteredPath commandpath.Path canonicalPath commandpath.Path discoveryPath commandpath.Path } func resolveEnteredRoute(args []string, snapshot *routingSnapshot) routeResult { path, trailing := commandPathTokens(args) result := routeResult{kind: routeUnknown} if snapshot == nil { result.args = append(append([]string(nil), path...), trailing...) result.enteredPath = path.Clone() return result } resolved, origins := snapshot.aliases.ResolveWithProvenance(path) trace := traceCanonicalPath(snapshot.canonical, resolved) switch { case trace.exact != nil: result.kind = routeCanonical result.canonicalPath = trace.exact.path.Clone() case trace.operandOwner != nil: result.kind = routeCanonical result.canonicalPath = trace.operandOwner.path.Clone() } if result.kind == routeCanonical { result.enteredPath = enteredEndpoint(path, origins, len(result.canonicalPath)) } else if len(path) == 0 { result.kind = routeCanonical } else if discovery, ok := findDiscoveryPath(snapshot.discoveryFlags, path); ok && len(discovery) == len(path) { result.kind = routeDiscovery result.discoveryPath = discovery result.enteredPath = discovery.Clone() result.args = commandpath.CloneTokens(trailing) } else { result.enteredPath = path.Clone() } if result.kind != routeDiscovery { result.args = make([]string, 0, len(resolved)+len(trailing)) result.args = append(result.args, resolved...) result.args = append(result.args, trailing...) } return result } func commandPathTokens(args []string) (commandpath.Path, []string) { end := len(args) for index, token := range args { if token == "--" || (token != "-" && strings.HasPrefix(token, "-")) { end = index break } } path := make(commandpath.Path, end) copy(path, args[:end]) return path, append([]string(nil), args[end:]...) } func enteredEndpoint(path commandpath.Path, origins [][]int, canonicalLength int) commandpath.Path { inputLength := 0 for _, componentOrigins := range origins[:canonicalLength] { for _, origin := range componentOrigins { if origin+1 > inputLength { inputLength = origin + 1 } } } return path[:inputLength].Clone() } func findDiscoveryPath(contexts map[string]resolvedFlagAliases, path commandpath.Path) (commandpath.Path, bool) { for length := len(path); length > 0; length-- { prefix := path[:length] if _, exists := contexts[prefix.Key()]; exists { return prefix.Clone(), true } } return nil, false }