Skip to content

Commit b8cd502

Browse files
committed
parser.Usage should also accept strings and fmt.Stringer
1 parent 0d55ac0 commit b8cd502

File tree

2 files changed

+71
-9
lines changed

2 files changed

+71
-9
lines changed

argparse.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -260,23 +260,32 @@ func (o *Command) Happened() bool {
260260
// Since Parser is a Command as well, they work in exactly same way. Meaning that usage string
261261
// can be retrieved for any level of commands. It will only include information about this Command,
262262
// its sub-commands, current Command arguments and arguments of all preceding commands (if any)
263-
func (o *Command) Usage(err interface{}) string {
263+
//
264+
// Accepts an interface that can be error, string or fmt.Stringer that will be prepended to a message.
265+
// All other interface types will be ignored
266+
func (o *Command) Usage(msg interface{}) string {
267+
var result string
264268
// Stay classy
265269
maxWidth := 80
266270
// List of arguments from all preceding commands
267271
arguments := make([]*arg, 0)
268272
// First get line of commands until root
269273
var chain []string
270274
current := o
271-
if err != nil {
272-
switch err.(type) {
275+
if msg != nil {
276+
switch msg.(type) {
273277
case subCommandError:
274-
fmt.Println(err.(error).Error())
275-
if err.(subCommandError).cmd != nil {
276-
return err.(subCommandError).cmd.Usage(nil)
278+
result = fmt.Sprintf("%s\n", msg.(error).Error())
279+
if msg.(subCommandError).cmd != nil {
280+
result += msg.(subCommandError).cmd.Usage(nil)
277281
}
282+
return result
278283
case error:
279-
fmt.Println(err.(error).Error())
284+
result = fmt.Sprintf("%s\n", msg.(error).Error())
285+
case string:
286+
result = fmt.Sprintf("%s\n", msg.(string))
287+
case fmt.Stringer:
288+
result = fmt.Sprintf("%s\n", msg.(fmt.Stringer).String())
280289
}
281290
}
282291
for current != nil {
@@ -301,8 +310,8 @@ func (o *Command) Usage(err interface{}) string {
301310
}
302311
}
303312

304-
// Build result description
305-
var result = "usage:"
313+
// Build usage description
314+
result += "usage:"
306315
leftPadding := len("usage: " + chain[0] + "")
307316
// Add preceding commands
308317
for _, v := range chain {

argparse_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,3 +1099,56 @@ func TestFloatFail1(t *testing.T) {
10991099
return
11001100
}
11011101
}
1102+
1103+
var pUsageString = `test string
1104+
usage: prog [-h|--help]
1105+
1106+
program description
1107+
1108+
Arguments:
1109+
1110+
-h --help Print help information
1111+
1112+
`
1113+
1114+
func TestUsageString(t *testing.T) {
1115+
p := NewParser("prog", "program description")
1116+
1117+
p.Parse(os.Args)
1118+
1119+
usage := p.Usage("test string")
1120+
1121+
if usage != pUsageString {
1122+
t.Errorf("%s", usage)
1123+
}
1124+
}
1125+
1126+
type s string
1127+
func (s s) String() string {
1128+
return string(s)
1129+
}
1130+
1131+
var pUsageStringer = `stringer message
1132+
usage: prog [-h|--help]
1133+
1134+
program description
1135+
1136+
Arguments:
1137+
1138+
-h --help Print help information
1139+
1140+
`
1141+
1142+
func TestUsageStringer(t *testing.T) {
1143+
p := NewParser("prog", "program description")
1144+
1145+
p.Parse(os.Args)
1146+
1147+
var msg s = "stringer message"
1148+
1149+
usage := p.Usage(msg)
1150+
1151+
if usage != pUsageStringer {
1152+
t.Errorf("%s", usage)
1153+
}
1154+
}

0 commit comments

Comments
 (0)