From 1bbbeded9d41d4adb8a4f25f3f8296db815a8a84 Mon Sep 17 00:00:00 2001 From: Shirong Lu <73147033+happysnaker@users.noreply.github.com> Date: Thu, 2 Jul 2026 03:31:46 +0800 Subject: [PATCH] fix: allow empty StringToString values --- string_to_string.go | 8 ++++-- string_to_string_test.go | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/string_to_string.go b/string_to_string.go index 518e1366..37fa6db2 100644 --- a/string_to_string.go +++ b/string_to_string.go @@ -24,8 +24,9 @@ func newStringToStringValue(val map[string]string, p *map[string]string) *string // Set updates the flag value from the given string, adding additional mappings or updating existing ones. func (s *stringToStringValue) Set(val string) error { var ss []string - n := strings.Count(val, "=") - switch n { + switch n := strings.Count(val, "="); { + case val == "": + ss = []string{} case 0: return fmt.Errorf("%s must be formatted as key=value", val) case 1: @@ -54,6 +55,9 @@ func (s *stringToStringValue) Set(val string) error { delete(*s.value, k) } } + if *s.value == nil { + *s.value = map[string]string{} + } for k, v := range out { (*s.value)[k] = v diff --git a/string_to_string_test.go b/string_to_string_test.go index d3346d63..91d13728 100644 --- a/string_to_string_test.go +++ b/string_to_string_test.go @@ -398,3 +398,58 @@ func TestS2SCalledTwice(t *testing.T) { } } } + +func TestS2SEmptyValueClearsDefaults(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSetWithDefault(&s2s) + + if err := f.Parse([]string{"--s2s="}); err != nil { + t.Fatalf("expected no error; got %v", err) + } + if s2s == nil { + t.Fatal("expected empty map, got nil") + } + if len(s2s) != 0 { + t.Fatalf("expected empty map, got %v", s2s) + } + + getS2S, err := f.GetStringToString("s2s") + if err != nil { + t.Fatalf("got an error from GetStringToString(): %v", err) + } + if getS2S == nil { + t.Fatal("expected empty map from GetStringToString, got nil") + } + if len(getS2S) != 0 { + t.Fatalf("expected empty map from GetStringToString, got %v", getS2S) + } +} + +func TestS2SEmptyValueKeepsEmptyDefaultNonNil(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSet(&s2s) + + if err := f.Parse([]string{"--s2s="}); err != nil { + t.Fatalf("expected no error; got %v", err) + } + if s2s == nil { + t.Fatal("expected empty map, got nil") + } + if len(s2s) != 0 { + t.Fatalf("expected empty map, got %v", s2s) + } +} + +func TestS2SEmptyValueCanBeFollowedByEntries(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSetWithDefault(&s2s) + + if err := f.Parse([]string{"--s2s=", "--s2s=a=1"}); err != nil { + t.Fatalf("expected no error; got %v", err) + } + + expected := map[string]string{"a": "1"} + if !reflect.DeepEqual(s2s, expected) { + t.Fatalf("expected %v, got %v", expected, s2s) + } +}