This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git


The following commit(s) were added to refs/heads/master by this push:
     new 16db39a  cli: fix auto-completion bug
16db39a is described below

commit 16db39a464c7cd5cdf09e6eb686a055a6cf7a442
Author: Rohit Yadav <[email protected]>
AuthorDate: Tue Mar 5 16:47:21 2019 +0530

    cli: fix auto-completion bug
    
    Refactors the logic that finds the auto-completion API.
    
    Signed-off-by: Rohit Yadav <[email protected]>
---
 cli/completer.go | 114 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 71 insertions(+), 43 deletions(-)

diff --git a/cli/completer.go b/cli/completer.go
index 3c7c5b9..da3311c 100644
--- a/cli/completer.go
+++ b/cli/completer.go
@@ -149,6 +149,9 @@ func buildArgOptions(response map[string]interface{}, hasID 
bool) []argOption {
                                } else {
                                        opt.Value = name
                                        opt.Detail = detail
+                                       if len(name) == 0 {
+                                               opt.Value = detail
+                                       }
                                }
                                argOptions = append(argOptions, opt)
                        }
@@ -177,6 +180,73 @@ func doInternal(line []rune, pos int, lineLen int, argName 
[]rune) (newLine [][]
        return
 }
 
+func findAutocompleteAPI(arg *config.APIArg, apiFound *config.API, apiMap 
map[string][]*config.API) *config.API {
+       if arg.Type == "map" {
+               return nil
+       }
+
+       var autocompleteAPI *config.API
+       argName := strings.Replace(arg.Name, "=", "", -1)
+       relatedNoun := argName
+       if argName == "id" || argName == "ids" {
+               // Heuristic: user is trying to autocomplete for id/ids arg for 
a list API
+               relatedNoun = apiFound.Noun
+               if apiFound.Verb != "list" {
+                       relatedNoun += "s"
+               }
+       } else if argName == "account" {
+               // Heuristic: user is trying to autocomplete for accounts
+               relatedNoun = "accounts"
+       } else if argName == "ipaddressid" {
+               // Heuristic: user is trying to autocomplete for ip addresses
+               relatedNoun = "publicipaddresses"
+       } else {
+               // Heuristic: autocomplete for the arg for which a list<Arg 
without id/ids>s API exists
+               // For example, for zoneid arg, listZones API exists
+               cutIdx := len(argName)
+               if strings.HasSuffix(argName, "id") {
+                       cutIdx -= 2
+               } else if strings.HasSuffix(argName, "ids") {
+                       cutIdx -= 3
+               } else {
+               }
+               relatedNoun = argName[:cutIdx] + "s"
+       }
+
+       config.Debug("Possible related noun for the arg: ", relatedNoun, " and 
type: ", arg.Type)
+       for _, listAPI := range apiMap["list"] {
+               if relatedNoun == listAPI.Noun {
+                       autocompleteAPI = listAPI
+                       break
+               }
+       }
+
+       if autocompleteAPI != nil {
+               config.Debug("Autocomplete: API found using heuristics: ", 
autocompleteAPI.Name)
+       }
+
+       if strings.HasSuffix(relatedNoun, "s") {
+               relatedNoun = relatedNoun[:len(relatedNoun)-1]
+       }
+
+       // Heuristic: find any list API that contains the arg name
+       if autocompleteAPI == nil {
+               config.Debug("Finding possible API that have: ", argName, " 
related APIs: ", arg.Related)
+               possibleAPIs := []*config.API{}
+               for _, listAPI := range apiMap["list"] {
+                       if strings.Contains(listAPI.Noun, argName) {
+                               config.Debug("Found possible API: ", 
listAPI.Name)
+                               possibleAPIs = append(possibleAPIs, listAPI)
+                       }
+               }
+               if len(possibleAPIs) == 1 {
+                       autocompleteAPI = possibleAPIs[0]
+               }
+       }
+
+       return autocompleteAPI
+}
+
 type autoCompleter struct {
        Config *config.Config
 }
@@ -280,49 +350,7 @@ func (t *autoCompleter) Do(line []rune, pos int) (options 
[][]rune, offset int)
                                return
                        }
 
-                       argName := strings.Replace(arg.Name, "=", "", -1)
-                       var autocompleteAPI *config.API
-                       var relatedNoun string
-                       if argName == "id" || argName == "ids" {
-                               relatedNoun = apiFound.Noun
-                               if apiFound.Verb != "list" {
-                                       relatedNoun += "s"
-                               }
-                       } else if argName == "account" {
-                               relatedNoun = "accounts"
-                       } else {
-                               relatedNoun = 
strings.Replace(strings.Replace(argName, "ids", "", -1), "id", "", -1) + "s"
-                       }
-
-                       for _, listAPI := range apiMap["list"] {
-                               if relatedNoun == listAPI.Noun {
-                                       autocompleteAPI = listAPI
-                                       break
-                               }
-                       }
-
-                       if autocompleteAPI == nil {
-                               relatedAPIName := ""
-                               for _, name := range arg.Related {
-                                       if strings.HasPrefix(name, "list") {
-                                               if len(relatedAPIName) == 0 {
-                                                       relatedAPIName = name
-                                               }
-                                               if len(name) < 
len(relatedAPIName) {
-                                                       relatedAPIName = name
-                                               }
-                                       }
-                               }
-                               if len(relatedAPIName) > 0 {
-                                       for _, listAPI := range apiMap["list"] {
-                                               if relatedAPIName == 
listAPI.Name {
-                                                       autocompleteAPI = 
listAPI
-                                                       break
-                                               }
-                                       }
-                               }
-                       }
-
+                       autocompleteAPI := findAutocompleteAPI(arg, apiFound, 
apiMap)
                        if autocompleteAPI == nil {
                                return nil, 0
                        }

Reply via email to