From 0f0a7daa87bf8bfad155d0f195b4e95f02237830 Mon Sep 17 00:00:00 2001 From: dheeraj12347 Date: Fri, 11 Sep 2026 17:11:40 +0000 Subject: [PATCH 1/2] Fix version parameter autocompletion --- cli/completer.go | 30 ++++++++++++++--- cli/completer_test.go | 78 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/cli/completer.go b/cli/completer.go index 9547f5a..7061975 100644 --- a/cli/completer.go +++ b/cli/completer.go @@ -113,7 +113,7 @@ type argOption struct { Detail string } -func buildArgOptions(response map[string]interface{}, hasID bool) []argOption { +func buildArgOptions(response map[string]interface{}, hasID bool, valueField string) []argOption { argOptions := []argOption{} for _, v := range response { switch obj := v.(type) { @@ -164,9 +164,18 @@ func buildArgOptions(response map[string]interface{}, hasID bool) []argOption { opt.Detail = detail } } else { - opt.Value = name + if valueField != "" { + if value, ok := resource[valueField].(string); ok { + opt.Value = value + } + } + + if len(opt.Value) == 0 { + opt.Value = name + } + opt.Detail = detail - if len(name) == 0 { + if len(opt.Value) == 0 { opt.Value = detail } } @@ -229,6 +238,14 @@ func findAutocompleteAPI(arg *config.APIArg, apiFound *config.API, apiMap map[st return nil } + if apiFound.Verb == "list" && strings.TrimSuffix(arg.Name, "=") == "version" { + for _, responseKey := range apiFound.ResponseKeys { + if responseKey == "version" { + return apiFound + } + } + } + var autocompleteAPI *config.API argName := strings.Replace(arg.Name, "=", "", -1) relatedNoun := argName @@ -479,7 +496,12 @@ func (t *autoCompleter) Do(line []rune, pos int) (options [][]rune, offset int) t.Config.StopSpinner(spinner) hasID := strings.HasSuffix(arg.Name, "id=") || strings.HasSuffix(arg.Name, "ids=") || autocompleteAPI.Name == "listUsageTypes" - argOptions = buildArgOptions(response, hasID) + valueField := "" + if apiFound == autocompleteAPI { + valueField = strings.TrimSuffix(arg.Name, "=") + } + + argOptions = buildArgOptions(response, hasID, valueField) } filteredOptions := []argOption{} diff --git a/cli/completer_test.go b/cli/completer_test.go index 0aa73df..9031c82 100644 --- a/cli/completer_test.go +++ b/cli/completer_test.go @@ -221,3 +221,81 @@ func TestFindAutocompleteAPIHeuristicWinsOverRelated(t *testing.T) { t.Fatalf("expected listProjects, got %s", result.Name) } } + +func TestFindAutocompleteAPIVersionUsesCurrentListAPI(t *testing.T) { + tests := []struct { + name string + apiFound *config.API + }{ + { + name: "listHosts", + apiFound: &config.API{ + Name: "listHosts", + Verb: "list", + Noun: "hosts", + ResponseKeys: []string{ + "id", + "name", + "version", + }, + }, + }, + { + name: "listRouters", + apiFound: &config.API{ + Name: "listRouters", + Verb: "list", + Noun: "routers", + ResponseKeys: []string{ + "name", + "version", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + arg := &config.APIArg{ + Name: "version=", + } + + apiMap := map[string][]*config.API{ + "list": { + { + Name: "listKubernetesSupportedVersions", + Noun: "kubernetessupportedversions", + }, + }, + } + + result := findAutocompleteAPI(arg, tt.apiFound, apiMap) + + if result != tt.apiFound { + t.Fatalf("expected %s, got %v", tt.apiFound.Name, result) + } + }) + } +} + +func TestBuildArgOptionsUsesValueField(t *testing.T) { + response := map[string]interface{}{ + "host": []interface{}{ + map[string]interface{}{ + "id": "host-id", + "name": "nvs-kvm01", + "version": "4.22.1.0", + }, + }, + } + + options := buildArgOptions(response, false, "version") + + if len(options) != 1 { + t.Fatalf("expected 1 option, got %d", len(options)) + } + + if options[0].Value != "4.22.1.0" { + t.Fatalf("expected 4.22.1.0, got %s", options[0].Value) + } +} From 7ade14b64b5705e2801b8ddf6d620fbfec62a70d Mon Sep 17 00:00:00 2001 From: dheeraj12347 Date: Fri, 18 Sep 2026 16:48:04 +0000 Subject: [PATCH 2/2] Fix version parameter autocompletion --- cli/completer.go | 10 +++++++++- cli/completer_test.go | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cli/completer.go b/cli/completer.go index 7061975..9203dcc 100644 --- a/cli/completer.go +++ b/cli/completer.go @@ -115,6 +115,7 @@ type argOption struct { func buildArgOptions(response map[string]interface{}, hasID bool, valueField string) []argOption { argOptions := []argOption{} + seenValues := make(map[string]struct{}) for _, v := range response { switch obj := v.(type) { case []interface{}: @@ -179,6 +180,13 @@ func buildArgOptions(response map[string]interface{}, hasID bool, valueField str opt.Value = detail } } + if valueField != "" { + if _, seen := seenValues[opt.Value]; seen { + continue + } + seenValues[opt.Value] = struct{}{} + } + argOptions = append(argOptions, opt) } break @@ -240,7 +248,7 @@ func findAutocompleteAPI(arg *config.APIArg, apiFound *config.API, apiMap map[st if apiFound.Verb == "list" && strings.TrimSuffix(arg.Name, "=") == "version" { for _, responseKey := range apiFound.ResponseKeys { - if responseKey == "version" { + if strings.TrimSuffix(responseKey, ",") == "version" { return apiFound } } diff --git a/cli/completer_test.go b/cli/completer_test.go index 9031c82..bb39213 100644 --- a/cli/completer_test.go +++ b/cli/completer_test.go @@ -234,9 +234,9 @@ func TestFindAutocompleteAPIVersionUsesCurrentListAPI(t *testing.T) { Verb: "list", Noun: "hosts", ResponseKeys: []string{ - "id", - "name", - "version", + "id,", + "name,", + "version,", }, }, }, @@ -247,8 +247,8 @@ func TestFindAutocompleteAPIVersionUsesCurrentListAPI(t *testing.T) { Verb: "list", Noun: "routers", ResponseKeys: []string{ - "name", - "version", + "name,", + "version,", }, }, }, @@ -280,22 +280,39 @@ func TestFindAutocompleteAPIVersionUsesCurrentListAPI(t *testing.T) { func TestBuildArgOptionsUsesValueField(t *testing.T) { response := map[string]interface{}{ - "host": []interface{}{ + "router": []interface{}{ map[string]interface{}{ - "id": "host-id", - "name": "nvs-kvm01", - "version": "4.22.1.0", + "id": "router-1", + "name": "router-1", + "version": "4.22.1.0", + "ipaddress": "10.0.0.1", + }, + map[string]interface{}{ + "id": "router-2", + "name": "router-2", + "version": "4.22.1.0", + "ipaddress": "10.0.0.2", + }, + map[string]interface{}{ + "id": "router-3", + "name": "router-3", + "version": "4.21.0.0", + "ipaddress": "10.0.0.3", }, }, } options := buildArgOptions(response, false, "version") - if len(options) != 1 { - t.Fatalf("expected 1 option, got %d", len(options)) + if len(options) != 2 { + t.Fatalf("expected 2 options, got %d", len(options)) } if options[0].Value != "4.22.1.0" { t.Fatalf("expected 4.22.1.0, got %s", options[0].Value) } + + if options[1].Value != "4.21.0.0" { + t.Fatalf("expected 4.21.0.0, got %s", options[1].Value) + } }