Merge pull request #1499 from dearchap/issue_557
Fix help results inconsistency
This commit is contained in:
commit
de83493182
@ -177,10 +177,13 @@ func ExampleApp_Run_commandHelp() {
|
|||||||
// greet describeit - use it to see a description
|
// greet describeit - use it to see a description
|
||||||
//
|
//
|
||||||
// USAGE:
|
// USAGE:
|
||||||
// greet describeit [arguments...]
|
// greet describeit [command options] [arguments...]
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// This is how we describe describeit the function
|
// This is how we describe describeit the function
|
||||||
|
//
|
||||||
|
// OPTIONS:
|
||||||
|
// --help, -h show help (default: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleApp_Run_noAction() {
|
func ExampleApp_Run_noAction() {
|
||||||
|
11
command.go
11
command.go
@ -170,7 +170,7 @@ func (c *Command) Run(ctx *Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if c.Action == nil {
|
if c.Action == nil {
|
||||||
c.Action = helpSubcommand.Action
|
c.Action = helpCommand.Action
|
||||||
}
|
}
|
||||||
|
|
||||||
cCtx.Command = c
|
cCtx.Command = c
|
||||||
@ -284,7 +284,7 @@ func (c *Command) startApp(ctx *Context) error {
|
|||||||
if c.Action != nil {
|
if c.Action != nil {
|
||||||
app.Action = c.Action
|
app.Action = c.Action
|
||||||
} else {
|
} else {
|
||||||
app.Action = helpSubcommand.Action
|
app.Action = helpCommand.Action
|
||||||
}
|
}
|
||||||
app.OnUsageError = c.OnUsageError
|
app.OnUsageError = c.OnUsageError
|
||||||
|
|
||||||
@ -298,7 +298,12 @@ func (c *Command) startApp(ctx *Context) error {
|
|||||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||||
if c.flagCategories == nil {
|
if c.flagCategories == nil {
|
||||||
return []VisibleFlagCategory{}
|
c.flagCategories = newFlagCategories()
|
||||||
|
for _, fl := range c.Flags {
|
||||||
|
if cf, ok := fl.(CategorizableFlag); ok {
|
||||||
|
c.flagCategories.AddFlag(cf.GetCategory(), cf)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return c.flagCategories.VisibleCategories()
|
return c.flagCategories.VisibleCategories()
|
||||||
}
|
}
|
||||||
|
@ -82,12 +82,10 @@ DESCRIPTION:
|
|||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{range .VisibleFlagCategories}}
|
||||||
{{if .Name}}{{.Name}}
|
{{if .Name}}{{.Name}}
|
||||||
{{end}}{{range .Flags}}{{.}}
|
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
CommandHelpTemplate is the text template for the command help topic. cli.go
|
CommandHelpTemplate is the text template for the command help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
@ -161,8 +159,7 @@ COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
|||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
||||||
{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
cli.go uses text/template to render templates. You can render custom help
|
cli.go uses text/template to render templates. You can render custom help
|
||||||
@ -568,6 +565,7 @@ type Command struct {
|
|||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
CustomHelpTemplate string
|
CustomHelpTemplate string
|
||||||
|
|
||||||
// Has unexported fields.
|
// Has unexported fields.
|
||||||
}
|
}
|
||||||
Command is a subcommand for a cli.App.
|
Command is a subcommand for a cli.App.
|
||||||
@ -586,6 +584,13 @@ func (c *Command) Run(ctx *Context) (err error)
|
|||||||
Run invokes the command given the context, parses ctx.Args() to generate
|
Run invokes the command given the context, parses ctx.Args() to generate
|
||||||
command-specific flags
|
command-specific flags
|
||||||
|
|
||||||
|
func (c *Command) VisibleCategories() []CommandCategory
|
||||||
|
VisibleCategories returns a slice of categories and commands that are
|
||||||
|
Hidden=false
|
||||||
|
|
||||||
|
func (c *Command) VisibleCommands() []*Command
|
||||||
|
VisibleCommands returns a slice of the Commands with Hidden=false
|
||||||
|
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
||||||
VisibleFlagCategories returns a slice containing all the visible flag
|
VisibleFlagCategories returns a slice containing all the visible flag
|
||||||
categories with the flags they contain
|
categories with the flags they contain
|
||||||
|
70
help.go
70
help.go
@ -15,6 +15,15 @@ const (
|
|||||||
helpAlias = "h"
|
helpAlias = "h"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// this instance is to avoid recursion in the ShowCommandHelp which can
|
||||||
|
// add a help command again
|
||||||
|
var helpCommandDontUse = &Command{
|
||||||
|
Name: helpName,
|
||||||
|
Aliases: []string{helpAlias},
|
||||||
|
Usage: "Shows a list of commands or help for one command",
|
||||||
|
ArgsUsage: "[command]",
|
||||||
|
}
|
||||||
|
|
||||||
var helpCommand = &Command{
|
var helpCommand = &Command{
|
||||||
Name: helpName,
|
Name: helpName,
|
||||||
Aliases: []string{helpAlias},
|
Aliases: []string{helpAlias},
|
||||||
@ -22,26 +31,43 @@ var helpCommand = &Command{
|
|||||||
ArgsUsage: "[command]",
|
ArgsUsage: "[command]",
|
||||||
Action: func(cCtx *Context) error {
|
Action: func(cCtx *Context) error {
|
||||||
args := cCtx.Args()
|
args := cCtx.Args()
|
||||||
if args.Present() {
|
argsPresent := args.First() != ""
|
||||||
return ShowCommandHelp(cCtx, args.First())
|
firstArg := args.First()
|
||||||
|
|
||||||
|
// This action can be triggered by a "default" action of a command
|
||||||
|
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||||
|
//
|
||||||
|
// 1 $ app
|
||||||
|
// 2 $ app help
|
||||||
|
// 3 $ app foo
|
||||||
|
// 4 $ app help foo
|
||||||
|
// 5 $ app foo help
|
||||||
|
|
||||||
|
// Case 4. when executing a help command set the context to parent
|
||||||
|
// to allow resolution of subsequent args. This will transform
|
||||||
|
// $ app help foo
|
||||||
|
// to
|
||||||
|
// $ app foo
|
||||||
|
// which will then be handled as case 3
|
||||||
|
if cCtx.Command.Name == helpName || cCtx.Command.Name == helpAlias {
|
||||||
|
cCtx = cCtx.parentContext
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = ShowAppHelp(cCtx)
|
// Case 4. $ app hello foo
|
||||||
return nil
|
// foo is the command for which help needs to be shown
|
||||||
},
|
if argsPresent {
|
||||||
}
|
return ShowCommandHelp(cCtx, firstArg)
|
||||||
|
|
||||||
var helpSubcommand = &Command{
|
|
||||||
Name: helpName,
|
|
||||||
Aliases: []string{helpAlias},
|
|
||||||
Usage: "Shows a list of commands or help for one command",
|
|
||||||
ArgsUsage: "[command]",
|
|
||||||
Action: func(cCtx *Context) error {
|
|
||||||
args := cCtx.Args()
|
|
||||||
if args.Present() {
|
|
||||||
return ShowCommandHelp(cCtx, args.First())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Case 1 & 2
|
||||||
|
// Special case when running help on main app itself as opposed to indivdual
|
||||||
|
// commands/subcommands
|
||||||
|
if cCtx.parentContext.App == nil {
|
||||||
|
_ = ShowAppHelp(cCtx)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 3, 5
|
||||||
return ShowSubcommandHelp(cCtx)
|
return ShowSubcommandHelp(cCtx)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -212,9 +238,19 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
|||||||
|
|
||||||
for _, c := range ctx.App.Commands {
|
for _, c := range ctx.App.Commands {
|
||||||
if c.HasName(command) {
|
if c.HasName(command) {
|
||||||
|
if !ctx.App.HideHelpCommand && !c.HasName(helpName) && len(c.Subcommands) != 0 {
|
||||||
|
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
||||||
|
}
|
||||||
|
if !ctx.App.HideHelp && HelpFlag != nil {
|
||||||
|
c.appendFlag(HelpFlag)
|
||||||
|
}
|
||||||
templ := c.CustomHelpTemplate
|
templ := c.CustomHelpTemplate
|
||||||
if templ == "" {
|
if templ == "" {
|
||||||
templ = CommandHelpTemplate
|
if len(c.Subcommands) == 0 {
|
||||||
|
templ = CommandHelpTemplate
|
||||||
|
} else {
|
||||||
|
templ = SubcommandHelpTemplate
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HelpPrinter(ctx.App.Writer, templ, c)
|
HelpPrinter(ctx.App.Writer, templ, c)
|
||||||
|
12
help_test.go
12
help_test.go
@ -186,7 +186,7 @@ func Test_helpSubcommand_Action_ErrorIfNoTopic(t *testing.T) {
|
|||||||
|
|
||||||
c := NewContext(app, set, nil)
|
c := NewContext(app, set, nil)
|
||||||
|
|
||||||
err := helpSubcommand.Action(c)
|
err := helpCommand.Action(c)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expected error from helpCommand.Action(), but got nil")
|
t.Fatalf("expected error from helpCommand.Action(), but got nil")
|
||||||
@ -248,7 +248,7 @@ func TestShowCommandHelp_HelpPrinter(t *testing.T) {
|
|||||||
fmt.Fprint(w, "yo")
|
fmt.Fprint(w, "yo")
|
||||||
},
|
},
|
||||||
command: "",
|
command: "",
|
||||||
wantTemplate: SubcommandHelpTemplate,
|
wantTemplate: AppHelpTemplate,
|
||||||
wantOutput: "yo",
|
wantOutput: "yo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -333,7 +333,7 @@ func TestShowCommandHelp_HelpPrinterCustom(t *testing.T) {
|
|||||||
fmt.Fprint(w, "yo")
|
fmt.Fprint(w, "yo")
|
||||||
},
|
},
|
||||||
command: "",
|
command: "",
|
||||||
wantTemplate: SubcommandHelpTemplate,
|
wantTemplate: AppHelpTemplate,
|
||||||
wantOutput: "yo",
|
wantOutput: "yo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1357,10 +1357,13 @@ DESCRIPTION:
|
|||||||
and a description long
|
and a description long
|
||||||
enough to wrap in this test
|
enough to wrap in this test
|
||||||
case
|
case
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--help, -h show help (default: false)
|
||||||
`
|
`
|
||||||
|
|
||||||
if output.String() != expected {
|
if output.String() != expected {
|
||||||
t.Errorf("Unexpected wrapping, got:\n%s\nexpected: %s",
|
t.Errorf("Unexpected wrapping, got:\n%s\nexpected:\n%s",
|
||||||
output.String(), expected)
|
output.String(), expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1426,7 +1429,6 @@ USAGE:
|
|||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
--help, -h show help (default: false)
|
--help, -h show help (default: false)
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
if output.String() != expected {
|
if output.String() != expected {
|
||||||
|
@ -54,12 +54,10 @@ DESCRIPTION:
|
|||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{range .VisibleFlagCategories}}
|
||||||
{{if .Name}}{{.Name}}
|
{{if .Name}}{{.Name}}
|
||||||
{{end}}{{range .Flags}}{{.}}
|
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
|
|
||||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
@ -80,8 +78,7 @@ COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
|||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
||||||
{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
|
|
||||||
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
||||||
|
17
testdata/godoc-v2.x.txt
vendored
17
testdata/godoc-v2.x.txt
vendored
@ -82,12 +82,10 @@ DESCRIPTION:
|
|||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{range .VisibleFlagCategories}}
|
||||||
{{if .Name}}{{.Name}}
|
{{if .Name}}{{.Name}}
|
||||||
{{end}}{{range .Flags}}{{.}}
|
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
||||||
{{end}}{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
CommandHelpTemplate is the text template for the command help topic. cli.go
|
CommandHelpTemplate is the text template for the command help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
@ -161,8 +159,7 @@ COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
|||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
||||||
{{end}}{{end}}
|
|
||||||
`
|
`
|
||||||
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
cli.go uses text/template to render templates. You can render custom help
|
cli.go uses text/template to render templates. You can render custom help
|
||||||
@ -568,6 +565,7 @@ type Command struct {
|
|||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
CustomHelpTemplate string
|
CustomHelpTemplate string
|
||||||
|
|
||||||
// Has unexported fields.
|
// Has unexported fields.
|
||||||
}
|
}
|
||||||
Command is a subcommand for a cli.App.
|
Command is a subcommand for a cli.App.
|
||||||
@ -586,6 +584,13 @@ func (c *Command) Run(ctx *Context) (err error)
|
|||||||
Run invokes the command given the context, parses ctx.Args() to generate
|
Run invokes the command given the context, parses ctx.Args() to generate
|
||||||
command-specific flags
|
command-specific flags
|
||||||
|
|
||||||
|
func (c *Command) VisibleCategories() []CommandCategory
|
||||||
|
VisibleCategories returns a slice of categories and commands that are
|
||||||
|
Hidden=false
|
||||||
|
|
||||||
|
func (c *Command) VisibleCommands() []*Command
|
||||||
|
VisibleCommands returns a slice of the Commands with Hidden=false
|
||||||
|
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
||||||
VisibleFlagCategories returns a slice containing all the visible flag
|
VisibleFlagCategories returns a slice containing all the visible flag
|
||||||
categories with the flags they contain
|
categories with the flags they contain
|
||||||
|
Loading…
x
Reference in New Issue
Block a user