From 7d8e3706d180b6259c63d80a8e216cf56c698ee7 Mon Sep 17 00:00:00 2001 From: JaySon-Huang Date: Fri, 3 Dec 2021 02:08:41 +0800 Subject: [PATCH 1/4] Add test cases Signed-off-by: JaySon-Huang --- command_test.go | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/command_test.go b/command_test.go index 583cb023..5b2da63a 100644 --- a/command_test.go +++ b/command_test.go @@ -2058,3 +2058,93 @@ func TestFParseErrWhitelistSiblingCommand(t *testing.T) { } checkStringContains(t, output, "unknown flag: --unknown") } + +func TestFCommandFindSubCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + type testOpts struct { + a bool + b bool + } + var opt testOpts + child := &Command{ + Use: "child", + RunE: func(cmd *Command, args []string) error { + fmt.Printf("Done! a=%v b=%v\n", opt.a, opt.b) + return nil + }, + } + child.Flags().BoolVar(&opt.a, "a", false, "a") + child.Flags().BoolVar(&opt.b, "b", false, "b") + flag := child.Flags().Lookup("a") + if flag != nil { + if flag.NoOptDefVal != "true" { + t.Errorf("ffff %v", flag.NoOptDefVal) + } + } + root.AddCommand(child) + + argsToTest := [][]string{ + {"--a", "--b", "child"}, + {"child", "--a"}, + {"child", "--b"}, + {"--a=false", "child"}, + {"--a=true", "child"}, + {"--a", "child"}, + {"--b", "child"}, + } + for _, args := range argsToTest { + cmdFound, _, err := root.Find(args) + if err != nil { + t.Errorf("Unexpected error: %v with args: %v", err, args) + } + if cmdFound.Name() != "child" { + t.Errorf("expected found 'child' command with args: %v", args) + } + } +} + +func TestFFindSubCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + type testOpts struct { + a bool + b bool + } + var opt testOpts + child := &Command{ + Use: "child", + RunE: func(cmd *Command, args []string) error { + fmt.Printf("Done! a=%v b=%v\n", opt.a, opt.b) + return nil + }, + } + child.Flags().BoolVar(&opt.a, "a", false, "a") + child.Flags().BoolVar(&opt.b, "b", false, "b") + root.AddCommand(child) + + // ok + output, err := executeCommand(root, "--a", "child") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --a") + + // ok + output, err = executeCommand(root, "--b", "child") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --b") + + // fail? + output, err = executeCommand(root, "--a", "--b", "child") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --a") +} From a916286db13fcd560c6ef72ddb600926868430b7 Mon Sep 17 00:00:00 2001 From: JaySon-Huang Date: Fri, 3 Dec 2021 02:52:49 +0800 Subject: [PATCH 2/4] Fix expected behavior Signed-off-by: JaySon-Huang --- command_test.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/command_test.go b/command_test.go index 5b2da63a..e6973d2a 100644 --- a/command_test.go +++ b/command_test.go @@ -2059,7 +2059,7 @@ func TestFParseErrWhitelistSiblingCommand(t *testing.T) { checkStringContains(t, output, "unknown flag: --unknown") } -func TestFCommandFindSubCommand(t *testing.T) { +func TestFindSubCommand(t *testing.T) { root := &Command{ Use: "root", Run: emptyRun, @@ -2078,22 +2078,11 @@ func TestFCommandFindSubCommand(t *testing.T) { } child.Flags().BoolVar(&opt.a, "a", false, "a") child.Flags().BoolVar(&opt.b, "b", false, "b") - flag := child.Flags().Lookup("a") - if flag != nil { - if flag.NoOptDefVal != "true" { - t.Errorf("ffff %v", flag.NoOptDefVal) - } - } root.AddCommand(child) argsToTest := [][]string{ - {"--a", "--b", "child"}, {"child", "--a"}, {"child", "--b"}, - {"--a=false", "child"}, - {"--a=true", "child"}, - {"--a", "child"}, - {"--b", "child"}, } for _, args := range argsToTest { cmdFound, _, err := root.Find(args) @@ -2104,9 +2093,24 @@ func TestFCommandFindSubCommand(t *testing.T) { t.Errorf("expected found 'child' command with args: %v", args) } } + + argsToTestNotFound := [][]string{ + {"--a", "--b", "child"}, + {"--a", "child"}, + {"--b", "child"}, + } + for _, args := range argsToTestNotFound { + cmdFound, _, err := root.Find(args) + if err != nil { + t.Errorf("Unexpected error: %v with args: %v", err, args) + } + if cmdFound.Name() != "root" { + t.Errorf("expected found 'root' command with args: %v", args) + } + } } -func TestFFindSubCommand(t *testing.T) { +func TestFParseUnknownFlagFromSubCommand(t *testing.T) { root := &Command{ Use: "root", Run: emptyRun, @@ -2127,21 +2131,18 @@ func TestFFindSubCommand(t *testing.T) { child.Flags().BoolVar(&opt.b, "b", false, "b") root.AddCommand(child) - // ok output, err := executeCommand(root, "--a", "child") if err == nil { t.Error("expected unknown flag error") } checkStringContains(t, output, "unknown flag: --a") - // ok output, err = executeCommand(root, "--b", "child") if err == nil { t.Error("expected unknown flag error") } checkStringContains(t, output, "unknown flag: --b") - // fail? output, err = executeCommand(root, "--a", "--b", "child") if err == nil { t.Error("expected unknown flag error") From d364ed015706a7e72df064bfb3d39e1a644f0f98 Mon Sep 17 00:00:00 2001 From: JaySon-Huang Date: Fri, 3 Dec 2021 02:53:30 +0800 Subject: [PATCH 3/4] Only delete arg when it is not starts with - Signed-off-by: JaySon-Huang --- command.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/command.go b/command.go index 2cc18891..1da9df6b 100644 --- a/command.go +++ b/command.go @@ -585,11 +585,12 @@ Loop: case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): // If '-f arg' then // delete 'arg' from args or break the loop if len(args) <= 1. - if len(args) <= 1 { + if len(args) == 0 { break Loop - } else { + } + // Only delete 'arg' when it is not starts with '-' + if !strings.HasPrefix(args[0], "-") { args = args[1:] - continue } case s != "" && !strings.HasPrefix(s, "-"): commands = append(commands, s) From cb29346a0f55acbb8f832a2e540bef23d3c56219 Mon Sep 17 00:00:00 2001 From: JaySon-Huang Date: Fri, 3 Dec 2021 10:52:17 +0800 Subject: [PATCH 4/4] Add comments Signed-off-by: JaySon-Huang --- command.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/command.go b/command.go index 1da9df6b..03a65782 100644 --- a/command.go +++ b/command.go @@ -588,7 +588,10 @@ Loop: if len(args) == 0 { break Loop } - // Only delete 'arg' when it is not starts with '-' + // When the flag 's' doesn't contain "=" and without "no option default values", but + // following with a string starts with '-', consider 's' an unknown boolean flag + // and don't delete 'arg'. + // Otherwise, consider it as '--flag arg' or '-f arg' and delete its following arg. if !strings.HasPrefix(args[0], "-") { args = args[1:] }