From 4dab30cb33e6633c33c787106bafbfbfdde7842d Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Sat, 31 Mar 2018 05:36:20 -0700 Subject: [PATCH 1/3] Add support for ignoring parse errors (#662) --- command.go | 10 +++++ command_test.go | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/command.go b/command.go index 15b81127..34d1bf36 100644 --- a/command.go +++ b/command.go @@ -27,6 +27,9 @@ import ( flag "github.com/spf13/pflag" ) +// FParseErrWhitelist configures Flag parse errors to be ignored +type FParseErrWhitelist flag.ParseErrorsWhitelist + // Command is just that, a command for your application. // E.g. 'go run ...' - 'run' is the command. Cobra requires // you to define the usage and description as part of your command @@ -137,6 +140,9 @@ type Command struct { // TraverseChildren parses flags on all parents before executing child command. TraverseChildren bool + //FParseErrWhitelist flag parse errors to be ignored + FParseErrWhitelist FParseErrWhitelist + // commands is the list of commands supported by this program. commands []*Command // parent is a parent command for this command. @@ -1463,6 +1469,10 @@ func (c *Command) ParseFlags(args []string) error { } beforeErrorBufLen := c.flagErrorBuf.Len() c.mergePersistentFlags() + + //do it here after merging all flags and just before parse + c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + err := c.Flags().Parse(args) // Print warnings if they occurred (e.g. deprecated flag messages). if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil { diff --git a/command_test.go b/command_test.go index d874a9a5..ccee031d 100644 --- a/command_test.go +++ b/command_test.go @@ -1626,3 +1626,108 @@ func TestCalledAs(t *testing.T) { t.Run(name, tc.test) } } + +func TestFParseErrWhitelistBackwardCompatibility(t *testing.T) { + c := &Command{Use: "c", Run: emptyRun} + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + output, err := executeCommand(c, "c", "-a", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} + +func TestFParseErrWhitelistSameCommand(t *testing.T) { + c := &Command{ + Use: "c", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + _, err := executeCommand(c, "c", "-a", "--unknown", "flag") + if err != nil { + t.Error("unexpected error: ", err) + } +} + +func TestFParseErrWhitelistParentCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + root.AddCommand(c) + + output, err := executeCommand(root, "child", "-a", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} + +func TestFParseErrWhitelistChildCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + root.AddCommand(c) + + _, err := executeCommand(root, "child", "-a", "--unknown", "flag") + if err != nil { + t.Error("unexpected error: ", err.Error()) + } +} + +func TestFParseErrWhitelistSiblingCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + s := &Command{ + Use: "sibling", + Run: emptyRun, + } + s.Flags().BoolP("boolb", "b", false, "a boolean flag") + + root.AddCommand(c) + root.AddCommand(s) + + output, err := executeCommand(root, "sibling", "-b", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} From cd30c2a7e91a1d63fd9a0027accf18a681e9d50b Mon Sep 17 00:00:00 2001 From: Allen Sun Date: Mon, 9 Apr 2018 00:17:36 +0800 Subject: [PATCH 2/3] typo: fix incorrect (#668) Signed-off-by: Allen Sun From 615425954c3b0d9485a7027d4d451fdcdfdee84e Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Thu, 12 Apr 2018 05:08:29 -0700 Subject: [PATCH 3/3] remove dot after the abs path (#672) --- cobra/cmd/init.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cobra/cmd/init.go b/cobra/cmd/init.go index 24413701..d65e6c8c 100644 --- a/cobra/cmd/init.go +++ b/cobra/cmd/init.go @@ -65,7 +65,7 @@ Init will not use an existing directory with contents.`, initializeProject(project) fmt.Fprintln(cmd.OutOrStdout(), `Your Cobra application is ready at -`+project.AbsPath()+`. +`+project.AbsPath()+` Give it a try by going there and running `+"`go run main.go`."+` Add commands to it by running `+"`cobra add [cmdname]`.")