From a2845e7f7a251714c387677b64cc73c8fd687833 Mon Sep 17 00:00:00 2001 From: spf13 Date: Mon, 30 Sep 2013 21:54:46 -0400 Subject: [PATCH] fixed spf13/cobra#1 spf13/hugo#88 --- cobra_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++--- command.go | 32 ++++++++++++++++-------------- commander.go | 40 ++++++++++++++++++++++++++++---------- 3 files changed, 98 insertions(+), 28 deletions(-) diff --git a/cobra_test.go b/cobra_test.go index 001c8256..f757a93c 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -10,11 +10,11 @@ import ( var _ = fmt.Println var tp, te, tt, t1 []string -var flagb1, flagb2, flagb3 bool +var flagb1, flagb2, flagb3, flagbr bool var flags1, flags2, flags3 string -var flagi1, flagi2, flagi3 int +var flagi1, flagi2, flagi3, flagir int var globalFlag1 bool -var flagEcho bool +var flagEcho, rootcalled bool var cmdPrint = &Command{ Use: "print [string to print]", @@ -41,6 +41,15 @@ var cmdTimes = &Command{ Run: timesRunner, } +var cmdRoot = &Command{ + Use: "cobra-test", + Short: "The root can run it's own function", + Long: "The root description for help", + Run: func(cmd *Command, args []string) { + rootcalled = true + }, +} + func timesRunner(cmd *Command, args []string) { tt = args } @@ -49,6 +58,7 @@ func flagInit() { cmdEcho.ResetFlags() cmdPrint.ResetFlags() cmdTimes.ResetFlags() + cmdRoot.ResetFlags() cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone") cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo") cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree") @@ -75,6 +85,17 @@ func initialize() *Commander { return c } +func initializeWithRootCmd() *Commander { + cmdRoot.ResetCommands() + tt, tp, te, rootcalled = nil, nil, nil, false + cmdRoot.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot") + cmdRoot.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag intthree") + var c = cmdRoot.ToCommander() + flagInit() + commandInit() + return c +} + func TestSingleCommand(t *testing.T) { c := initialize() c.AddCommand(cmdPrint, cmdEcho) @@ -292,3 +313,30 @@ func TestHelpCommand(t *testing.T) { t.Errorf("Wrong error message displayed, \n %s", buf.String()) } } + +func TestCommandToCommander(t *testing.T) { + c := initializeWithRootCmd() + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs([]string(nil)) + c.Execute() + + if rootcalled != true { + t.Errorf("Root Function was not called") + } +} + +func TestRootFlags(t *testing.T) { + c := initializeWithRootCmd() + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs(strings.Split("-i 17 -b", " ")) + c.Execute() + + if flagbr != true { + t.Errorf("flag value should be true, %v given", flagbr) + } + + if flagir != 17 { + t.Errorf("flag value should be 17, %d given", flagir) + } + +} diff --git a/command.go b/command.go index 1bc3dbf6..01526269 100644 --- a/command.go +++ b/command.go @@ -104,7 +104,7 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) { // if commander returned and not appropriately matched return nil & error if commandFound.Name() == c.Name() && commandFound.Name() != arrs[0] { - return nil, a, fmt.Errorf("Command not found") + return nil, a, fmt.Errorf("unknown command %q\nRun 'help' for usage.\n", a[0]) } return commandFound, a, nil @@ -138,26 +138,28 @@ func (c *Command) Out() io.Writer { } // execute the command determined by args and the command tree -func (c *Command) execute(args []string) (err error) { - err = fmt.Errorf("unknown subcommand %q\nRun 'help' for usage.\n", args[0]) +func (c *Command) findAndExecute(args []string) (err error) { + cmd, a, e := c.Find(args) + if e != nil { + return e + } + return cmd.execute(a) +} + +func (c *Command) execute(a []string) (err error) { if c == nil { return fmt.Errorf("Called Execute() on a nil Command") } - cmd, a, e := c.Find(args) - if e == nil { - err = cmd.ParseFlags(a) - if err != nil { - return err - } else { - argWoFlags := cmd.Flags().Args() - cmd.Run(cmd, argWoFlags) - return nil - } + err = c.ParseFlags(a) + if err != nil { + return err + } else { + argWoFlags := c.Flags().Args() + c.Run(c, argWoFlags) + return nil } - err = e - return err } // Used for testing diff --git a/commander.go b/commander.go index 2b415281..abe0e590 100644 --- a/commander.go +++ b/commander.go @@ -78,20 +78,39 @@ func (c *Commander) Execute() (err error) { // initialize help as the last point possible to allow for user // overriding c.initHelp() + var args []string + if len(c.args) == 0 { - if len(os.Args) == 1 { - // If only the executable is called and the root is runnable, run it - if c.Runnable() { - argWoFlags := c.Flags().Args() - c.Run(c.cmd, argWoFlags) - } else { - c.Usage() - } + args = os.Args[1:] + } else { + args = c.args + } + + if len(args) == 0 { + // Only the executable is called and the root is runnable, run it + if c.Runnable() { + err = c.execute([]string(nil)) } else { - err = c.execute(os.Args[1:]) + c.Usage() } } else { - err = c.execute(c.args) + err = c.findAndExecute(args) + } + + // Now handle the case where the root is runnable and only flags are provided + if err != nil && c.Runnable() { + e := c.ParseFlags(args) + if e != nil { + return e + } else { + argWoFlags := c.Flags().Args() + if len(argWoFlags) > 0 { + c.Usage() + } else { + c.Run(c.cmd, argWoFlags) + err = nil + } + } } if err != nil { @@ -99,6 +118,7 @@ func (c *Commander) Execute() (err error) { c.Printf("%v: invalid command %#q\n", c.Root().Name(), os.Args[1:]) c.Printf("Run '%v help' for usage\n", c.Root().Name()) } + return }