Skip to content

Commit 622e83b

Browse files
committed
Use Related metadata only when the noun heuristics find nothing
Checking Related before the heuristics changed 47 existing completions against the bundled API cache, many of them wrong: registerIso projectid resolved to listProjectAccounts instead of listProjects, acquirePodIpAddress podid to listZones instead of listPods, and executeWebhookDelivery webhookid to listWebhookDeliveries instead of listWebhooks. The loose Related match picks the first list API in the array, whatever its noun. Move the Related lookup after the noun heuristics and run it only when they found no API. That keeps all 142 new completions Related metadata adds and leaves every existing completion untouched. Add a test pinning the ordering.
1 parent 4513eca commit 622e83b

2 files changed

Lines changed: 57 additions & 27 deletions

File tree

cli/completer.go

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -269,33 +269,6 @@ func findAutocompleteAPI(arg *config.APIArg, apiFound *config.API, apiMap map[st
269269
relatedNoun = pluralizeNoun(base)
270270
}
271271

272-
// Prefer authoritative Related metadata: a list API whose noun matches
273-
// the related noun derived above.
274-
for _, relatedAPI := range arg.Related {
275-
if !strings.HasPrefix(strings.ToLower(relatedAPI), "list") {
276-
continue
277-
}
278-
for _, listAPI := range apiMap["list"] {
279-
if strings.EqualFold(listAPI.Name, relatedAPI) && strings.EqualFold(listAPI.Noun, relatedNoun) {
280-
config.Debug("Autocomplete: API found using Related metadata: ", listAPI.Name)
281-
return listAPI
282-
}
283-
}
284-
}
285-
286-
// Fall back to any list API named in the Related metadata.
287-
for _, relatedAPI := range arg.Related {
288-
if !strings.HasPrefix(strings.ToLower(relatedAPI), "list") {
289-
continue
290-
}
291-
for _, listAPI := range apiMap["list"] {
292-
if strings.EqualFold(listAPI.Name, relatedAPI) {
293-
config.Debug("Autocomplete: API found using Related metadata fallback: ", listAPI.Name)
294-
return listAPI
295-
}
296-
}
297-
}
298-
299272
config.Debug("Possible related noun for the arg: ", relatedNoun, " and type: ", arg.Type)
300273
autocompleteAPI = findAPI(apiMap, relatedNoun)
301274

@@ -314,6 +287,22 @@ func findAutocompleteAPI(arg *config.APIArg, apiFound *config.API, apiMap map[st
314287
relatedNoun = relatedNoun[:len(relatedNoun)-1]
315288
}
316289

290+
// Prefer the API's own Related metadata when the noun heuristics found
291+
// nothing, so entity-reference args still get completions.
292+
if autocompleteAPI == nil {
293+
for _, relatedAPI := range arg.Related {
294+
if !strings.HasPrefix(strings.ToLower(relatedAPI), "list") {
295+
continue
296+
}
297+
for _, listAPI := range apiMap["list"] {
298+
if strings.EqualFold(listAPI.Name, relatedAPI) {
299+
config.Debug("Autocomplete: API found using Related metadata: ", listAPI.Name)
300+
return listAPI
301+
}
302+
}
303+
}
304+
}
305+
317306
// Heuristic: find any list API that contains the arg name
318307
if autocompleteAPI == nil {
319308
config.Debug("Finding possible API that have: ", argName, " related APIs: ", arg.Related)

cli/completer_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,44 @@ func TestFindAutocompleteAPIMapTypeReturnsNil(t *testing.T) {
163163
t.Fatalf("expected nil, got %v", result)
164164
}
165165
}
166+
167+
func TestFindAutocompleteAPIHeuristicWinsOverRelated(t *testing.T) {
168+
// registerIso's projectid arg lists many related APIs; the noun heuristic
169+
// must keep winning so the completion stays listProjects.
170+
arg := &config.APIArg{
171+
Name: "projectid=",
172+
Related: []string{
173+
"listProjectAccounts",
174+
"listProjects",
175+
},
176+
}
177+
178+
apiFound := &config.API{
179+
Name: "registerIso",
180+
Verb: "register",
181+
Noun: "iso",
182+
}
183+
184+
apiMap := map[string][]*config.API{
185+
"list": {
186+
{
187+
Name: "listProjectAccounts",
188+
Noun: "projectaccounts",
189+
},
190+
{
191+
Name: "listProjects",
192+
Noun: "projects",
193+
},
194+
},
195+
}
196+
197+
result := findAutocompleteAPI(arg, apiFound, apiMap)
198+
199+
if result == nil {
200+
t.Fatal("expected API, got nil")
201+
}
202+
203+
if result.Name != "listProjects" {
204+
t.Fatalf("expected listProjects, got %s", result.Name)
205+
}
206+
}

0 commit comments

Comments
 (0)