forked from tucnak/climax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelp.go
132 lines (106 loc) · 2.52 KB
/
help.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package climax
import (
"bytes"
"strings"
"text/template"
)
const globalHelpTemplate string = `{{.Brief}}
Usage:
{{.Name}} {{if .Commands}}command [arguments]{{end}}
{{if .Commands}}The commands are:
{{if .UngroupedCount}}{{range .Commands}}
{{if not .Group}}{{.Name | printf "%-11s"}} {{.Brief}}{{end}}{{end}}
{{end}}{{range .Groups}}{{if .Commands}}
{{.Name}}
{{range .Commands}}
{{.Name | printf "%-11s"}} {{.Brief}}{{end}}
{{end}}{{end}}
Use "{{.Name}} help [command]" for more information about a command.{{end}}
{{if .Topics}}
Additional help topics:
{{range .Topics}}
{{.Name | printf "%-11s"}} {{.Brief}}{{end}}
Use "{{.Name}} help [topic]" for more information about a topic.
{{end}}`
const commandHelpTemplate string = `Usage: {{commandUsage .Command}}
{{.Help}}
{{if .Flags}}
Available options:
{{range .Flags}}
{{flagUsage . false}}
{{.Help | tabout}}{{end}}{{end}}
{{if .Examples}}
Examples:
{{$app := .App}}{{$cmd := .Name}}{{range .Examples}}
$ {{$app}} {{$cmd}} {{.Usecase}}
{{.Description | tabout}}
{{end}}{{end}}`
func templated(canvas string, data interface{}) string {
t := template.New("")
t.Funcs(template.FuncMap{
"tabout": alignMultilineHelp,
"commandUsage": commandUsage,
"flagUsage": flagUsage,
})
template.Must(t.Parse(canvas))
var b bytes.Buffer
err := t.Execute(&b, data)
if err != nil {
panic(err)
}
output := b.String()
// TODO: Fix this nasty workaround for templating ASAP!
output = strings.Replace(output, "\n\n\n", "", -1)
return output
}
func alignMultilineHelp(text string) string {
return strings.Replace(text, "\n", "\n\t\t", -1)
}
func commandUsage(command Command) string {
if command.Usage != "" {
return command.Name + " " + command.Usage
}
usage := command.Name
for _, flag := range command.Flags {
usage += " [" + flagUsage(flag, true) + "]"
}
return usage
}
func flagUsage(flag Flag, tiny bool) string {
if tiny {
if flag.Short != "" {
return "-" + flag.Short
}
return "--" + flag.Name
}
var short string
if flag.Short != "" {
short = "-" + flag.Short + ", "
}
if flag.Usage != "" {
return short + flag.Usage
}
usage := "--" + flag.Name
if flag.Variable {
usage += "=\"\""
}
return short + usage
}
func (a *Application) globalHelp() string {
return templated(globalHelpTemplate, struct {
Application
UngroupedCount int
}{
*a,
a.ungroupedCmdsCount,
})
}
func (a *Application) commandHelp(command *Command) string {
return templated(commandHelpTemplate, struct {
Command
App string
}{
*command,
a.Name,
})
}