Merge pull request #283 from codegangsta/really-skip-flag-parsing

Really skip flag parsing
This commit is contained in:
Jesse Szwedko 2015-11-20 13:56:42 -08:00
commit 0302d3914d
3 changed files with 61 additions and 59 deletions

View File

@ -74,6 +74,8 @@ func (c Command) Run(ctx *Context) error {
set := flagSet(c.Name, c.Flags) set := flagSet(c.Name, c.Flags)
set.SetOutput(ioutil.Discard) set.SetOutput(ioutil.Discard)
var err error
if !c.SkipFlagParsing {
firstFlagIndex := -1 firstFlagIndex := -1
terminatorIndex := -1 terminatorIndex := -1
for index, arg := range ctx.Args() { for index, arg := range ctx.Args() {
@ -85,8 +87,7 @@ func (c Command) Run(ctx *Context) error {
} }
} }
var err error if firstFlagIndex > -1 {
if firstFlagIndex > -1 && !c.SkipFlagParsing {
args := ctx.Args() args := ctx.Args()
regularArgs := make([]string, len(args[1:firstFlagIndex])) regularArgs := make([]string, len(args[1:firstFlagIndex]))
copy(regularArgs, args[1:firstFlagIndex]) copy(regularArgs, args[1:firstFlagIndex])
@ -103,6 +104,11 @@ func (c Command) Run(ctx *Context) error {
} else { } else {
err = set.Parse(ctx.Args().Tail()) err = set.Parse(ctx.Args().Tail())
} }
} else {
if c.SkipFlagParsing {
err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
}
}
if err != nil { if err != nil {
fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.") fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")

View File

@ -1,17 +1,29 @@
package cli package cli
import ( import (
"errors"
"flag" "flag"
"testing" "testing"
) )
func TestCommandDoNotIgnoreFlags(t *testing.T) { func TestCommandFlagParsing(t *testing.T) {
cases := []struct {
testArgs []string
skipFlagParsing bool
expectedErr error
}{
{[]string{"blah", "blah", "-break"}, false, errors.New("flag provided but not defined: -break")}, // Test normal "not ignoring flags" flow
{[]string{"blah", "blah"}, true, nil}, // Test SkipFlagParsing without any args that look like flags
{[]string{"blah", "-break"}, true, nil}, // Test SkipFlagParsing with random flag arg
{[]string{"blah", "-help"}, true, nil}, // Test SkipFlagParsing with "special" help flag arg
}
for _, c := range cases {
app := NewApp() app := NewApp()
set := flag.NewFlagSet("test", 0) set := flag.NewFlagSet("test", 0)
test := []string{"blah", "blah", "-break"} set.Parse(c.testArgs)
set.Parse(test)
c := NewContext(app, set, nil) context := NewContext(app, set, nil)
command := Command{ command := Command{
Name: "test-cmd", Name: "test-cmd",
@ -20,28 +32,12 @@ func TestCommandDoNotIgnoreFlags(t *testing.T) {
Description: "testing", Description: "testing",
Action: func(_ *Context) {}, Action: func(_ *Context) {},
} }
err := command.Run(c)
expect(t, err.Error(), "flag provided but not defined: -break") command.SkipFlagParsing = c.skipFlagParsing
err := command.Run(context)
expect(t, err, c.expectedErr)
expect(t, []string(context.Args()), c.testArgs)
} }
func TestCommandIgnoreFlags(t *testing.T) {
app := NewApp()
set := flag.NewFlagSet("test", 0)
test := []string{"blah", "blah", "-break"}
set.Parse(test)
c := NewContext(app, set, nil)
command := Command{
Name: "test-cmd",
Aliases: []string{"tc"},
Usage: "this is for testing",
Description: "testing",
Action: func(_ *Context) {},
SkipFlagParsing: true,
}
err := command.Run(c)
expect(t, err, nil)
} }

View File

@ -7,13 +7,13 @@ import (
/* Test Helpers */ /* Test Helpers */
func expect(t *testing.T, a interface{}, b interface{}) { func expect(t *testing.T, a interface{}, b interface{}) {
if a != b { if !reflect.DeepEqual(a, b) {
t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
} }
} }
func refute(t *testing.T, a interface{}, b interface{}) { func refute(t *testing.T, a interface{}, b interface{}) {
if a == b { if reflect.DeepEqual(a, b) {
t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
} }
} }