@@ -394,33 +394,11 @@ func (o *Command) Selector(short string, long string, options []string, opts *Op
394
394
return & result
395
395
}
396
396
397
- // Happened shows whether Command was specified on CLI arguments or not. If Command did not "happen", then
398
- // all its descendant commands and arguments are not parsed. Returns a boolean value.
399
- func (o * Command ) Happened () bool {
400
- return o .happened
401
- }
402
-
403
- // Usage returns a multiline string that is the same as a help message for this Parser or Command.
404
- // Since Parser is a Command as well, they work in exactly same way. Meaning that usage string
405
- // can be retrieved for any level of commands. It will only include information about this Command,
406
- // its sub-commands, current Command arguments and arguments of all preceding commands (if any)
407
- //
397
+ // message2String - puts msg in result string
408
398
// Accepts an interface that can be error, string or fmt.Stringer that will be prepended to a message.
409
399
// All other interface types will be ignored
410
- func (o * Command ) Usage (msg interface {}) string {
411
- for _ , cmd := range o .commands {
412
- if cmd .Happened () {
413
- return cmd .Usage (msg )
414
- }
415
- }
400
+ func message2String (msg interface {}) string {
416
401
var result string
417
- // Stay classy
418
- maxWidth := 80
419
- // List of arguments from all preceding commands
420
- arguments := make ([]* arg , 0 )
421
- // First get line of commands until root
422
- var chain []string
423
- current := o
424
402
if msg != nil {
425
403
switch msg .(type ) {
426
404
case subCommandError :
@@ -437,23 +415,33 @@ func (o *Command) Usage(msg interface{}) string {
437
415
result = fmt .Sprintf ("%s\n " , msg .(fmt.Stringer ).String ())
438
416
}
439
417
}
418
+ return result
419
+ }
420
+
421
+ // getPrecedingCommands - collects info on command chain from root to current (o *Command) and all arguments in this chain
422
+ func (o * Command ) getPrecedingCommands (chain * []string , arguments * []* arg ) {
423
+ current := o
424
+ // Get line of commands until root
440
425
for current != nil {
441
- chain = append (chain , current .name )
426
+ * chain = append (* chain , current .name )
442
427
// Also add arguments
443
428
if current .args != nil {
444
- arguments = append (arguments , current .args ... )
429
+ * arguments = append (* arguments , current .args ... )
445
430
}
446
431
current = current .parent
447
432
}
448
433
// Reverse the slice
449
- last := len (chain ) - 1
450
- for i := 0 ; i < len (chain )/ 2 ; i ++ {
451
- chain [i ], chain [last - i ] = chain [last - i ], chain [i ]
434
+ last := len (* chain ) - 1
435
+ for i := 0 ; i < len (* chain )/ 2 ; i ++ {
436
+ ( * chain ) [i ], ( * chain ) [last - i ] = ( * chain ) [last - i ], ( * chain ) [i ]
452
437
}
453
- // If this Command has sub-commands we need their list
438
+ }
439
+
440
+ // getSubCommands - collects info on subcommands of current command
441
+ func (o * Command ) getSubCommands (chain * []string ) []Command {
454
442
commands := make ([]Command , 0 )
455
443
if o .commands != nil && len (o .commands ) > 0 {
456
- chain = append (chain , "<Command>" )
444
+ * chain = append (* chain , "<Command>" )
457
445
for _ , v := range o .commands {
458
446
// Skip hidden commands
459
447
if v .description == DisableDescription {
@@ -462,9 +450,11 @@ func (o *Command) Usage(msg interface{}) string {
462
450
commands = append (commands , * v )
463
451
}
464
452
}
453
+ return commands
454
+ }
465
455
466
- // Build usage description
467
- result += "usage:"
456
+ // precedingCommands2Result - puts info about command chain from root to current (o *Command) into result string buffer
457
+ func ( o * Command ) precedingCommands2Result ( result string , chain [] string , arguments [] * arg , maxWidth int ) string {
468
458
leftPadding := len ("usage: " + chain [0 ] + "" )
469
459
// Add preceding commands
470
460
for _ , v := range chain {
@@ -478,12 +468,16 @@ func (o *Command) Usage(msg interface{}) string {
478
468
}
479
469
result = addToLastLine (result , v .usage (), maxWidth , leftPadding , true )
480
470
}
481
-
482
471
// Add program/Command description to the result
483
472
result = result + "\n \n " + strings .Repeat (" " , leftPadding )
484
473
result = addToLastLine (result , o .description , maxWidth , leftPadding , true )
485
474
result = result + "\n \n "
486
475
476
+ return result
477
+ }
478
+
479
+ // subCommands2Result - puts info about subcommands of current command into result string buffer
480
+ func subCommands2Result (result string , commands []Command , maxWidth int ) string {
487
481
// Add list of sub-commands to the result
488
482
if len (commands ) > 0 {
489
483
cmdContent := "Commands:\n \n "
@@ -509,8 +503,11 @@ func (o *Command) Usage(msg interface{}) string {
509
503
}
510
504
result = result + cmdContent + "\n "
511
505
}
506
+ return result
507
+ }
512
508
513
- // Add list of arguments to the result
509
+ // arguments2Result - puts info about all arguments of current command into result string buffer
510
+ func arguments2Result (result string , arguments []* arg , maxWidth int ) string {
514
511
if len (arguments ) > 0 {
515
512
argContent := "Arguments:\n \n "
516
513
// Get biggest padding
@@ -544,6 +541,51 @@ func (o *Command) Usage(msg interface{}) string {
544
541
}
545
542
result = result + argContent + "\n "
546
543
}
544
+ return result
545
+ }
546
+
547
+ // Happened shows whether Command was specified on CLI arguments or not. If Command did not "happen", then
548
+ // all its descendant commands and arguments are not parsed. Returns a boolean value.
549
+ func (o * Command ) Happened () bool {
550
+ return o .happened
551
+ }
552
+
553
+ // Usage returns a multiline string that is the same as a help message for this Parser or Command.
554
+ // Since Parser is a Command as well, they work in exactly same way. Meaning that usage string
555
+ // can be retrieved for any level of commands. It will only include information about this Command,
556
+ // its sub-commands, current Command arguments and arguments of all preceding commands (if any)
557
+ //
558
+ // Accepts an interface that can be error, string or fmt.Stringer that will be prepended to a message.
559
+ // All other interface types will be ignored
560
+ func (o * Command ) Usage (msg interface {}) string {
561
+ for _ , cmd := range o .commands {
562
+ if cmd .Happened () {
563
+ return cmd .Usage (msg )
564
+ }
565
+ }
566
+
567
+ var result string
568
+ // Stay classy
569
+ maxWidth := 80
570
+ // List of arguments from all preceding commands
571
+ arguments := make ([]* arg , 0 )
572
+ // Line of commands until root
573
+ var chain []string
574
+
575
+ // Put message in resultz
576
+ result = message2String (msg )
577
+
578
+ //collect info about Preceding Commands into chain and arguments
579
+ o .getPrecedingCommands (& chain , & arguments )
580
+ // If this Command has sub-commands we need their list
581
+ commands := o .getSubCommands (& chain )
582
+
583
+ // Build usage description from description of preceding commands chain and each of subcommands
584
+ result += "usage:"
585
+ result = o .precedingCommands2Result (result , chain , arguments , maxWidth )
586
+ result = subCommands2Result (result , commands , maxWidth )
587
+ // Add list of arguments to the result
588
+ result = arguments2Result (result , arguments , maxWidth )
547
589
548
590
return result
549
591
}
0 commit comments