From b28cb1a6dd757cc84aeaefddf32e01ca60245a87 Mon Sep 17 00:00:00 2001 From: Maciej Szulik Date: Fri, 19 Dec 2014 21:55:52 +0100 Subject: [PATCH] bump(github.com/spf13/cobra):e1e66f7b4e667751cf530ddb6e72b79d6eeb0235 --- Godeps/Godeps.json | 2 +- .../src/github.com/spf13/cobra/README.md | 4 +- .../src/github.com/spf13/cobra/cobra.go | 6 +++ .../src/github.com/spf13/cobra/cobra_test.go | 46 ++++++++++++++++++ .../src/github.com/spf13/cobra/command.go | 48 ++++++++++++++----- 5 files changed, 93 insertions(+), 13 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 6de24af7789..02e241bc950 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -161,7 +161,7 @@ }, { "ImportPath": "github.com/spf13/cobra", - "Rev": "b1e90a7943957b51bb96a13b44b844475bcf95c0" + "Rev": "e1e66f7b4e667751cf530ddb6e72b79d6eeb0235" }, { "ImportPath": "github.com/spf13/pflag", diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/README.md b/Godeps/_workspace/src/github.com/spf13/cobra/README.md index 67c4eff218c..528233d3874 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/README.md +++ b/Godeps/_workspace/src/github.com/spf13/cobra/README.md @@ -120,7 +120,9 @@ In this example we are attaching it to the root, but commands can be attached at ### Assign flags to a command -Since the flags are defined and used in different locations, we need to define a variable outside with the correct scope to assign the flag to work with. +Since the flags are defined and used in different locations, we need to +define a variable outside with the correct scope to assign the flag to +work with. var Verbose bool var Source string diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go b/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go index e03b4969e25..1b5ca36024a 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go @@ -31,12 +31,16 @@ var initializers []func() // Set this to true to enable it var EnablePrefixMatching bool = false +//OnInitialize takes a series of func() arguments and appends them to a slice of func(). func OnInitialize(y ...func()) { for _, x := range y { initializers = append(initializers, x) } } +//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans, +//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as +//ints and then compared. func Gt(a interface{}, b interface{}) bool { var left, right int64 av := reflect.ValueOf(a) @@ -64,6 +68,7 @@ func Gt(a interface{}, b interface{}) bool { return left > right } +//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic. func Eq(a interface{}, b interface{}) bool { av := reflect.ValueOf(a) bv := reflect.ValueOf(b) @@ -79,6 +84,7 @@ func Eq(a interface{}, b interface{}) bool { return false } +//rpad adds padding to the right of a string func rpad(s string, padding int) string { template := fmt.Sprintf("%%-%ds", padding) return fmt.Sprintf(template, s) diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go index 05d18d0c57c..dd44812c570 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go @@ -136,6 +136,24 @@ func noRRSetupTest(input string) resulter { return fullTester(c, input) } +func rootOnlySetupTest(input string) resulter { + c := initializeWithRootCmd() + + return simpleTester(c, input) +} + +func simpleTester(c *Command, input string) resulter { + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + c.SetArgs(strings.Split(input, " ")) + + err := c.Execute() + output := buf.String() + + return resulter{err, output, c} +} + func fullTester(c *Command, input string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input @@ -156,6 +174,12 @@ func checkResultContains(t *testing.T, x resulter, check string) { } } +func checkResultOmits(t *testing.T, x resulter, check string) { + if strings.Contains(x.Output, check) { + t.Errorf("Unexpected response.\nExpecting to omit: \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) @@ -437,6 +461,7 @@ func TestRootHelp(t *testing.T) { x := fullSetupTest("--help") checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about that command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -445,6 +470,7 @@ func TestRootHelp(t *testing.T) { x = fullSetupTest("echo --help") checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about that command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -452,6 +478,26 @@ func TestRootHelp(t *testing.T) { } +func TestRootNoCommandHelp(t *testing.T) { + x := rootOnlySetupTest("--help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about that command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } + + x = rootOnlySetupTest("echo --help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about that command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } +} + func TestFlagsBeforeCommand(t *testing.T) { // short without space x := fullSetupTest("-i10 echo") diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/command.go b/Godeps/_workspace/src/github.com/spf13/cobra/command.go index 1337065d700..a3a01ad59dc 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/command.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/command.go @@ -11,9 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Commands similar to git, go tools and other modern CLI tools -// inspired by go, go-Commander, gh and subcommand - +//Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. +//In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. package cobra import ( @@ -57,8 +56,9 @@ type Command struct { commandsMaxCommandPathLen int flagErrorBuf *bytes.Buffer + cmdErrorBuf *bytes.Buffer - args []string + args []string // actual args parsed from flags output *io.Writer // nil means stderr; use Out() method instead usageFunc func(*Command) error // Usage can be defined by application usageTemplate string // Can be defined by Application @@ -172,6 +172,7 @@ func (c *Command) UsagePadding() int { var minCommandPathPadding int = 11 +// func (c *Command) CommandPathPadding() int { if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen { return minCommandPathPadding @@ -203,9 +204,9 @@ Available Commands: {{range .Commands}}{{if .Runnable}} {{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }} Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}} -{{end}} +{{end}}{{ if .HasSubCommands }} Use "{{.Root.Name}} help [command]" for more information about that command. -` +{{end}}` } } @@ -355,10 +356,22 @@ func (c *Command) execute(a []string) (err error) { err = c.ParseFlags(a) if err != nil { + // We're writing subcommand usage to root command's error buffer to have it displayed to the user + r := c.Root() + if r.cmdErrorBuf == nil { + r.cmdErrorBuf = new(bytes.Buffer) + } + // for writing the usage to the buffer we need to switch the output temporarily + // since Out() returns root output, you also need to revert that on root + out := r.Out() + r.SetOutput(r.cmdErrorBuf) + c.Usage() + r.SetOutput(out) return err } else { - // If help is called, regardless of other flags, we print that - if c.helpFlagVal { + // If help is called, regardless of other flags, we print that. + // Print help also if c.Run is nil. + if c.helpFlagVal || !c.Runnable() { c.Help() return nil } @@ -430,7 +443,12 @@ func (c *Command) Execute() (err error) { // Flags parsing had an error. // If an error happens here, we have to report it to the user c.Println(c.errorMsgFromParse()) - c.Usage() + // If an error happens search also for subcommand info about that + if c.cmdErrorBuf != nil && c.cmdErrorBuf.Len() > 0 { + c.Println(c.cmdErrorBuf.String()) + } else { + c.Usage() + } return e } else { // If help is called, regardless of other flags, we print that @@ -465,6 +483,10 @@ func (c *Command) Execute() (err error) { func (c *Command) initHelp() { if c.helpCommand == nil { + if !c.HasSubCommands() { + return + } + c.helpCommand = &Command{ Use: "help [command]", Short: "Help about any command", @@ -479,13 +501,17 @@ func (c *Command) initHelp() { // Used for testing func (c *Command) ResetCommands() { c.commands = nil + c.helpCommand = nil + c.cmdErrorBuf = new(bytes.Buffer) + c.cmdErrorBuf.Reset() } +//Commands returns a slice of child commands. func (c *Command) Commands() []*Command { return c.commands } -// Add one or many commands as children of this +// AddCommand adds one or more commands to this parent command. func (c *Command) AddCommand(cmds ...*Command) { for i, x := range cmds { if cmds[i] == c { @@ -549,7 +575,7 @@ func (c *Command) UsageString() string { return bb.String() } -// The full path to this command +// CommandPath returns the full path to this command. func (c *Command) CommandPath() string { str := c.Name() x := c