mirror of
https://github.com/spf13/cobra
synced 2024-11-16 18:57:08 +00:00
Fix stripFlags to be more intelligent about what it parses.
This commit is contained in:
parent
5c9146990b
commit
e0489d488c
2 changed files with 108 additions and 2 deletions
29
command.go
29
command.go
|
@ -251,7 +251,23 @@ func (c *Command) resetChildrensParents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func stripFlags(args []string) []string {
|
// Test if the named flag is a boolean flag.
|
||||||
|
func isBooleanFlag(name string, f *flag.FlagSet) bool {
|
||||||
|
flag := f.Lookup(name)
|
||||||
|
if flag == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return flag.Value.Type() == "bool"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if the named flag is a boolean flag.
|
||||||
|
func isBooleanShortFlag(name string, f *flag.FlagSet) bool {
|
||||||
|
result := false
|
||||||
|
f.VisitAll(func (f *flag.Flag) { if f.Shorthand == name && f.Value.Type() == "bool" { result = true } })
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripFlags(args []string, c *Command) []string {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
@ -259,6 +275,7 @@ func stripFlags(args []string) []string {
|
||||||
commands := []string{}
|
commands := []string{}
|
||||||
|
|
||||||
inQuote := false
|
inQuote := false
|
||||||
|
inFlag := false
|
||||||
for _, y := range args {
|
for _, y := range args {
|
||||||
if !inQuote {
|
if !inQuote {
|
||||||
switch {
|
switch {
|
||||||
|
@ -266,8 +283,16 @@ func stripFlags(args []string) []string {
|
||||||
inQuote = true
|
inQuote = true
|
||||||
case strings.Contains(y, "=\""):
|
case strings.Contains(y, "=\""):
|
||||||
inQuote = true
|
inQuote = true
|
||||||
|
case strings.HasPrefix(y, "--") && !strings.Contains(y, "="):
|
||||||
|
// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
|
||||||
|
inFlag = !isBooleanFlag(y[2:], c.Flags())
|
||||||
|
case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(y[1:], c.Flags()):
|
||||||
|
inFlag = true
|
||||||
|
case inFlag:
|
||||||
|
inFlag = false
|
||||||
case !strings.HasPrefix(y, "-"):
|
case !strings.HasPrefix(y, "-"):
|
||||||
commands = append(commands, y)
|
commands = append(commands, y)
|
||||||
|
inFlag = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +330,7 @@ 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() {
|
||||||
argsWOflags := stripFlags(args)
|
argsWOflags := stripFlags(args, c)
|
||||||
if len(argsWOflags) > 0 {
|
if len(argsWOflags) > 0 {
|
||||||
matches := make([]*Command, 0)
|
matches := make([]*Command, 0)
|
||||||
for _, cmd := range c.commands {
|
for _, cmd := range c.commands {
|
||||||
|
|
81
command_test.go
Normal file
81
command_test.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package cobra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStripFlags(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input []string
|
||||||
|
output []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
[]string{"foo", "bar"},
|
||||||
|
[]string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"foo", "--bar", "-b"},
|
||||||
|
[]string{"foo"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-b", "foo", "--bar", "bar"},
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-i10", "echo"},
|
||||||
|
[]string{"echo"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-i=10", "echo"},
|
||||||
|
[]string{"echo"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"--int=100", "echo"},
|
||||||
|
[]string{"echo"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-ib", "echo", "-bfoo", "baz"},
|
||||||
|
[]string{"echo", "baz"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-i=baz", "bar", "-i", "foo", "blah"},
|
||||||
|
[]string{"bar", "blah"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"--int=baz", "-bbar", "-i", "foo", "blah"},
|
||||||
|
[]string{"blah"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"--cat", "bar", "-i", "foo", "blah"},
|
||||||
|
[]string{"bar", "blah"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"-c", "bar", "-i", "foo", "blah"},
|
||||||
|
[]string{"bar", "blah"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdPrint := &Command{
|
||||||
|
Use: "print [string to print]",
|
||||||
|
Short: "Print anything to the screen",
|
||||||
|
Long: `an utterly useless command for testing.`,
|
||||||
|
Run: func(cmd *Command, args []string) {
|
||||||
|
tp = args
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var flagi int
|
||||||
|
var flagstr string
|
||||||
|
var flagbool bool
|
||||||
|
cmdPrint.Flags().IntVarP(&flagi, "int", "i", 345, "help message for flag int")
|
||||||
|
cmdPrint.Flags().StringVarP(&flagstr, "bar", "b", "bar", "help message for flag string")
|
||||||
|
cmdPrint.Flags().BoolVarP(&flagbool, "cat", "c", false, "help message for flag bool")
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
output := stripFlags(test.input, cmdPrint)
|
||||||
|
if !reflect.DeepEqual(test.output, output) {
|
||||||
|
t.Errorf("expected: %v, got: %v", test.output, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue