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 len(path) == 0: result.kind = routeCanonical default: discovery, ok := findDiscoveryPath(snapshot.discoveryFlags, resolved, path) if !ok && len(snapshot.discoveryFlags) > 0 { discovery, ok = findDiscoveryPath(snapshot.discoveryFlags, snapshot.aliases.ResolutionPaths(path)...) } if ok { result.kind = routeDiscovery result.discoveryPath = discovery result.enteredPath = path.Clone() result.args = commandpath.CloneTokens(trailing) } else if trace.operandOwner != nil { result.kind = routeCanonical result.canonicalPath = trace.operandOwner.path.Clone() } else { result.enteredPath = path.Clone() } } if result.kind == routeCanonical { result.enteredPath = enteredEndpoint(path, origins, len(result.canonicalPath)) } 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, paths ...commandpath.Path) (commandpath.Path, bool) { for _, path := range paths { if _, exists := contexts[path.Key()]; len(path) > 0 && exists { return path.Clone(), true } } return nil, false }