// +build ignore package core import ( "encoding/json" "strings" ) const ( clear = "\x1b[0m" bright = "\x1b[1m" gray = "\x1b[90m" yellow = "\x1b[33m" ) // Command represents a Tile38 command. type Command struct { Name string `json:"-"` Summary string `json:"summary"` Complexity string `json:"complexity"` Arguments []Argument `json:"arguments"` Since string `json:"since"` Group string `json:"group"` DevOnly bool `json:"dev"` } // String returns a string representation of the command. func (c Command) String() string { var s = c.Name for _, arg := range c.Arguments { s += " " + arg.String() } return s } // TermOutput returns a string representation of the command suitable for displaying in a terminal. func (c Command) TermOutput(indent string) string { line := c.String() var line1 string if strings.HasPrefix(line, c.Name) { line1 = bright + c.Name + clear + gray + line[len(c.Name):] + clear } else { line1 = bright + strings.Replace(c.String(), " ", " "+clear+gray, 1) + clear } line2 := yellow + "summary: " + clear + c.Summary //line3 := yellow + "since: " + clear + c.Since return indent + line1 + "\n" + indent + line2 + "\n" //+ indent + line3 + "\n" } // EnumArg represents a enum arguments. type EnumArg struct { Name string `json:"name"` Arguments []Argument `json:"arguments"` } // String returns a string representation of an EnumArg. func (a EnumArg) String() string { var s = a.Name for _, arg := range a.Arguments { s += " " + arg.String() } return s } // Argument represents a command argument. type Argument struct { Command string `json:"command"` NameAny interface{} `json:"name"` TypeAny interface{} `json:"type"` Optional bool `json:"optional"` Multiple bool `json:"multiple"` Variadic bool `json:"variadic"` Enum []string `json:"enum"` EnumArgs []EnumArg `json:"enumargs"` } // String returns a string representation of an Argument. func (a Argument) String() string { var s string if a.Command != "" { s += " " + a.Command } if len(a.EnumArgs) > 0 { eargs := "" for _, arg := range a.EnumArgs { v := arg.String() if strings.Contains(v, " ") { v = "(" + v + ")" } eargs += v + "|" } if len(eargs) > 0 { eargs = eargs[:len(eargs)-1] } s += " " + eargs } else if len(a.Enum) > 0 { s += " " + strings.Join(a.Enum, "|") } else { names, _ := a.NameTypes() subs := "" for _, name := range names { subs += " " + name } subs = strings.TrimSpace(subs) s += " " + subs if a.Variadic { if len(names) == 0 { s += " [" + subs + " ...]" } else { s += " [" + names[len(names)-1] + " ...]" } } if a.Multiple { s += " ..." } } s = strings.TrimSpace(s) if a.Optional { s = "[" + s + "]" } return s } func parseAnyStringArray(any interface{}) []string { if str, ok := any.(string); ok { return []string{str} } else if any, ok := any.([]interface{}); ok { arr := []string{} for _, any := range any { if str, ok := any.(string); ok { arr = append(arr, str) } } return arr } return []string{} } // NameTypes returns the types and names of an argument as separate arrays. func (a Argument) NameTypes() (names, types []string) { names = parseAnyStringArray(a.NameAny) types = parseAnyStringArray(a.TypeAny) if len(types) > len(names) { types = types[:len(names)] } else { for len(types) < len(names) { types = append(types, "") } } return } // Commands is a map of all of the commands. var Commands = func() map[string]Command { var commands map[string]Command if err := json.Unmarshal([]byte(commandsJSON), &commands); err != nil { panic(err.Error()) } for name, command := range commands { command.Name = strings.ToUpper(name) commands[name] = command } return commands }() var commandsJSON = `{{.CommandsJSON}}`