Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit 0acf6ac

Browse files
committed
Help output formatting cleanups, part 2.
* Sort the Commanders and Commands by name. * Clean up the help templates a bit. * Give the full path to a specific command in the Usage: line.
1 parent 0578428 commit 0acf6ac

File tree

1 file changed

+65
-17
lines changed

1 file changed

+65
-17
lines changed

commands.go

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ package commander
1212
import (
1313
"bytes"
1414
"fmt"
15+
"github.com/gonuts/flag"
1516
"io"
1617
"os"
1718
"os/exec"
19+
"sort"
1820
"strings"
1921
"text/template"
20-
21-
"github.com/gonuts/flag"
2222
)
2323

2424
// A Commander holds the configuration for the command line tool.
@@ -38,6 +38,45 @@ type Commander struct {
3838
Commanders []*Commander
3939
}
4040

41+
// Type to allow us to use sort.Sort on a slice of Commanders
42+
type CommanderSlice []*Commander
43+
44+
func (c CommanderSlice) Len() int {
45+
return len(c)
46+
}
47+
48+
func (c CommanderSlice) Less(i, j int) bool {
49+
return c[i].Name < c[j].Name
50+
}
51+
52+
func (c CommanderSlice) Swap(i, j int) {
53+
c[i], c[j] = c[j], c[i]
54+
}
55+
56+
type CommandSlice []*Command
57+
58+
func (c CommandSlice) Len() int {
59+
return len(c)
60+
}
61+
62+
func (c CommandSlice) Less(i, j int) bool {
63+
return c[i].Name() < c[j].Name()
64+
}
65+
66+
func (c CommandSlice) Swap(i, j int) {
67+
c[i], c[j] = c[j], c[i]
68+
}
69+
70+
// Sort the subcommanders.
71+
func (c *Commander) SortCommanders() {
72+
sort.Sort(CommanderSlice(c.Commanders))
73+
}
74+
75+
// Sort the commanders
76+
func (c *Commander) SortCommands() {
77+
sort.Sort(CommandSlice(c.Commands))
78+
}
79+
4180
// Run executes the commander using the provided arguments. The command
4281
// matching the first argument is executed and it receives the remaining
4382
// arguments.
@@ -116,7 +155,9 @@ func (c *Commander) Run(args []string) error {
116155
}
117156

118157
func (c *Commander) usage() error {
119-
err := tmpl(os.Stderr,strings.Replace(usageTemplate,"%%MAX%%",fmt.Sprintf("%d",c.MaxLen()),-1),c)
158+
c.SortCommanders()
159+
c.SortCommands()
160+
err := tmpl(os.Stderr, strings.Replace(usageTemplate, "%%MAX%%", fmt.Sprintf("%d", c.MaxLen()), -1), c)
120161
if err != nil {
121162
fmt.Println(err)
122163
}
@@ -149,7 +190,7 @@ func (c *Commander) help(args []string) error {
149190
c := struct {
150191
*Command
151192
ProgramName string
152-
}{cmd, c.Name}
193+
}{cmd, c.FullSpacedName()}
153194
return tmpl(os.Stdout, helpTemplate, c)
154195
}
155196
}
@@ -159,13 +200,13 @@ func (c *Commander) help(args []string) error {
159200

160201
func (c *Commander) MaxLen() (res int) {
161202
res = 0
162-
for _,cmd := range c.Commands {
203+
for _, cmd := range c.Commands {
163204
i := len(cmd.Name())
164205
if i > res {
165206
res = i
166207
}
167208
}
168-
for _,cmd := range c.Commanders {
209+
for _, cmd := range c.Commanders {
169210
i := len(cmd.Name)
170211
if i > res {
171212
res = i
@@ -183,6 +224,15 @@ func (c *Commander) FullName() string {
183224
return n
184225
}
185226

227+
//FullSpacedName returns the full name of the commander, with subcommand names seperated by spaces.
228+
func (c *Commander) FullSpacedName() string {
229+
n := c.Name
230+
if c.Parent != nil {
231+
n = c.Parent.FullSpacedName() + " " + n
232+
}
233+
return n
234+
}
235+
186236
// A Command is an implementation of a subcommand.
187237
type Command struct {
188238
// Run runs the command.
@@ -242,23 +292,21 @@ func (c *Command) Runnable() bool {
242292
return c.Run != nil
243293
}
244294

245-
var usageTemplate = `Usage:
246-
{{.Name}} command [arguments]
295+
var usageTemplate = `Usage: {{.FullSpacedName}} command [arguments]
247296
248-
The commands are:
249-
{{range .Commands}}{{if .Runnable}}
250-
{{.Name | printf "%-%%MAX%%s"}} {{.Short}}{{end}}{{end}}
251-
{{range $cmd := .Commanders}}
252-
{{.Name | printf "%-%%MAX%%s"}} {{.Short}}{{end}}
297+
Commands:
298+
{{range .Commands}}{{if .Runnable}} {{.Name | printf "%-%%MAX%%s"}} {{.Short}}{{end}}
299+
{{end}}
253300
254-
Use "{{$.Name}} help [command]" for more information about a command.
301+
Subcommands:
302+
{{range .Commanders}} {{.Name | printf "%-%%MAX%%s"}} {{.Short}}
303+
{{end}}
304+
Use "{{.Name}} help [command]" for more information about a command.
255305
256306
Additional help topics:
257-
{{range $cmd := .Commands}}{{if not .Runnable}}
307+
{{range .Commands}}{{if not .Runnable}}
258308
{{.Name | printf "%-%%MAX%%s"}} {{.Short}}{{end}}{{end}}
259-
260309
Use "{{.Name}} help [topic]" for more information about that topic.
261-
262310
`
263311

264312
var helpTemplate = `{{if .Runnable}}Usage: {{.ProgramName}} {{.UsageLine}}

0 commit comments

Comments
 (0)