github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/cf/commandregistry/registry.go (about) 1 package commandregistry 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 "unicode/utf8" 8 9 "code.cloudfoundry.org/cli/cf" 10 "code.cloudfoundry.org/cli/cf/flags" 11 . "code.cloudfoundry.org/cli/cf/i18n" 12 "code.cloudfoundry.org/cli/command/translatableerror" 13 "code.cloudfoundry.org/cli/util/configv3" 14 15 . "code.cloudfoundry.org/cli/cf/terminal" 16 ) 17 18 var _ = initI18nFunc() 19 var Commands = NewRegistry() 20 21 func initI18nFunc() bool { 22 config, err := configv3.LoadConfig() 23 24 var configErrTemplate string 25 if err != nil { 26 if ce, ok := err.(translatableerror.EmptyConfigError); ok { 27 configErrTemplate = ce.Error() 28 } else { 29 fmt.Println(FailureColor("FAILED")) 30 fmt.Println("Error read/writing config: ", err.Error()) 31 os.Exit(1) 32 } 33 } 34 35 T = Init(config) 36 37 if err != nil { 38 fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", T(configErrTemplate, map[string]interface{}{ 39 "FilePath": configv3.ConfigFilePath(), 40 }))) 41 } 42 return true 43 } 44 45 type registry struct { 46 cmd map[string]Command 47 alias map[string]string 48 } 49 50 func NewRegistry() *registry { 51 return ®istry{ 52 cmd: make(map[string]Command), 53 alias: make(map[string]string), 54 } 55 } 56 57 func Register(cmd Command) { 58 m := cmd.MetaData() 59 Commands.cmd[m.Name] = cmd 60 61 Commands.alias[m.ShortName] = m.Name 62 } 63 64 func (r *registry) FindCommand(name string) Command { 65 if _, ok := r.cmd[name]; ok { 66 return r.cmd[name] 67 } 68 69 if alias, exists := r.alias[name]; exists { 70 return r.cmd[alias] 71 } 72 73 return nil 74 } 75 76 func (r *registry) CommandExists(name string) bool { 77 if strings.TrimSpace(name) == "" { 78 return false 79 } 80 81 var ok bool 82 83 if _, ok = r.cmd[name]; !ok { 84 alias, exists := r.alias[name] 85 86 if exists { 87 _, ok = r.cmd[alias] 88 } 89 } 90 91 return ok 92 } 93 94 func (r *registry) ListCommands() []string { 95 keys := make([]string, len(r.cmd)) 96 97 i := 0 98 for k := range r.cmd { 99 keys[i] = k 100 i++ 101 } 102 103 return keys 104 } 105 106 func (r *registry) SetCommand(cmd Command) { 107 r.cmd[cmd.MetaData().Name] = cmd 108 } 109 110 func (r *registry) RemoveCommand(cmdName string) { 111 delete(r.cmd, cmdName) 112 } 113 114 func (r *registry) TotalCommands() int { 115 return len(r.cmd) 116 } 117 118 func (r *registry) MaxCommandNameLength() int { 119 maxNameLen := 0 120 for name := range r.cmd { 121 if nameLen := utf8.RuneCountInString(name); nameLen > maxNameLen { 122 maxNameLen = nameLen 123 } 124 } 125 return maxNameLen 126 } 127 128 func (r *registry) Metadatas() []CommandMetadata { 129 var m []CommandMetadata 130 131 for _, c := range r.cmd { 132 m = append(m, c.MetaData()) 133 } 134 135 return m 136 } 137 138 func (r *registry) CommandUsage(cmdName string) string { 139 cmd := r.FindCommand(cmdName) 140 141 return CLICommandUsagePresenter(cmd).Usage() 142 } 143 144 type usagePresenter struct { 145 cmd Command 146 } 147 148 func CLICommandUsagePresenter(cmd Command) *usagePresenter { 149 return &usagePresenter{ 150 cmd: cmd, 151 } 152 } 153 154 func (u *usagePresenter) Usage() string { 155 metadata := u.cmd.MetaData() 156 157 output := T("NAME:") + "\n" 158 output += " " + metadata.Name + " - " + metadata.Description + "\n\n" 159 160 output += T("USAGE:") + "\n" 161 output += " " + strings.Replace(strings.Join(metadata.Usage, ""), "CF_NAME", cf.Name, -1) + "\n" 162 163 if len(metadata.Examples) > 0 { 164 output += "\n" 165 output += fmt.Sprintf("%s:\n", T("EXAMPLES")) 166 for _, e := range metadata.Examples { 167 output += fmt.Sprintf(" %s\n", strings.Replace(e, "CF_NAME", cf.Name, -1)) 168 } 169 } 170 171 if metadata.ShortName != "" { 172 output += "\n" + T("ALIAS:") + "\n" 173 output += " " + metadata.ShortName + "\n" 174 } 175 176 if metadata.Flags != nil { 177 output += "\n" + T("OPTIONS:") + "\n" 178 output += flags.NewFlagContext(metadata.Flags).ShowUsage(3) 179 } 180 181 return output 182 }