131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
package root
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/kr/text"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type helpEntry struct {
|
|
Title string
|
|
Body string
|
|
}
|
|
|
|
func helpFunc(cmd *cobra.Command, _ []string) {
|
|
entries := getEntries(cmd)
|
|
|
|
out := cmd.OutOrStdout()
|
|
for _, e := range entries {
|
|
if e.Title != "" {
|
|
fmt.Fprintf(out, "\033[1m%s\033[0m\n", e.Title)
|
|
fmt.Fprintln(out, text.Indent(strings.Trim(e.Body, "\r\n"), " "))
|
|
} else {
|
|
fmt.Fprintln(out, e.Body)
|
|
}
|
|
fmt.Fprintln(out)
|
|
}
|
|
}
|
|
|
|
func getEntries(cmd *cobra.Command) []helpEntry {
|
|
mainCmds, otherCmds := groupCommands(cmd.Commands())
|
|
|
|
var entries []helpEntry
|
|
|
|
appendIfNotEmpty := func(b interface{}, t string) {
|
|
switch d := b.(type) {
|
|
case string:
|
|
if b != "" {
|
|
entries = append(entries, helpEntry{Title: t, Body: d})
|
|
}
|
|
case []string:
|
|
if len(d) > 0 {
|
|
entries = append(entries, helpEntry{Title: t, Body: strings.Join(d, "\n")})
|
|
}
|
|
}
|
|
}
|
|
|
|
if cmd.Long != "" {
|
|
entries = append(entries, helpEntry{"", cmd.Long})
|
|
} else if cmd.Short != "" {
|
|
entries = append(entries, helpEntry{"", cmd.Short})
|
|
}
|
|
|
|
appendIfNotEmpty(cmd.UseLine(), "USAGE")
|
|
appendIfNotEmpty(mainCmds, "MAIN COMMANDS")
|
|
appendIfNotEmpty(otherCmds, "OTHER COMMANDS")
|
|
appendIfNotEmpty(outdent(cmd.LocalFlags().FlagUsages()), "FLAGS")
|
|
appendIfNotEmpty(outdent(cmd.InheritedFlags().FlagUsages()), "INHERITED FLAGS")
|
|
if _, ok := cmd.Annotations["help:args"]; ok {
|
|
appendIfNotEmpty(cmd.Annotations["help:args"], "ARGUMENTS")
|
|
}
|
|
appendIfNotEmpty(cmd.Example, "EXAMPLES")
|
|
appendIfNotEmpty(cmd.Aliases, "ALIASES")
|
|
entries = append(entries, helpEntry{
|
|
"LEARN MORE",
|
|
`Use 'jira <command> <subcommand> --help' for more information about a command.
|
|
Read the doc or get help at https://github.com/ankitpokhrel/jira-cli`,
|
|
})
|
|
|
|
return entries
|
|
}
|
|
|
|
func groupCommands(cmds []*cobra.Command) ([]string, []string) {
|
|
var primary, secondary []string
|
|
|
|
for _, c := range cmds {
|
|
if c.Short == "" {
|
|
continue
|
|
}
|
|
if c.Hidden {
|
|
continue
|
|
}
|
|
|
|
s := rpad(c.Name(), c.NamePadding()) + c.Short
|
|
if _, ok := c.Annotations["cmd:main"]; ok {
|
|
primary = append(primary, s)
|
|
} else {
|
|
secondary = append(secondary, s)
|
|
}
|
|
}
|
|
|
|
if len(primary) == 0 {
|
|
primary = secondary
|
|
secondary = []string{}
|
|
}
|
|
|
|
return primary, secondary
|
|
}
|
|
|
|
func outdent(s string) string {
|
|
lines, minIndent := strings.Split(s, "\n"), -1
|
|
|
|
for _, l := range lines {
|
|
if l == "" {
|
|
continue
|
|
}
|
|
|
|
indent := len(l) - len(strings.TrimLeft(l, " "))
|
|
if minIndent == -1 || indent < minIndent {
|
|
minIndent = indent
|
|
}
|
|
}
|
|
|
|
if minIndent <= 0 {
|
|
return s
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
for _, l := range lines {
|
|
fmt.Fprintln(&buf, strings.TrimPrefix(l, strings.Repeat(" ", minIndent)))
|
|
}
|
|
return strings.TrimSuffix(buf.String(), "\n")
|
|
}
|
|
|
|
func rpad(s string, pad int) string {
|
|
template := fmt.Sprintf("%%-%ds ", pad)
|
|
return fmt.Sprintf(template, s)
|
|
}
|