From 07be8145cc894ca8a4063b4445ded2fab319d15d Mon Sep 17 00:00:00 2001 From: spf13 Date: Tue, 17 Jun 2014 12:28:42 -0400 Subject: [PATCH] Adding support for --help --- README.md | 10 ++++---- cobra_test.go | 63 +++++++++++++++++++++++++++++++++++++++++++++------ command.go | 16 ++++++++++++- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0d76bd5f..5e939586 100644 --- a/README.md +++ b/README.md @@ -298,11 +298,11 @@ embeds the usage as part of it's output. hugo [command] Available Commands: - server :: Hugo runs it's own a webserver to render the files - version :: Print the version number of Hugo - check :: Check content in the source directory - benchmark :: Benchmark hugo by building a site a number of times - help [command] :: Help about any command + server Hugo runs it's own a webserver to render the files + version Print the version number of Hugo + check Check content in the source directory + benchmark Benchmark hugo by building a site a number of times + help [command] Help about any command Available Flags: -b, --base-url="": hostname (and path) to the root eg. http://spf13.com/ diff --git a/cobra_test.go b/cobra_test.go index b479fe19..3f50dff9 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -114,11 +114,49 @@ func initializeWithRootCmd() *Command { tt, tp, te, rootcalled = nil, nil, nil, false flagInit() cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot") - cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag intthree") + cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot") commandInit() return cmdRootWithRun } +type resulter struct { + Error error + Output string + Command *Command +} + +func fullSetupTest(input string) resulter { + c := initializeWithRootCmd() + + return fullTester(c, input) +} + +func noRRSetupTest(input string) resulter { + c := initialize() + + return fullTester(c, input) +} + +func fullTester(c *Command, input string) resulter { + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs(strings.Split(input, " ")) + + err := c.Execute() + output := buf.String() + + return resulter{err, output, c} +} + +func checkResultContains(t *testing.T, x resulter, check string) { + if !strings.Contains(x.Output, check) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", check, x.Output) + } +} + func checkOutputContains(t *testing.T, c *Command, check string) { buf := new(bytes.Buffer) c.SetOutput(buf) @@ -448,12 +486,23 @@ func TestRootFlags(t *testing.T) { } func TestRootHelp(t *testing.T) { - fmt.Println("testing root help") - c := initializeWithRootCmd() - c.AddCommand(cmdPrint, cmdEcho) - c.SetArgs(strings.Split("--help", " ")) - e := c.Execute() - fmt.Println(e) + x := fullSetupTest("--help") + + checkResultContains(t, x, "Available Commands:") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } + + x = fullSetupTest("echo --help") + + checkResultContains(t, x, "Available Commands:") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } + +} checkOutputContains(t, c, "Available Commands:") } diff --git a/command.go b/command.go index 426b034a..538b6b7b 100644 --- a/command.go +++ b/command.go @@ -63,6 +63,7 @@ type Command struct { helpTemplate string // Can be defined by Application helpFunc func(*Command, []string) // Help can be defined by application helpCommand *Command // The help command + helpFlagVal bool } // os.Args[1:] by default, if desired, can be overridden @@ -301,6 +302,12 @@ func (c *Command) execute(a []string) (err error) { if err != nil { return err } else { + // If help is called, regardless of other flags, we print that + if c.helpFlagVal { + c.Help() + return nil + } + argWoFlags := c.Flags().Args() c.Run(c, argWoFlags) return nil @@ -349,6 +356,13 @@ func (c *Command) Execute() (err error) { c.Usage() return e } else { + + // If help is called, regardless of other flags, we print that + if c.helpFlagVal { + c.Help() + return nil + } + argWoFlags := c.Flags().Args() if len(argWoFlags) > 0 { c.Usage() @@ -555,6 +569,7 @@ func (c *Command) Flags() *flag.FlagSet { c.flagErrorBuf = new(bytes.Buffer) } c.flags.SetOutput(c.flagErrorBuf) + c.flags.BoolVar(&c.helpFlagVal, "help", false, "help for "+c.Name()) } return c.flags } @@ -617,7 +632,6 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) { // Parses persistent flag tree & local flags func (c *Command) ParseFlags(args []string) (err error) { c.mergePersistentFlags() - err = c.Flags().Parse(args) // The upstream library adds spaces to the error