You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2018/04/13 22:50:15 UTC
[cloudstack-cloudmonkey] branch master updated: lint: introduce
lint and fix lint issues
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 0eb9c6b lint: introduce lint and fix lint issues
0eb9c6b is described below
commit 0eb9c6b87a56bb16efdadf6aac8376c8f1a8b19e
Author: Rohit Yadav <ro...@apache.org>
AuthorDate: Sat Apr 14 04:13:20 2018 +0530
lint: introduce lint and fix lint issues
Signed-off-by: Rohit Yadav <ro...@apache.org>
---
.travis.yml | 1 +
cli/completer.go | 55 +++++++++++++++++++++++--------------------------------
cli/exec.go | 1 +
cli/selector.go | 34 +++++++++++++++++-----------------
cli/shell.go | 10 +++++++---
cmd/api.go | 1 +
cmd/command.go | 5 +++++
cmd/network.go | 9 +++++----
cmd/request.go | 2 ++
cmd/set.go | 2 +-
config/about.go | 3 +++
config/cache.go | 33 ++++++++++++++++++++-------------
config/config.go | 34 ++++++++++++++++++----------------
config/prompt.go | 1 +
14 files changed, 105 insertions(+), 86 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 5acfcd3..412ca24 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,3 +24,4 @@ go:
script:
- make all
+ - make lint
diff --git a/cli/completer.go b/cli/completer.go
index 58ff60b..271faa1 100644
--- a/cli/completer.go
+++ b/cli/completer.go
@@ -29,29 +29,27 @@ import (
"github.com/chzyer/readline/runes"
)
-type CliCompleter struct {
+type autoCompleter struct {
Config *config.Config
}
-var completer *CliCompleter
-
-func buildApiCacheMap(apiMap map[string][]*config.Api) map[string][]*config.Api {
+func buildAPICacheMap(apiMap map[string][]*config.API) map[string][]*config.API {
for _, cmd := range cmd.AllCommands() {
verb := cmd.Name
if cmd.SubCommands != nil && len(cmd.SubCommands) > 0 {
for _, scmd := range cmd.SubCommands {
- dummyApi := &config.Api{
+ dummyAPI := &config.API{
Name: scmd,
Verb: verb,
}
- apiMap[verb] = append(apiMap[verb], dummyApi)
+ apiMap[verb] = append(apiMap[verb], dummyAPI)
}
} else {
- dummyApi := &config.Api{
+ dummyAPI := &config.API{
Name: "",
Verb: verb,
}
- apiMap[verb] = append(apiMap[verb], dummyApi)
+ apiMap[verb] = append(apiMap[verb], dummyAPI)
}
}
return apiMap
@@ -87,9 +85,9 @@ func doInternal(line []rune, pos int, lineLen int, argName []rune) (newLine [][]
return
}
-func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
+func (t *autoCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
- apiMap := buildApiCacheMap(t.Config.GetApiVerbMap())
+ apiMap := buildAPICacheMap(t.Config.GetAPIVerbMap())
var verbs []string
for verb := range apiMap {
@@ -138,7 +136,7 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
}
// Find API
- var apiFound *config.Api
+ var apiFound *config.API
for _, api := range apiMap[verbFound] {
if api.Noun == nounFound {
apiFound = api
@@ -165,7 +163,7 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
return
}
- var autocompleteApi *config.Api
+ var autocompleteAPI *config.API
var relatedNoun string
if arg.Name == "id" || arg.Name == "ids" {
relatedNoun = apiFound.Noun
@@ -179,23 +177,23 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
}
for _, related := range apiMap["list"] {
if relatedNoun == related.Noun {
- autocompleteApi = related
+ autocompleteAPI = related
break
}
}
- if autocompleteApi == nil {
+ if autocompleteAPI == nil {
return nil, 0
}
- r := cmd.NewRequest(nil, shellConfig, nil, nil)
- autocompleteApiArgs := []string{"listall=true"}
- if autocompleteApi.Noun == "templates" {
- autocompleteApiArgs = append(autocompleteApiArgs, "templatefilter=all")
+ r := cmd.NewRequest(nil, completer.Config, nil, nil)
+ autocompleteAPIArgs := []string{"listall=true"}
+ if autocompleteAPI.Noun == "templates" {
+ autocompleteAPIArgs = append(autocompleteAPIArgs, "templatefilter=all")
}
- response, _ := cmd.NewAPIRequest(r, autocompleteApi.Name, autocompleteApiArgs)
+ response, _ := cmd.NewAPIRequest(r, autocompleteAPI.Name, autocompleteAPIArgs)
- var autocompleteOptions []SelectOption
+ var autocompleteOptions []selectOption
for _, v := range response {
switch obj := v.(type) {
case []interface{}:
@@ -207,9 +205,9 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
if !ok {
continue
}
- opt := SelectOption{}
+ opt := selectOption{}
if resource["id"] != nil {
- opt.Id = resource["id"].(string)
+ opt.ID = resource["id"].(string)
}
if resource["name"] != nil {
opt.Name = resource["name"].(string)
@@ -232,15 +230,15 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
return autocompleteOptions[i].Name < autocompleteOptions[j].Name
})
fmt.Println()
- selectedOption := ShowSelector(autocompleteOptions)
+ selectedOption := showSelector(autocompleteOptions)
if strings.HasSuffix(arg.Name, "id") || strings.HasSuffix(arg.Name, "ids") {
- selected = selectedOption.Id
+ selected = selectedOption.ID
} else {
selected = selectedOption.Name
}
} else {
if len(autocompleteOptions) == 1 {
- selected = autocompleteOptions[0].Id
+ selected = autocompleteOptions[0].ID
}
}
options = [][]rune{[]rune(selected + " ")}
@@ -250,10 +248,3 @@ func (t *CliCompleter) Do(line []rune, pos int) (options [][]rune, offset int) {
return options, offset
}
-
-func NewCompleter(cfg *config.Config) *CliCompleter {
- completer = &CliCompleter{
- Config: cfg,
- }
- return completer
-}
diff --git a/cli/exec.go b/cli/exec.go
index f118768..d64daa1 100644
--- a/cli/exec.go
+++ b/cli/exec.go
@@ -23,6 +23,7 @@ import (
"github.com/chzyer/readline"
)
+// ExecCmd executes a single provided command
func ExecCmd(cfg *config.Config, args []string, shell *readline.Instance) error {
if len(args) < 1 {
return nil
diff --git a/cli/selector.go b/cli/selector.go
index 27e03b2..104e16e 100644
--- a/cli/selector.go
+++ b/cli/selector.go
@@ -25,47 +25,47 @@ import (
"github.com/manifoldco/promptui"
)
-type SelectOption struct {
- Id string
+type selectOption struct {
+ ID string
Name string
Detail string
}
-type Selector struct {
+type selector struct {
InUse bool
}
-var selector Selector
+var optionSelector selector
func init() {
- selector = Selector{
+ optionSelector = selector{
InUse: false,
}
}
-func (s Selector) lock() {
+func (s selector) lock() {
s.InUse = true
}
-func (s Selector) unlock() {
+func (s selector) unlock() {
s.InUse = false
}
-func ShowSelector(options []SelectOption) SelectOption {
- if selector.InUse {
- return SelectOption{}
+func showSelector(options []selectOption) selectOption {
+ if optionSelector.InUse {
+ return selectOption{}
}
- selector.lock()
- defer selector.unlock()
+ optionSelector.lock()
+ defer optionSelector.unlock()
templates := &promptui.SelectTemplates{
Label: "{{ . }}",
- Active: "▶ {{ .Name | cyan }} ({{ .Id | red }})",
- Inactive: " {{ .Name | cyan }} ({{ .Id | red }})",
- Selected: "👊Selected: {{ .Name | cyan }} ({{ .Id | red }})",
+ Active: "▶ {{ .Name | cyan }} ({{ .ID | red }})",
+ Inactive: " {{ .Name | cyan }} ({{ .ID | red }})",
+ Selected: "👊Selected: {{ .Name | cyan }} ({{ .ID | red }})",
Details: `
--------- Current Selection ----------
-{{ "Id:" | faint }} {{ .Id }}
+{{ "ID:" | faint }} {{ .ID }}
{{ "Name:" | faint }} {{ .Name }}
{{ "Info:" | faint }} {{ .Detail }}`,
}
@@ -98,7 +98,7 @@ func ShowSelector(options []SelectOption) SelectOption {
if err != nil {
fmt.Printf("Prompt failed %v\n", err)
- return SelectOption{}
+ return selectOption{}
}
return options[i]
diff --git a/cli/shell.go b/cli/shell.go
index 903a607..26ab8d9 100644
--- a/cli/shell.go
+++ b/cli/shell.go
@@ -28,14 +28,18 @@ import (
"github.com/chzyer/readline"
)
-var shellConfig *config.Config
+var completer *autoCompleter
+// ExecShell starts a shell
func ExecShell(cfg *config.Config) {
- shellConfig = cfg
+ completer = &autoCompleter{
+ Config: cfg,
+ }
+
shell, err := readline.NewEx(&readline.Config{
Prompt: cfg.GetPrompt(),
HistoryFile: cfg.HistoryFile,
- AutoComplete: NewCompleter(cfg),
+ AutoComplete: completer,
InterruptPrompt: "^C",
EOFPrompt: "exit",
VimMode: false,
diff --git a/cmd/api.go b/cmd/api.go
index ad51753..e185a74 100644
--- a/cmd/api.go
+++ b/cmd/api.go
@@ -26,6 +26,7 @@ import (
var apiCommand *Command
+// GetAPIHandler returns a catchall command handler
func GetAPIHandler() *Command {
return apiCommand
}
diff --git a/cmd/command.go b/cmd/command.go
index b631d6c..4f90387 100644
--- a/cmd/command.go
+++ b/cmd/command.go
@@ -21,6 +21,7 @@ import (
"fmt"
)
+// Command describes a CLI command
type Command struct {
Name string
Help string
@@ -32,14 +33,17 @@ type Command struct {
var commands []*Command
var commandMap map[string]*Command
+// FindCommand finds command handler for a command string
func FindCommand(name string) *Command {
return commandMap[name]
}
+// AllCommands returns all available commands
func AllCommands() []*Command {
return commands
}
+// AddCommand adds a command to internal list
func AddCommand(cmd *Command) {
commands = append(commands, cmd)
if commandMap == nil {
@@ -48,6 +52,7 @@ func AddCommand(cmd *Command) {
commandMap[cmd.Name] = cmd
}
+// PrintUsage prints help usage for a command
func PrintUsage() {
commandHelp := ""
for _, cmd := range commands {
diff --git a/cmd/network.go b/cmd/network.go
index 94f67ad..0eb973d 100644
--- a/cmd/network.go
+++ b/cmd/network.go
@@ -56,6 +56,7 @@ func encodeRequestParams(params url.Values) string {
return buf.String()
}
+// NewAPIRequest makes an API request to configured management server
func NewAPIRequest(r *Request, api string, args []string) (map[string]interface{}, error) {
params := make(url.Values)
params.Add("command", api)
@@ -66,7 +67,7 @@ func NewAPIRequest(r *Request, api string, args []string) (map[string]interface{
}
}
- apiKey := r.Config.Core.ActiveProfile.ApiKey
+ apiKey := r.Config.Core.ActiveProfile.APIKey
secretKey := r.Config.Core.ActiveProfile.SecretKey
if len(apiKey) > 0 {
@@ -81,10 +82,10 @@ func NewAPIRequest(r *Request, api string, args []string) (map[string]interface{
signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))
encodedParams = encodedParams + fmt.Sprintf("&signature=%s", url.QueryEscape(signature))
- apiUrl := fmt.Sprintf("%s?%s", r.Config.Core.ActiveProfile.Url, encodedParams)
+ apiURL := fmt.Sprintf("%s?%s", r.Config.Core.ActiveProfile.URL, encodedParams)
- //fmt.Println("[debug] Requesting: ", apiUrl)
- response, err := http.Get(apiUrl)
+ //fmt.Println("[debug] Requesting: ", apiURL)
+ response, err := http.Get(apiURL)
if err != nil {
fmt.Println("Error:", err)
return nil, err
diff --git a/cmd/request.go b/cmd/request.go
index 66d7a48..45b006a 100644
--- a/cmd/request.go
+++ b/cmd/request.go
@@ -22,6 +22,7 @@ import (
"github.com/chzyer/readline"
)
+// Request describes a command request
type Request struct {
Command *Command
Config *config.Config
@@ -29,6 +30,7 @@ type Request struct {
Args []string
}
+// NewRequest creates a new request from a command
func NewRequest(cmd *Command, cfg *config.Config, shell *readline.Instance, args []string) *Request {
return &Request{
Command: cmd,
diff --git a/cmd/set.go b/cmd/set.go
index 2e716e9..a40e5ba 100644
--- a/cmd/set.go
+++ b/cmd/set.go
@@ -34,7 +34,7 @@ func init() {
}
subCommand := r.Args[0]
value := strings.Join(r.Args[1:], " ")
- r.Config.UpdateGlobalConfig(subCommand, value)
+ r.Config.UpdateConfig(subCommand, value)
if subCommand == "profile" && r.Shell != nil {
r.Shell.SetPrompt(r.Config.GetPrompt())
diff --git a/config/about.go b/config/about.go
index 0d59518..c47c029 100644
--- a/config/about.go
+++ b/config/about.go
@@ -19,14 +19,17 @@ package config
import "fmt"
+// Name of the CLI
func (c *Config) Name() string {
return "Apache CloudStack 🐵 cloudmonkey"
}
+// Version of the CLI
func (c *Config) Version() string {
return "6.0.0-alpha1"
}
+// PrintHeader prints startup message in CLI mode
func (c *Config) PrintHeader() {
fmt.Println(c.Name(), c.Version())
fmt.Println("Type \"help\" for details, \"sync\" to update API cache or press tab to list commands")
diff --git a/config/cache.go b/config/cache.go
index e908cea..8a4501a 100644
--- a/config/cache.go
+++ b/config/cache.go
@@ -26,7 +26,8 @@ import (
"unicode"
)
-type ApiArg struct {
+// APIArg are the args passable to an API
+type APIArg struct {
Name string
Type string
Related []string
@@ -35,11 +36,12 @@ type ApiArg struct {
Length int
}
-type Api struct {
+// API describes a CloudStack API
+type API struct {
Name string
Verb string
Noun string
- Args []*ApiArg
+ Args []*APIArg
RequiredArgs []string
Related []string
Async bool
@@ -47,14 +49,15 @@ type Api struct {
ResponseName string
}
-var apiCache map[string]*Api
-var apiVerbMap map[string][]*Api
+var apiCache map[string]*API
+var apiVerbMap map[string][]*API
-func (c *Config) GetApiVerbMap() map[string][]*Api {
+// GetAPIVerbMap returns API cache by verb
+func (c *Config) GetAPIVerbMap() map[string][]*API {
if apiVerbMap != nil {
return apiVerbMap
}
- apiSplitMap := make(map[string][]*Api)
+ apiSplitMap := make(map[string][]*API)
for api := range apiCache {
verb := apiCache[api].Verb
apiSplitMap[verb] = append(apiSplitMap[verb], apiCache[api])
@@ -62,14 +65,16 @@ func (c *Config) GetApiVerbMap() map[string][]*Api {
return apiSplitMap
}
-func (c *Config) GetCache() map[string]*Api {
+// GetCache returns API cache by full API name
+func (c *Config) GetCache() map[string]*API {
if apiCache == nil {
// read from disk?
- return make(map[string]*Api)
+ return make(map[string]*API)
}
return apiCache
}
+// LoadCache loads cache using the default cache file
func LoadCache(c *Config) {
cache, err := ioutil.ReadFile(c.CacheFile)
if err != nil {
@@ -81,13 +86,15 @@ func LoadCache(c *Config) {
c.UpdateCache(data)
}
+// SaveCache saves received auto-discovery data to cache file
func (c *Config) SaveCache(response map[string]interface{}) {
output, _ := json.Marshal(response)
ioutil.WriteFile(c.CacheFile, output, 0600)
}
+// UpdateCache uses auto-discovery data to update internal API cache
func (c *Config) UpdateCache(response map[string]interface{}) interface{} {
- apiCache = make(map[string]*Api)
+ apiCache = make(map[string]*API)
apiVerbMap = nil
count := response["count"]
@@ -114,7 +121,7 @@ func (c *Config) UpdateCache(response map[string]interface{}) interface{} {
verb := apiName[:idx]
noun := strings.ToLower(apiName[idx:])
- var apiArgs []*ApiArg
+ var apiArgs []*APIArg
for _, argNode := range api["params"].([]interface{}) {
apiArg, _ := argNode.(map[string]interface{})
related := []string{}
@@ -122,7 +129,7 @@ func (c *Config) UpdateCache(response map[string]interface{}) interface{} {
related = strings.Split(apiArg["related"].(string), ",")
sort.Strings(related)
}
- apiArgs = append(apiArgs, &ApiArg{
+ apiArgs = append(apiArgs, &APIArg{
Name: apiArg["name"].(string),
Type: apiArg["type"].(string),
Required: apiArg["required"].(bool),
@@ -142,7 +149,7 @@ func (c *Config) UpdateCache(response map[string]interface{}) interface{} {
}
}
- apiCache[strings.ToLower(apiName)] = &Api{
+ apiCache[strings.ToLower(apiName)] = &API{
Name: apiName,
Verb: verb,
Noun: noun,
diff --git a/config/config.go b/config/config.go
index e5336e5..df6d4c1 100644
--- a/config/config.go
+++ b/config/config.go
@@ -26,23 +26,26 @@ import (
"strconv"
)
+// Output formats
const (
- Json = "json"
- Xml = "xml"
- Table = "table"
- Text = "text"
+ JSON = "json"
+ XML = "xml"
+ TABLE = "table"
+ TEXT = "text"
)
+// ServerProfile describes a management server
type ServerProfile struct {
- Url string `ini:"url"`
+ URL string `ini:"url"`
Username string `ini:"username"`
Password string `ini:"password"`
Domain string `ini:"domain"`
- ApiKey string `ini:"apikey"`
+ APIKey string `ini:"apikey"`
SecretKey string `ini:"secretkey"`
VerifyCert bool `ini:"verifycert"`
}
+// Core block describes common options for the CLI
type Core struct {
AsyncBlock bool `ini:"asyncblock"`
Timeout int `ini:"timeout"`
@@ -51,6 +54,7 @@ type Core struct {
ActiveProfile *ServerProfile `ini:"-"`
}
+// Config describes CLI config file and default options
type Config struct {
Dir string
ConfigFile string
@@ -80,14 +84,14 @@ func defaultConfig() *Config {
Core: &Core{
AsyncBlock: false,
Timeout: 1800,
- Output: Json,
+ Output: JSON,
ProfileName: "local",
ActiveProfile: &ServerProfile{
- Url: "http://localhost:8080/client/api",
+ URL: "http://localhost:8080/client/api",
Username: "admin",
Password: "password",
Domain: "/",
- ApiKey: "",
+ APIKey: "",
SecretKey: "",
VerifyCert: false,
},
@@ -154,11 +158,8 @@ func reloadConfig(cfg *Config) *Config {
return cfg
}
-func (c *Config) UpdateGlobalConfig(key string, value string) {
- c.UpdateConfig("", key, value)
-}
-
-func (c *Config) UpdateConfig(namespace string, key string, value string) {
+// UpdateConfig updates and saves config
+func (c *Config) UpdateConfig(key string, value string) {
switch key {
case "asyncblock":
c.Core.AsyncBlock = value == "true"
@@ -171,7 +172,7 @@ func (c *Config) UpdateConfig(namespace string, key string, value string) {
c.Core.ProfileName = value
c.Core.ActiveProfile = nil
case "url":
- c.Core.ActiveProfile.Url = value
+ c.Core.ActiveProfile.URL = value
case "username":
c.Core.ActiveProfile.Username = value
case "password":
@@ -179,7 +180,7 @@ func (c *Config) UpdateConfig(namespace string, key string, value string) {
case "domain":
c.Core.ActiveProfile.Domain = value
case "apikey":
- c.Core.ActiveProfile.ApiKey = value
+ c.Core.ActiveProfile.APIKey = value
case "secretkey":
c.Core.ActiveProfile.SecretKey = value
case "verifycert":
@@ -191,6 +192,7 @@ func (c *Config) UpdateConfig(namespace string, key string, value string) {
reloadConfig(c)
}
+// NewConfig creates or reload config and loads API cache
func NewConfig() *Config {
defaultConf := defaultConfig()
defaultConf.Core = nil
diff --git a/config/prompt.go b/config/prompt.go
index ea8dd82..83b04b1 100644
--- a/config/prompt.go
+++ b/config/prompt.go
@@ -43,6 +43,7 @@ func promptMoji() string {
return emoji() // 🐒
}
+// GetPrompt returns prompt that the CLI should use
func (c *Config) GetPrompt() string {
return fmt.Sprintf("(%s) %s > ", c.Core.ProfileName, promptMoji())
}
--
To stop receiving notification emails like this one, please contact
rohit@apache.org.