From a69ddbb9655444c63d932d11f91d05eef1265ae5 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 19 Nov 2014 18:29:56 -0800 Subject: [PATCH 1/2] commands/cli: Fixed parse bug when optional argument is defined first --- commands/cli/parse.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/commands/cli/parse.go b/commands/cli/parse.go index a5a0e07159c..9858a997e46 100644 --- a/commands/cli/parse.go +++ b/commands/cli/parse.go @@ -182,9 +182,11 @@ func parseArgs(inputs []string, stdin *os.File, argDefs []cmds.Argument, recursi argDef := getArgDef(argDefIndex, argDefs) // skip optional argument definitions if there aren't sufficient remaining inputs - if numInputs-i <= numRequired && !argDef.Required { - continue - } else if argDef.Required { + for numInputs-i <= numRequired && !argDef.Required { + argDefIndex++ + argDef = getArgDef(argDefIndex, argDefs) + } + if argDef.Required { numRequired-- } From 922f84878caea85c26b7dd11578bd502bd1763ca Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 19 Nov 2014 18:30:06 -0800 Subject: [PATCH 2/2] commands/cli: Added argument parse tests --- commands/cli/parse_test.go | 105 +++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/commands/cli/parse_test.go b/commands/cli/parse_test.go index 8fe5b351056..d7d949de316 100644 --- a/commands/cli/parse_test.go +++ b/commands/cli/parse_test.go @@ -49,3 +49,108 @@ func TestOptionParsing(t *testing.T) { t.Errorf("Returned command was different than expected") } } + +func TestArgumentParsing(t *testing.T) { + rootCmd := &commands.Command{ + Subcommands: map[string]*commands.Command{ + "noarg": &commands.Command{}, + "onearg": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("a", true, false, "some arg"), + }, + }, + "twoargs": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("a", true, false, "some arg"), + commands.StringArg("b", true, false, "another arg"), + }, + }, + "variadic": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("a", true, true, "some arg"), + }, + }, + "optional": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("b", false, true, "another arg"), + }, + }, + "reversedoptional": &commands.Command{ + Arguments: []commands.Argument{ + commands.StringArg("a", false, false, "some arg"), + commands.StringArg("b", true, false, "another arg"), + }, + }, + }, + } + + _, _, _, err := Parse([]string{"noarg"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"noarg", "value!"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (provided an arg, but command didn't define any)") + } + + _, _, _, err = Parse([]string{"onearg", "value!"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"onearg"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (didn't provide any args, arg is required)") + } + + _, _, _, err = Parse([]string{"twoargs", "value1", "value2"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"twoargs", "value!"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (only provided 1 arg, needs 2)") + } + _, _, _, err = Parse([]string{"twoargs"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (didn't provide any args, 2 required)") + } + + _, _, _, err = Parse([]string{"variadic", "value!"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"variadic", "value1", "value2", "value3"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"variadic"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (didn't provide any args, 1 required)") + } + + _, _, _, err = Parse([]string{"optional", "value!"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"optional"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + + _, _, _, err = Parse([]string{"reversedoptional", "value1", "value2"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"reversedoptional", "value!"}, nil, rootCmd) + if err != nil { + t.Error("Should have passed") + } + _, _, _, err = Parse([]string{"reversedoptional"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (didn't provide any args, 1 required)") + } + _, _, _, err = Parse([]string{"reversedoptional", "value1", "value2", "value3"}, nil, rootCmd) + if err == nil { + t.Error("Should have failed (provided too many args, only takes 1)") + } +}