fix: reset flags' value to default if flags have been parsed

This commit is contained in:
levisyin 2023-11-26 16:00:15 +08:00
parent 3d8ac432bd
commit 934601d616
2 changed files with 58 additions and 0 deletions

View file

@ -1830,6 +1830,12 @@ func (c *Command) ParseFlags(args []string) error {
// do it here after merging all flags and just before parse // do it here after merging all flags and just before parse
c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) 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) err := c.Flags().Parse(args)
// Print warnings if they occurred (e.g. deprecated flag messages). // Print warnings if they occurred (e.g. deprecated flag messages).
if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil { if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {

View file

@ -15,6 +15,7 @@
package cobra package cobra
import ( import (
"fmt"
"strings" "strings"
"testing" "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())
}