From 934601d616e60e17133b3b8a1611c27651026db6 Mon Sep 17 00:00:00 2001 From: levisyin Date: Sun, 26 Nov 2023 16:00:15 +0800 Subject: [PATCH] fix: reset flags' value to default if flags have been parsed --- command.go | 6 ++++++ flag_groups_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/command.go b/command.go index 11a3e9c9..e9652a84 100644 --- a/command.go +++ b/command.go @@ -1830,6 +1830,12 @@ func (c *Command) ParseFlags(args []string) error { // do it here after merging all flags and just before parse c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + // if flag has been parsed, we should reset flags' value to default + if c.Flags().Parsed() { + c.Flags().Visit(func(f *flag.Flag) { + f.Value.Set(f.DefValue) + }) + } 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/flag_groups_test.go b/flag_groups_test.go index cffa8552..b9a92971 100644 --- a/flag_groups_test.go +++ b/flag_groups_test.go @@ -15,6 +15,7 @@ package cobra import ( + "fmt" "strings" "testing" ) @@ -193,3 +194,54 @@ func TestValidateFlagGroups(t *testing.T) { }) } } + +func TestSetArgs(t *testing.T) { + getCMD := func() *Command { + cmd := &Command{ + Use: "testcmd", + RunE: func(cmd *Command, args []string) error { + a, _ := cmd.Flags().GetBool("a") + b, _ := cmd.Flags().GetBool("b") + c, _ := cmd.Flags().GetBool("c") + switch { + case a && b, a && c, b && c: + return fmt.Errorf("a,b,c only one could be true") + } + return nil + }, + } + f := cmd.Flags() + f.BoolP("a", "a", false, "a,b,c only one could be true") + f.BoolP("b", "b", false, "a,b,c only one could be true") + f.Bool("c", false, "a,b,c only one could be true") + return cmd + } + + cmd := getCMD() + + // step 1 + cmd.SetArgs([]string{ + "--a=true", + }) + assertNoErr(t, cmd.Execute()) + // step 2 + cmd.SetArgs([]string{ + "--b=true", + }) + t.Log(cmd.Flags().Changed("a")) + assertNoErr(t, cmd.Execute()) + + // step 3 + cmd.SetArgs([]string{ + "--c=true", + }) + assertNoErr(t, cmd.Execute()) + + // step 4 + cmd.SetArgs([]string{ + "--a=false", + "--b=false", + "--c=true", + }) + assertNoErr(t, cmd.Execute()) +}