From bb7601a3ffdc78bbe7efe7e77a196e09cf3607c7 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 15 Nov 2016 11:18:33 -0500 Subject: [PATCH] exit with status 1 if help is called on an invalid command. Signed-off-by: Daniel Nephin --- cli/cobra.go | 19 +++++++++++++++++++ cmd/docker/docker_test.go | 27 +++++++++++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/cli/cobra.go b/cli/cobra.go index 324c0d7b2d..139845cb1b 100644 --- a/cli/cobra.go +++ b/cli/cobra.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "strings" "github.com/spf13/cobra" ) @@ -17,6 +18,7 @@ func SetupRootCommand(rootCmd *cobra.Command) { rootCmd.SetUsageTemplate(usageTemplate) rootCmd.SetHelpTemplate(helpTemplate) rootCmd.SetFlagErrorFunc(FlagErrorFunc) + rootCmd.SetHelpCommand(helpCommand) rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") @@ -39,6 +41,23 @@ func FlagErrorFunc(cmd *cobra.Command, err error) error { } } +var helpCommand = &cobra.Command{ + Use: "help [command]", + Short: "Help about the command", + PersistentPreRun: func(cmd *cobra.Command, args []string) {}, + PersistentPostRun: func(cmd *cobra.Command, args []string) {}, + RunE: func(c *cobra.Command, args []string) error { + cmd, args, e := c.Root().Find(args) + if cmd == nil || e != nil || len(args) > 0 { + return fmt.Errorf("unknown help topic: %v", strings.Join(args, " ")) + } + + helpFunc := cmd.HelpFunc() + helpFunc(cmd, args) + return nil + }, +} + func hasSubCommands(cmd *cobra.Command) bool { return len(operationSubCommands(cmd)) > 0 } diff --git a/cmd/docker/docker_test.go b/cmd/docker/docker_test.go index 47e24eb0da..8738f6005d 100644 --- a/cmd/docker/docker_test.go +++ b/cmd/docker/docker_test.go @@ -1,13 +1,14 @@ package main import ( + "io/ioutil" "os" "testing" "github.com/Sirupsen/logrus" - "github.com/docker/docker/utils" - "github.com/docker/docker/cli/command" + "github.com/docker/docker/pkg/testutil/assert" + "github.com/docker/docker/utils" ) func TestClientDebugEnabled(t *testing.T) { @@ -16,14 +17,16 @@ func TestClientDebugEnabled(t *testing.T) { cmd := newDockerCommand(&command.DockerCli{}) cmd.Flags().Set("debug", "true") - if err := cmd.PersistentPreRunE(cmd, []string{}); err != nil { - t.Fatalf("Unexpected error: %s", err.Error()) - } - - if os.Getenv("DEBUG") != "1" { - t.Fatal("expected debug enabled, got false") - } - if logrus.GetLevel() != logrus.DebugLevel { - t.Fatalf("expected logrus debug level, got %v", logrus.GetLevel()) - } + err := cmd.PersistentPreRunE(cmd, []string{}) + assert.NilError(t, err) + assert.Equal(t, os.Getenv("DEBUG"), "1") + assert.Equal(t, logrus.GetLevel(), logrus.DebugLevel) +} + +func TestExitStatusForInvalidSubcommandWithHelpFlag(t *testing.T) { + discard := ioutil.Discard + cmd := newDockerCommand(command.NewDockerCli(os.Stdin, discard, discard)) + cmd.SetArgs([]string{"help", "invalid"}) + err := cmd.Execute() + assert.Error(t, err, "unknown help topic: invalid") }