mirror of
https://github.com/spf13/cobra
synced 2024-11-24 14:47:12 +00:00
Support for flags before commands
This commit is contained in:
parent
07be8145cc
commit
10a8494a87
3 changed files with 171 additions and 121 deletions
25
README.md
25
README.md
|
@ -18,6 +18,13 @@ all commands.
|
||||||
Cobra has an exceptionally clean interface and simple design without needless
|
Cobra has an exceptionally clean interface and simple design without needless
|
||||||
constructors or initialization methods.
|
constructors or initialization methods.
|
||||||
|
|
||||||
|
Applications built with Cobra commands are designed to be as user friendly as
|
||||||
|
possible. Flags can be placed before or after the command (as long as a
|
||||||
|
confusing space isn’t provided). Both short and long flags can be used. A
|
||||||
|
command need not even be fully typed. The shortest unambiguous string will
|
||||||
|
suffice. Help is automatically generated and available for the application or
|
||||||
|
for a specific command using either the help command or the --help flag.
|
||||||
|
|
||||||
## Concepts
|
## Concepts
|
||||||
|
|
||||||
Cobra is built on a structure of commands & flags.
|
Cobra is built on a structure of commands & flags.
|
||||||
|
@ -283,14 +290,13 @@ You can provide your own command, function or template through the following met
|
||||||
|
|
||||||
The latter two will also apply to any children commands.
|
The latter two will also apply to any children commands.
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
When the user provides an invalid flag or invalid command Cobra responds by
|
When the user provides an invalid flag or invalid command Cobra responds by
|
||||||
showing the user the 'usage'
|
showing the user the 'usage'
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
You may recognize this from the help above. That's because the default help
|
You may recognize this from the help above. That's because the default help
|
||||||
embeds the usage as part of it's output.
|
embeds the usage as part of it's output.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
@ -332,7 +338,22 @@ Like help the function and template are over ridable through public methods.
|
||||||
command.SetUsageTemplate(s string)
|
command.SetUsageTemplate(s string)
|
||||||
|
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
Cobra provides a ‘DebugFlags’ method on a command which when called will print
|
||||||
|
out everything Cobra knows about the flags for each command
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
command.DebugFlags()
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
* **0.9.0** June 17, 2014
|
||||||
|
* flags can appears anywhere in the args (provided they are unambiguous)
|
||||||
|
* --help prints usage screen for app or command
|
||||||
|
* Prefix matching for commands
|
||||||
|
* Cleaner looking help and usage output
|
||||||
|
* Extensive test suite
|
||||||
* **0.8.0** Nov 5, 2013
|
* **0.8.0** Nov 5, 2013
|
||||||
* Reworked interface to remove commander completely
|
* Reworked interface to remove commander completely
|
||||||
* Command now primary structure
|
* Command now primary structure
|
||||||
|
|
190
cobra_test.go
190
cobra_test.go
|
@ -168,10 +168,7 @@ func checkOutputContains(t *testing.T, c *Command, check string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSingleCommand(t *testing.T) {
|
func TestSingleCommand(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("print one two")
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("print one two", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if te != nil || tt != nil {
|
if te != nil || tt != nil {
|
||||||
t.Error("Wrong command called")
|
t.Error("Wrong command called")
|
||||||
|
@ -185,11 +182,7 @@ func TestSingleCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildCommand(t *testing.T) {
|
func TestChildCommand(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("echo times one two")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo times one two", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if te != nil || tp != nil {
|
if te != nil || tp != nil {
|
||||||
t.Error("Wrong command called")
|
t.Error("Wrong command called")
|
||||||
|
@ -203,11 +196,7 @@ func TestChildCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildCommandPrefix(t *testing.T) {
|
func TestChildCommandPrefix(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("ech tim one two")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("ech tim one two", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if te != nil || tp != nil {
|
if te != nil || tp != nil {
|
||||||
t.Error("Wrong command called")
|
t.Error("Wrong command called")
|
||||||
|
@ -255,10 +244,7 @@ func TestChildSameNamePrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFlagLong(t *testing.T) {
|
func TestFlagLong(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("echo --intone=13 something here")
|
||||||
c.AddCommand(cmdPrint, cmdEcho, cmdTimes)
|
|
||||||
c.SetArgs(strings.Split("echo --intone=13 something here", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(te, " ") != "something here" {
|
if strings.Join(te, " ") != "something here" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
||||||
|
@ -272,10 +258,7 @@ func TestFlagLong(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFlagShort(t *testing.T) {
|
func TestFlagShort(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("echo -i13 something here")
|
||||||
c.AddCommand(cmdPrint, cmdEcho, cmdTimes)
|
|
||||||
c.SetArgs(strings.Split("echo -i13 something here", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(te, " ") != "something here" {
|
if strings.Join(te, " ") != "something here" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
||||||
|
@ -287,10 +270,7 @@ func TestFlagShort(t *testing.T) {
|
||||||
t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
|
t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
|
||||||
}
|
}
|
||||||
|
|
||||||
c = initialize()
|
noRRSetupTest("echo -i 13 something here")
|
||||||
c.AddCommand(cmdPrint, cmdEcho, cmdTimes)
|
|
||||||
c.SetArgs(strings.Split("echo -i 13 something here", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(te, " ") != "something here" {
|
if strings.Join(te, " ") != "something here" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
t.Errorf("flags didn't leave proper args remaining..%s given", te)
|
||||||
|
@ -302,11 +282,7 @@ func TestFlagShort(t *testing.T) {
|
||||||
t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
|
t.Errorf("default flag value changed, 234 expected, %d given", flagi2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing same shortcode, different command
|
noRRSetupTest("print -i99 one two")
|
||||||
c = initialize()
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho, cmdTimes)
|
|
||||||
c.SetArgs(strings.Split("print -i99 one two", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(tp, " ") != "one two" {
|
if strings.Join(tp, " ") != "one two" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", tp)
|
t.Errorf("flags didn't leave proper args remaining..%s given", tp)
|
||||||
|
@ -320,33 +296,21 @@ func TestFlagShort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChildCommandFlags(t *testing.T) {
|
func TestChildCommandFlags(t *testing.T) {
|
||||||
c := initialize()
|
noRRSetupTest("echo times -j 99 one two")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo times -j 99 one two", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(tt, " ") != "one two" {
|
if strings.Join(tt, " ") != "one two" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", tt)
|
t.Errorf("flags didn't leave proper args remaining..%s given", tt)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
// Testing with flag that shouldn't be persistent
|
// Testing with flag that shouldn't be persistent
|
||||||
c = initialize()
|
r := noRRSetupTest("echo times -j 99 -i77 one two")
|
||||||
c.SetOutput(buf)
|
|
||||||
// define children
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
// define grandchild
|
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.SetArgs(strings.Split("echo times -j 99 -i77 one two", " "))
|
|
||||||
e := c.Execute()
|
|
||||||
|
|
||||||
if e == nil {
|
if r.Error == nil {
|
||||||
t.Errorf("invalid flag should generate error")
|
t.Errorf("invalid flag should generate error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(buf.String(), "unknown shorthand") {
|
if !strings.Contains(r.Output, "unknown shorthand") {
|
||||||
t.Errorf("Wrong error message displayed, \n %s", buf.String())
|
t.Errorf("Wrong error message displayed, \n %s", r.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagi2 != 99 {
|
if flagi2 != 99 {
|
||||||
|
@ -358,61 +322,38 @@ func TestChildCommandFlags(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing with flag only existing on child
|
// Testing with flag only existing on child
|
||||||
buf.Reset()
|
r = noRRSetupTest("echo -j 99 -i77 one two")
|
||||||
c = initialize()
|
|
||||||
c.SetOutput(buf)
|
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo -j 99 -i77 one two", " "))
|
|
||||||
err := c.Execute()
|
|
||||||
|
|
||||||
if err == nil {
|
if r.Error == nil {
|
||||||
t.Errorf("invalid flag should generate error")
|
t.Errorf("invalid flag should generate error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(buf.String(), "intone=123") {
|
if !strings.Contains(r.Output, "intone=123") {
|
||||||
t.Errorf("Wrong error message displayed, \n %s", buf.String())
|
t.Errorf("Wrong error message displayed, \n %s", r.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing flag with invalid input
|
// Testing flag with invalid input
|
||||||
buf.Reset()
|
r = noRRSetupTest("echo -i10E")
|
||||||
c = initialize()
|
|
||||||
c.SetOutput(buf)
|
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo -i10E", " "))
|
|
||||||
err = c.Execute()
|
|
||||||
|
|
||||||
if err == nil {
|
if r.Error == nil {
|
||||||
t.Errorf("invalid input should generate error")
|
t.Errorf("invalid input should generate error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.Contains(buf.String(), "invalid argument \"10E\" for -i10E") {
|
if !strings.Contains(r.Output, "invalid argument \"10E\" for -i10E") {
|
||||||
t.Errorf("Wrong error message displayed, \n %s", buf.String())
|
t.Errorf("Wrong error message displayed, \n %s", r.Output)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTrailingCommandFlags(t *testing.T) {
|
func TestTrailingCommandFlags(t *testing.T) {
|
||||||
buf := new(bytes.Buffer)
|
x := fullSetupTest("echo two -x")
|
||||||
c := initialize()
|
|
||||||
c.SetOutput(buf)
|
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo two -x", " "))
|
|
||||||
e3 := c.Execute()
|
|
||||||
|
|
||||||
if e3 == nil {
|
if x.Error == nil {
|
||||||
t.Errorf("invalid flag should generate error")
|
t.Errorf("invalid flag should generate error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPersistentFlags(t *testing.T) {
|
func TestPersistentFlags(t *testing.T) {
|
||||||
c := initialize()
|
fullSetupTest("echo -s something more here")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo -s something more here", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
// persistentFlag should act like normal flag on it's own command
|
// persistentFlag should act like normal flag on it's own command
|
||||||
if strings.Join(te, " ") != "more here" {
|
if strings.Join(te, " ") != "more here" {
|
||||||
|
@ -424,11 +365,7 @@ func TestPersistentFlags(t *testing.T) {
|
||||||
t.Errorf("string flag didn't get correct value, had %v", flags1)
|
t.Errorf("string flag didn't get correct value, had %v", flags1)
|
||||||
}
|
}
|
||||||
|
|
||||||
c = initialize()
|
fullSetupTest("echo times -s again -c test here")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("echo times -s again -c test here", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if strings.Join(tt, " ") != "test here" {
|
if strings.Join(tt, " ") != "test here" {
|
||||||
t.Errorf("flags didn't leave proper args remaining..%s given", tt)
|
t.Errorf("flags didn't leave proper args remaining..%s given", tt)
|
||||||
|
@ -444,26 +381,15 @@ func TestPersistentFlags(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelpCommand(t *testing.T) {
|
func TestHelpCommand(t *testing.T) {
|
||||||
c := initialize()
|
c := fullSetupTest("help echo")
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
checkResultContains(t, c, cmdEcho.Long)
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("help echo", " "))
|
|
||||||
|
|
||||||
checkOutputContains(t, c, cmdEcho.Long)
|
r := fullSetupTest("help echo times")
|
||||||
|
checkResultContains(t, r, cmdTimes.Long)
|
||||||
c = initialize()
|
|
||||||
cmdEcho.AddCommand(cmdTimes)
|
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("help echo times", " "))
|
|
||||||
|
|
||||||
checkOutputContains(t, c, cmdTimes.Long)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunnableRootCommand(t *testing.T) {
|
func TestRunnableRootCommand(t *testing.T) {
|
||||||
c := initializeWithRootCmd()
|
fullSetupTest("")
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs([]string(nil))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if rootcalled != true {
|
if rootcalled != true {
|
||||||
t.Errorf("Root Function was not called")
|
t.Errorf("Root Function was not called")
|
||||||
|
@ -471,10 +397,7 @@ func TestRunnableRootCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRootFlags(t *testing.T) {
|
func TestRootFlags(t *testing.T) {
|
||||||
c := initializeWithRootCmd()
|
fullSetupTest("-i 17 -b")
|
||||||
c.AddCommand(cmdPrint, cmdEcho)
|
|
||||||
c.SetArgs(strings.Split("-i 17 -b", " "))
|
|
||||||
c.Execute()
|
|
||||||
|
|
||||||
if flagbr != true {
|
if flagbr != true {
|
||||||
t.Errorf("flag value should be true, %v given", flagbr)
|
t.Errorf("flag value should be true, %v given", flagbr)
|
||||||
|
@ -504,5 +427,56 @@ func TestRootHelp(t *testing.T) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkOutputContains(t, c, "Available Commands:")
|
func TestFlagsBeforeCommand(t *testing.T) {
|
||||||
|
// short without space
|
||||||
|
x := fullSetupTest("-i10 echo")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// short (int) with equals
|
||||||
|
// It appears that pflags doesn't support this...
|
||||||
|
// Commenting out until support can be added
|
||||||
|
|
||||||
|
//x = noRRSetupTest("echo -i=10")
|
||||||
|
//if x.Error != nil {
|
||||||
|
//t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
|
||||||
|
//}
|
||||||
|
|
||||||
|
// long with equals
|
||||||
|
x = noRRSetupTest("--intone=123 echo one two")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// With parsing error properly reported
|
||||||
|
x = fullSetupTest("-i10E echo")
|
||||||
|
if !strings.Contains(x.Output, "invalid argument \"10E\" for -i10E") {
|
||||||
|
t.Errorf("Wrong error message displayed, \n %s", x.Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
//With quotes
|
||||||
|
x = fullSetupTest("-s=\"walking\" echo")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//With quotes and space
|
||||||
|
x = fullSetupTest("-s=\"walking fast\" echo")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//With inner quote
|
||||||
|
x = fullSetupTest("-s=\"walking \\\"Inner Quote\\\" fast\" echo")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//With quotes and space
|
||||||
|
x = fullSetupTest("-s=\"walking \\\"Inner Quote\\\" fast\" echo")
|
||||||
|
if x.Error != nil {
|
||||||
|
t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
77
command.go
77
command.go
|
@ -225,6 +225,45 @@ func (c *Command) resetChildrensParents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stripFlags(args []string) []string {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
commands := []string{}
|
||||||
|
|
||||||
|
inQuote := false
|
||||||
|
for _, y := range args {
|
||||||
|
if !inQuote {
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(y, "\""):
|
||||||
|
inQuote = true
|
||||||
|
case strings.Contains(y, "=\""):
|
||||||
|
inQuote = true
|
||||||
|
case !strings.HasPrefix(y, "-"):
|
||||||
|
commands = append(commands, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(y, "\"") && !strings.HasSuffix(y, "\\\"") {
|
||||||
|
inQuote = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return commands
|
||||||
|
}
|
||||||
|
|
||||||
|
func argsMinusX(args []string, x string) []string {
|
||||||
|
newargs := []string{}
|
||||||
|
|
||||||
|
for _, y := range args {
|
||||||
|
if x != y {
|
||||||
|
newargs = append(newargs, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newargs
|
||||||
|
}
|
||||||
|
|
||||||
// find the target command given the args and command tree
|
// find the target command given the args and command tree
|
||||||
// Meant to be run on the highest node. Only searches down.
|
// Meant to be run on the highest node. Only searches down.
|
||||||
func (c *Command) Find(arrs []string) (*Command, []string, error) {
|
func (c *Command) Find(arrs []string) (*Command, []string, error) {
|
||||||
|
@ -240,18 +279,21 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) {
|
||||||
|
|
||||||
innerfind = func(c *Command, args []string) (*Command, []string) {
|
innerfind = func(c *Command, args []string) (*Command, []string) {
|
||||||
if len(args) > 0 && c.HasSubCommands() {
|
if len(args) > 0 && c.HasSubCommands() {
|
||||||
matches := make([]*Command, 0)
|
argsWOflags := stripFlags(args)
|
||||||
for _, cmd := range c.commands {
|
if len(argsWOflags) > 0 {
|
||||||
if cmd.Name() == args[0] { // exact name match
|
matches := make([]*Command, 0)
|
||||||
return innerfind(cmd, args[1:])
|
for _, cmd := range c.commands {
|
||||||
} else if strings.HasPrefix(cmd.Name(), args[0]) { // prefix match
|
if cmd.Name() == argsWOflags[0] { // exact name match
|
||||||
matches = append(matches, cmd)
|
return innerfind(cmd, argsMinusX(args, cmd.Name()))
|
||||||
|
} else if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match
|
||||||
|
matches = append(matches, cmd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// only accept a single prefix match - multiple matches would be ambiguous
|
// only accept a single prefix match - multiple matches would be ambiguous
|
||||||
if len(matches) == 1 {
|
if len(matches) == 1 {
|
||||||
return innerfind(matches[0], args[1:])
|
return innerfind(matches[0], argsMinusX(args, argsWOflags[0]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +356,18 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) errorMsgFromParse() string {
|
||||||
|
s := c.flagErrorBuf.String()
|
||||||
|
|
||||||
|
x := strings.Split(s, "\n")
|
||||||
|
|
||||||
|
if len(x) > 0 {
|
||||||
|
return x[0]
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call execute to use the args (os.Args[1:] by default)
|
// Call execute to use the args (os.Args[1:] by default)
|
||||||
// and run through the command tree finding appropriate matches
|
// and run through the command tree finding appropriate matches
|
||||||
// for commands and then corresponding flags.
|
// for commands and then corresponding flags.
|
||||||
|
@ -352,7 +406,8 @@ func (c *Command) Execute() (err error) {
|
||||||
e := c.ParseFlags(args)
|
e := c.ParseFlags(args)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
// Flags parsing had an error.
|
// Flags parsing had an error.
|
||||||
fmt.Println(e)
|
//fmt.Println(e)
|
||||||
|
c.Println(c.errorMsgFromParse())
|
||||||
c.Usage()
|
c.Usage()
|
||||||
return e
|
return e
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue