diff --git a/app_test.go b/app_test.go index c609a06..78f0c10 100644 --- a/app_test.go +++ b/app_test.go @@ -193,6 +193,50 @@ func TestApp_CommandWithArgBeforeFlags(t *testing.T) { expect(t, firstArg, "my-arg") } +func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) { + var parsedOption string + var args []string + + app := cli.NewApp() + command := cli.Command{ + Name: "cmd", + Flags: []cli.Flag{ + cli.StringFlag{Name: "option", Value: "", Usage: "some option"}, + }, + Action: func(c *cli.Context) { + parsedOption = c.String("option") + args = c.Args() + }, + } + app.Commands = []cli.Command{command} + + app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"}) + + expect(t, parsedOption, "my-option") + expect(t, args[0], "my-arg") + expect(t, args[1], "--") + expect(t, args[2], "--notARealFlag") +} + +func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) { + var args []string + + app := cli.NewApp() + command := cli.Command{ + Name: "cmd", + Action: func(c *cli.Context) { + args = c.Args() + }, + } + app.Commands = []cli.Command{command} + + app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"}) + + expect(t, args[0], "my-arg") + expect(t, args[1], "--") + expect(t, args[2], "notAFlagAtAll") +} + func TestApp_Float64Flag(t *testing.T) { var meters float64 diff --git a/command.go b/command.go index 0c50629..ffd3ef8 100644 --- a/command.go +++ b/command.go @@ -56,18 +56,30 @@ func (c Command) Run(ctx *Context) error { set.SetOutput(ioutil.Discard) firstFlagIndex := -1 + terminatorIndex := -1 for index, arg := range ctx.Args() { - if strings.HasPrefix(arg, "-") { - firstFlagIndex = index + if arg == "--" { + terminatorIndex = index break + } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 { + firstFlagIndex = index } } var err error if firstFlagIndex > -1 && !c.SkipFlagParsing { args := ctx.Args() - regularArgs := args[1:firstFlagIndex] - flagArgs := args[firstFlagIndex:] + regularArgs := make([]string, len(args[1:firstFlagIndex])) + copy(regularArgs, args[1:firstFlagIndex]) + + var flagArgs []string + if terminatorIndex > -1 { + flagArgs = args[firstFlagIndex:terminatorIndex] + regularArgs = append(regularArgs, args[terminatorIndex:]...) + } else { + flagArgs = args[firstFlagIndex:] + } + err = set.Parse(append(flagArgs, regularArgs...)) } else { err = set.Parse(ctx.Args().Tail())