@@ -15,33 +15,59 @@ const (
1515 helpAlias = "h"
1616)
1717
18- var helpCommand = & Command {
18+ // this instance is to avoid recursion in the ShowCommandHelp which can
19+ // add a help command again
20+ var helpCommandDontUse = & Command {
1921 Name : helpName ,
2022 Aliases : []string {helpAlias },
2123 Usage : "Shows a list of commands or help for one command" ,
2224 ArgsUsage : "[command]" ,
23- Action : func (cCtx * Context ) error {
24- args := cCtx .Args ()
25- if args .Present () {
26- return ShowCommandHelp (cCtx , args .First ())
27- }
28-
29- _ = ShowAppHelp (cCtx )
30- return nil
31- },
3225}
3326
34- var helpSubcommand = & Command {
27+ var helpCommand = & Command {
3528 Name : helpName ,
3629 Aliases : []string {helpAlias },
3730 Usage : "Shows a list of commands or help for one command" ,
3831 ArgsUsage : "[command]" ,
3932 Action : func (cCtx * Context ) error {
4033 args := cCtx .Args ()
41- if args .Present () {
42- return ShowCommandHelp (cCtx , args .First ())
34+ argsPresent := args .First () != ""
35+ firstArg := args .First ()
36+
37+ // This action can be triggered by a "default" action of a command
38+ // or via cmd.Run when cmd == helpCmd. So we have following possibilities
39+ //
40+ // 1 $ app
41+ // 2 $ app help
42+ // 3 $ app foo
43+ // 4 $ app help foo
44+ // 5 $ app foo help
45+
46+ // Case 4. when executing a help command set the context to parent
47+ // to allow resolution of subsequent args. This will transform
48+ // $ app help foo
49+ // to
50+ // $ app foo
51+ // which will then be handled as case 3
52+ if cCtx .Command .Name == helpName || cCtx .Command .Name == helpAlias {
53+ cCtx = cCtx .parentContext
4354 }
4455
56+ // Case 4. $ app hello foo
57+ // foo is the command for which help needs to be shown
58+ if argsPresent {
59+ return ShowCommandHelp (cCtx , firstArg )
60+ }
61+
62+ // Case 1 & 2
63+ // Special case when running help on main app itself as opposed to indivdual
64+ // commands/subcommands
65+ if cCtx .parentContext .App == nil {
66+ _ = ShowAppHelp (cCtx )
67+ return nil
68+ }
69+
70+ // Case 3, 5
4571 return ShowSubcommandHelp (cCtx )
4672 },
4773}
@@ -212,9 +238,19 @@ func ShowCommandHelp(ctx *Context, command string) error {
212238
213239 for _ , c := range ctx .App .Commands {
214240 if c .HasName (command ) {
241+ if ! ctx .App .HideHelpCommand && ! c .HasName (helpName ) && len (c .Subcommands ) != 0 {
242+ c .Subcommands = append (c .Subcommands , helpCommandDontUse )
243+ }
244+ if ! ctx .App .HideHelp && HelpFlag != nil {
245+ c .appendFlag (HelpFlag )
246+ }
215247 templ := c .CustomHelpTemplate
216248 if templ == "" {
217- templ = CommandHelpTemplate
249+ if len (c .Subcommands ) == 0 {
250+ templ = CommandHelpTemplate
251+ } else {
252+ templ = SubcommandHelpTemplate
253+ }
218254 }
219255
220256 HelpPrinter (ctx .App .Writer , templ , c )
0 commit comments