Sets a subcommand's parent cmd

This allows the help output to show the correct/full command path to the
subcommand.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2015-06-20 19:59:54 -04:00
parent f9982619cc
commit 758ad1e836
3 changed files with 51 additions and 4 deletions

View File

@ -735,6 +735,36 @@ func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
} }
} }
func TestApp_Run_SubcommandFullPath(t *testing.T) {
app := cli.NewApp()
buf := new(bytes.Buffer)
app.Writer = buf
subCmd := cli.Command{
Name: "bar",
Usage: "does bar things",
}
cmd := cli.Command{
Name: "foo",
Description: "foo commands",
Subcommands: []cli.Command{subCmd},
}
app.Commands = []cli.Command{cmd}
err := app.Run([]string{"command", "foo", "bar", "--help"})
if err != nil {
t.Error(err)
}
output := buf.String()
if !strings.Contains(output, "foo bar - does bar things") {
t.Errorf("expected full path to subcommand: %s", output)
}
if !strings.Contains(output, "command foo bar [arguments...]") {
t.Errorf("expected full path to subcommand: %s", output)
}
}
func TestApp_Run_Help(t *testing.T) { func TestApp_Run_Help(t *testing.T) {
var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}} var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}

View File

@ -36,11 +36,21 @@ type Command struct {
SkipFlagParsing bool SkipFlagParsing bool
// Boolean to hide built-in help command // Boolean to hide built-in help command
HideHelp bool HideHelp bool
commandNamePath []string
}
// Returns the full name of the command.
// For subcommands this ensures that parent commands are part of the command path
func (c Command) FullName() string {
if c.commandNamePath == nil {
return c.Name
}
return strings.Join(c.commandNamePath, " ")
} }
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags // Invokes the command given the context, parses ctx.Args() to generate command-specific flags
func (c Command) Run(ctx *Context) error { func (c Command) Run(ctx *Context) error {
if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil { if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil {
return c.startApp(ctx) return c.startApp(ctx)
} }
@ -179,5 +189,12 @@ func (c Command) startApp(ctx *Context) error {
app.Action = helpSubcommand.Action app.Action = helpSubcommand.Action
} }
var newCmds []Command
for _, cc := range app.Commands {
cc.commandNamePath = []string{c.Name, cc.Name}
newCmds = append(newCmds, cc)
}
app.Commands = newCmds
return app.RunAsSubcommand(ctx) return app.RunAsSubcommand(ctx)
} }

View File

@ -38,10 +38,10 @@ COPYRIGHT:
// 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.
var CommandHelpTemplate = `NAME: var CommandHelpTemplate = `NAME:
{{.Name}} - {{.Usage}} {{.FullName}} - {{.Usage}}
USAGE: USAGE:
command {{.Name}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}} command {{.FullName}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{.Description}}{{end}}{{if .Flags}} {{.Description}}{{end}}{{if .Flags}}