summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrégoire Duchêne <gduchene@awhk.org>2022-12-03 12:19:17 +0000
committerGrégoire Duchêne <gduchene@awhk.org>2022-12-03 12:19:17 +0000
commit6f81c7e746a3c7917f9d0efc1a6b34d905135866 (patch)
treeb49e97a4031736f7959cbb854b5eca60cca948eb
parenta3ef784a3b5af5dd98ab8d9a44404f2ef240a626 (diff)
Prevent flags from being set again by defaultv0.3.0
Flag values that are safe to be set again should implement the new MutableFlagValue interface.
-rw-r--r--flag.go13
-rw-r--r--flag_test.go9
2 files changed, 22 insertions, 0 deletions
diff --git a/flag.go b/flag.go
index 6fe41f3..4ef45d1 100644
--- a/flag.go
+++ b/flag.go
@@ -82,6 +82,12 @@ func InitFlagSet(fs *flag.FlagSet, env []string, cfg map[string]string, args []s
return
}
+ if f.DefValue != f.Value.String() {
+ if _, ok := f.Value.(MutableFlagValue); !ok {
+ return
+ }
+ }
+
var next string
if val, found := environ[strings.ToUpper(strings.ReplaceAll(f.Name, "-", "_"))]; found {
next = val
@@ -102,6 +108,13 @@ func InitFlagSet(fs *flag.FlagSet, env []string, cfg map[string]string, args []s
return err
}
+// MutableFlagValue is used to signal whether it is safe to set a flag
+// to another value if it has already been set before, i.e. if its
+// current value (as a string) is the same as its default value.
+type MutableFlagValue interface {
+ MutableFlagValue()
+}
+
// ParseString returns the string passed with no error set.
func ParseString(s string) (string, error) {
return s, nil
diff --git a/flag_test.go b/flag_test.go
index 26568d6..1f36b63 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -110,4 +110,13 @@ func TestInitFlagSet(s *testing.T) {
t.AssertEqual(tc.expStr, *fm)
})
}
+
+ t.Run("NoMutableFlagValue", func(t *core.T) {
+ fs := flag.NewFlagSet("", flag.PanicOnError)
+ fi := fs.Int("int", 0, "")
+ t.AssertErrorIs(nil, core.InitFlagSet(fs, nil, nil, []string{"-int=42"}))
+ t.AssertEqual(42, *fi)
+ t.AssertErrorIs(nil, core.InitFlagSet(fs, nil, nil, []string{"-int=21"}))
+ t.AssertEqual(42, *fi)
+ })
}