-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregistry.go
More file actions
78 lines (69 loc) · 2.34 KB
/
Copy pathregistry.go
File metadata and controls
78 lines (69 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package shellshape
import "sort"
// HandlerOptions configures how a command is normalized.
type HandlerOptions struct {
// HasSubcommands indicates the second positional token is a subcommand
// (e.g. "docker run", "git commit"). The subcommand is extracted and
// passed to the handler before remaining tokens.
HasSubcommands bool
// Subcommands, when non-nil, restricts subcommand extraction to only
// tokens in this set. Useful for commands like `bun` that can be invoked
// either with a subcommand (`bun run`, `bun test`) or as a script runner
// (`bun /tmp/script.ts`). Only applies when HasSubcommands is true.
Subcommands map[string]bool
}
var handlers = map[string]HandlerFunc{}
var handlerOptions = map[string]HandlerOptions{}
// Register adds a command handler to the registry.
// If fn is nil the command is registered for its options only (e.g. subcommand
// detection) without a per-command handler.
func Register(name string, fn HandlerFunc, opts ...HandlerOptions) {
if fn != nil {
handlers[name] = fn
}
if len(opts) > 0 {
handlerOptions[name] = opts[0]
}
}
func hasSubcommands(exe string) bool {
return handlerOptions[exe].HasSubcommands
}
// isValidSubcommand reports whether tok should be extracted as the
// subcommand for exe. When a handler declares a Subcommands whitelist,
// only tokens in that set qualify; otherwise any token (including global
// flags) is accepted for backwards compatibility. Handlers that want to
// handle leading global flags themselves can use the whitelist to opt out.
func isValidSubcommand(exe, tok string) bool {
if set := handlerOptions[exe].Subcommands; set != nil {
return set[tok]
}
return true
}
// RegisteredHandlers returns a sorted list of all registered command names.
func RegisteredHandlers() []string {
seen := make(map[string]bool)
for name := range handlers {
seen[name] = true
}
for name := range handlerOptions {
seen[name] = true
}
names := make([]string, 0, len(seen))
for name := range seen {
names = append(names, name)
}
sort.Strings(names)
return names
}
func init() {
// Commands that need subcommand detection but have no per-command handler.
for _, name := range []string{
"git", "cargo", "gcloud", "az",
"pip", "pip3", "uv", "poetry",
"snap",
"launchctl",
"pulumi", "ollama", "lms",
} {
Register(name, nil, HandlerOptions{HasSubcommands: true})
}
}