Merge pull request #399 from codegangsta/exit-nonzero-for-unknown-subcommand
Exit non-zero if a unknown subcommand is given
This commit is contained in:
commit
63ed8b0bde
10
CHANGELOG.md
10
CHANGELOG.md
@ -11,11 +11,15 @@
|
||||
|
||||
### Changed
|
||||
- `Float64Flag`, `IntFlag`, and `DurationFlag` default values are no longer
|
||||
quoted in help text output.
|
||||
quoted in help text output.
|
||||
- All flag types now include `(default: {value})` strings following usage when a
|
||||
default value can be (reasonably) detected.
|
||||
default value can be (reasonably) detected.
|
||||
- `IntSliceFlag` and `StringSliceFlag` usage strings are now more consistent
|
||||
with non-slice flag types
|
||||
with non-slice flag types
|
||||
- Apps now exit with a code of 3 if an unknown subcommand is specified
|
||||
(previously they printed "No help topic for...", but still exited 0. This
|
||||
makes it easier to script around apps built using `cli` since they can trust
|
||||
that a 0 exit code indicated a successful execution.
|
||||
|
||||
## [1.16.0] - 2016-05-02
|
||||
### Added
|
||||
|
32
help.go
32
help.go
@ -82,10 +82,10 @@ var helpCommand = Command{
|
||||
Action: func(c *Context) error {
|
||||
args := c.Args()
|
||||
if args.Present() {
|
||||
ShowCommandHelp(c, args.First())
|
||||
} else {
|
||||
ShowAppHelp(c)
|
||||
return ShowCommandHelp(c, args.First())
|
||||
}
|
||||
|
||||
ShowAppHelp(c)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@ -98,11 +98,10 @@ var helpSubcommand = Command{
|
||||
Action: func(c *Context) error {
|
||||
args := c.Args()
|
||||
if args.Present() {
|
||||
ShowCommandHelp(c, args.First())
|
||||
} else {
|
||||
ShowSubcommandHelp(c)
|
||||
return ShowCommandHelp(c, args.First())
|
||||
}
|
||||
return nil
|
||||
|
||||
return ShowSubcommandHelp(c)
|
||||
},
|
||||
}
|
||||
|
||||
@ -131,30 +130,31 @@ func DefaultAppComplete(c *Context) {
|
||||
}
|
||||
|
||||
// Prints help for the given command
|
||||
func ShowCommandHelp(ctx *Context, command string) {
|
||||
func ShowCommandHelp(ctx *Context, command string) error {
|
||||
// show the subcommand help for a command with subcommands
|
||||
if command == "" {
|
||||
HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, c := range ctx.App.Commands {
|
||||
if c.HasName(command) {
|
||||
HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.App.CommandNotFound != nil {
|
||||
ctx.App.CommandNotFound(ctx, command)
|
||||
} else {
|
||||
fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
|
||||
if ctx.App.CommandNotFound == nil {
|
||||
return NewExitError(fmt.Sprintf("No help topic for '%v'", command), 3)
|
||||
}
|
||||
|
||||
ctx.App.CommandNotFound(ctx, command)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prints help for the given subcommand
|
||||
func ShowSubcommandHelp(c *Context) {
|
||||
ShowCommandHelp(c, c.Command.Name)
|
||||
func ShowSubcommandHelp(c *Context) error {
|
||||
return ShowCommandHelp(c, c.Command.Name)
|
||||
}
|
||||
|
||||
// Prints the version number of the App
|
||||
|
57
help_test.go
57
help_test.go
@ -2,6 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@ -112,6 +113,62 @@ func Test_Version_Custom_Flags(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_helpCommand_Action_ErrorIfNoTopic(t *testing.T) {
|
||||
app := NewApp()
|
||||
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Parse([]string{"foo"})
|
||||
|
||||
c := NewContext(app, set, nil)
|
||||
|
||||
err := helpCommand.Action.(func(*Context) error)(c)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("expected error from helpCommand.Action(), but got nil")
|
||||
}
|
||||
|
||||
exitErr, ok := err.(*ExitError)
|
||||
if !ok {
|
||||
t.Fatalf("expected ExitError from helpCommand.Action(), but instead got: %v", err.Error())
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(exitErr.Error(), "No help topic for") {
|
||||
t.Fatalf("expected an unknown help topic error, but got: %v", exitErr.Error())
|
||||
}
|
||||
|
||||
if exitErr.exitCode != 3 {
|
||||
t.Fatalf("expected exit value = 3, got %d instead", exitErr.exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_helpSubcommand_Action_ErrorIfNoTopic(t *testing.T) {
|
||||
app := NewApp()
|
||||
|
||||
set := flag.NewFlagSet("test", 0)
|
||||
set.Parse([]string{"foo"})
|
||||
|
||||
c := NewContext(app, set, nil)
|
||||
|
||||
err := helpSubcommand.Action.(func(*Context) error)(c)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("expected error from helpCommand.Action(), but got nil")
|
||||
}
|
||||
|
||||
exitErr, ok := err.(*ExitError)
|
||||
if !ok {
|
||||
t.Fatalf("expected ExitError from helpCommand.Action(), but instead got: %v", err.Error())
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(exitErr.Error(), "No help topic for") {
|
||||
t.Fatalf("expected an unknown help topic error, but got: %v", exitErr.Error())
|
||||
}
|
||||
|
||||
if exitErr.exitCode != 3 {
|
||||
t.Fatalf("expected exit value = 3, got %d instead", exitErr.exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowAppHelp_HiddenCommand(t *testing.T) {
|
||||
app := &App{
|
||||
Commands: []Command{
|
||||
|
Loading…
Reference in New Issue
Block a user