github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/cf/commandregistry/registry.go (about)

     1  package commandregistry
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"unicode/utf8"
     8  
     9  	"github.com/liamawhite/cli-with-i18n/cf"
    10  	"github.com/liamawhite/cli-with-i18n/cf/flags"
    11  	. "github.com/liamawhite/cli-with-i18n/cf/i18n"
    12  	"github.com/liamawhite/cli-with-i18n/command/translatableerror"
    13  	"github.com/liamawhite/cli-with-i18n/util/configv3"
    14  
    15  	. "github.com/liamawhite/cli-with-i18n/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 &registry{
    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  }