-
Notifications
You must be signed in to change notification settings - Fork 348
Expand file tree
/
Copy pathcompletion.go
More file actions
134 lines (111 loc) · 3.47 KB
/
completion.go
File metadata and controls
134 lines (111 loc) · 3.47 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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package root
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"github.com/docker/docker-agent/pkg/config"
"github.com/docker/docker-agent/pkg/userconfig"
)
func completeRunExec(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
switch len(args) {
case 0:
return completeAlias(toComplete)
case 1:
return completeMessage(cmd, args, toComplete)
default:
return nil, cobra.ShellCompDirectiveNoFileComp
}
}
func completeAlias(toComplete string) ([]string, cobra.ShellCompDirective) {
if strings.HasPrefix(toComplete, "/") || strings.HasPrefix(toComplete, ".") {
return completeAgentFilename(toComplete)
}
var candidates []string
// Add matching built-in agent names
for _, name := range config.BuiltinAgentNames() {
if strings.HasPrefix(name, toComplete) {
candidates = append(candidates, name+"\tbuilt-in agent")
}
}
// Add matching aliases
cfg, err := userconfig.Load()
if err == nil {
for k, v := range cfg.Aliases {
if strings.HasPrefix(k, toComplete) {
candidates = append(candidates, k+"\t"+v.Path)
}
}
}
// Also add matching YAML files from the current directory
fileCandidates, _ := completeAgentFilename(toComplete)
candidates = append(candidates, fileCandidates...)
return candidates, cobra.ShellCompDirectiveNoFileComp
}
func completeMessage(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !strings.HasPrefix(toComplete, "/") {
return nil, cobra.ShellCompDirectiveNoFileComp
}
agentSource, err := config.Resolve(args[0], nil)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
cfg, err := config.Load(context.Background(), agentSource)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
agent, _ := cmd.Flags().GetString("agent")
if agent == "" {
if len(cfg.Agents) == 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
// Mirror team.DefaultAgent: prefer "root" when present, otherwise
// the first agent declared. This keeps shell completion in sync
// with the agent the runtime would actually run.
agent = cfg.Agents[0].Name
if _, hasRoot := cfg.Agents.Lookup("root"); hasRoot {
agent = "root"
}
}
agentCfg, found := cfg.Agents.Lookup(agent)
if !found {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var candidates []string
for k, v := range agentCfg.Commands {
if strings.HasPrefix("/"+k, toComplete) {
candidates = append(candidates, "/"+k+"\t"+v.DisplayText())
}
}
return candidates, cobra.ShellCompDirectiveNoFileComp
}
func completeAgentFilename(toComplete string) ([]string, cobra.ShellCompDirective) {
dirPrefix, base := filepath.Split(toComplete)
dirToRead := dirPrefix
if dirToRead == "" {
dirToRead = "."
}
entries, err := os.ReadDir(dirToRead)
if err != nil {
return nil, cobra.ShellCompDirectiveNoFileComp
}
var out []string
for _, e := range entries {
name := e.Name()
if !strings.HasPrefix(name, base) {
continue
}
switch {
case e.IsDir():
out = append(out, dirPrefix+name+string(filepath.Separator))
case strings.EqualFold(filepath.Ext(name), ".yaml"), strings.EqualFold(filepath.Ext(name), ".yml"):
out = append(out, dirPrefix+name)
}
}
// Don't add space after single directory completion
if len(out) == 1 && strings.HasSuffix(out[0], string(filepath.Separator)) {
return out, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace
}
return out, cobra.ShellCompDirectiveNoFileComp
}