forked from runatlantis/atlantis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelp_fmt.go
135 lines (118 loc) · 3.53 KB
/
help_fmt.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
133
134
135
package cmd
import (
"bytes"
"fmt"
"sort"
"strings"
"text/template"
)
// usageTmpl returns a cobra-compatible usage template that will be printed
// during the help output.
// This template prints help like:
// --name=<value>
// <description>
// We use it over the default template so that the output it easier to read.
func usageTmpl(stringFlags map[string]stringFlag, intFlags map[string]intFlag, boolFlags map[string]boolFlag) string {
var flagNames []string
for name, f := range stringFlags {
if f.hidden {
continue
}
flagNames = append(flagNames, name)
}
for name, f := range boolFlags {
if f.hidden {
continue
}
flagNames = append(flagNames, name)
}
for name, f := range intFlags {
if f.hidden {
continue
}
flagNames = append(flagNames, name)
}
sort.Strings(flagNames)
type flag struct {
Name string
Description string
IsBoolFlag bool
}
var flags []flag
for _, name := range flagNames {
var descrip string
var isBool bool
if f, ok := stringFlags[name]; ok {
descripWithDefault := f.description
if f.defaultValue != "" {
descripWithDefault += fmt.Sprintf(" (default %q)", f.defaultValue)
}
descrip = to80CharCols(descripWithDefault)
isBool = false
} else if f, ok := boolFlags[name]; ok {
descrip = to80CharCols(f.description)
isBool = true
} else if f, ok := intFlags[name]; ok {
descripWithDefault := f.description
if f.defaultValue != 0 {
descripWithDefault += fmt.Sprintf(" (default %d)", f.defaultValue)
}
descrip = to80CharCols(descripWithDefault)
isBool = false
} else {
panic("this is a bug")
}
flags = append(flags, flag{
Name: name,
Description: descrip,
IsBoolFlag: isBool,
})
}
tmpl := template.Must(template.New("").Parse(
" --{{.Name}}{{if not .IsBoolFlag}}=<value>{{end}}\n{{.Description}}\n"))
var flagHelpOutput string
for _, f := range flags {
buf := &bytes.Buffer{}
if err := tmpl.Execute(buf, f); err != nil {
panic(err)
}
flagHelpOutput += buf.String()
}
// Most of this template is taken from cobra.Command.UsageTemplate()
// but we're subbing out the "Flags:" section with our custom output.
return fmt.Sprintf(`Usage:{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
Examples:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Flags:
%s{{end}}{{if .HasAvailableInheritedFlags}}
Global Flags:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
`, flagHelpOutput)
}
func to80CharCols(s string) string {
var splitAt80 string
splitSpaces := strings.Split(s, " ")
var nextLine string
for i, spaceSplit := range splitSpaces {
if len(nextLine)+len(spaceSplit)+1 > 80 {
splitAt80 += fmt.Sprintf(" %s\n", strings.TrimSuffix(nextLine, " "))
nextLine = ""
}
if i == len(splitSpaces)-1 {
nextLine += spaceSplit + " "
splitAt80 += fmt.Sprintf(" %s\n", strings.TrimSuffix(nextLine, " "))
break
}
nextLine += spaceSplit + " "
}
return splitAt80
}