diff --git a/internal/yamlmap/yaml_map.go b/internal/yamlmap/yaml_map.go index 1f47449..78d0991 100644 --- a/internal/yamlmap/yaml_map.go +++ b/internal/yamlmap/yaml_map.go @@ -35,6 +35,13 @@ func MapValue() *Map { }} } +func NullValue() *Map { + return &Map{&yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!null", + }} +} + func Unmarshal(data []byte) (*Map, error) { var root yaml.Node err := yaml.Unmarshal(data, &root) diff --git a/pkg/config/config.go b/pkg/config/config.go index e2b1fc8..cda69d8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -102,7 +102,12 @@ func (c *Config) Remove(keys []string) error { // Set a string value in a Config. // The keys argument is a sequence of key values so that nested // entries can be set. If any of the keys do not exist they will -// be created. +// be created. If the string value to be set is empty it will be +// represented as null not an empty string when written. +// +// var c *Config +// c.Set([]string{"key"}, "") +// Write(c) // writes `key: ` not `key: ""` func (c *Config) Set(keys []string, value string) { c.mu.Lock() defer c.mu.Unlock() @@ -116,7 +121,11 @@ func (c *Config) Set(keys []string, value string) { } m = entry } - m.SetEntry(keys[len(keys)-1], yamlmap.StringValue(value)) + val := yamlmap.StringValue(value) + if value == "" { + val = yamlmap.NullValue() + } + m.SetEntry(keys[len(keys)-1], val) } func (c *Config) deepCopy() *Config { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index b24e3c4..03fdf06 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -406,6 +406,18 @@ func TestWrite(t *testing.T) { } } +func TestWriteEmptyValues(t *testing.T) { + tempDir := t.TempDir() + t.Setenv("GH_CONFIG_DIR", tempDir) + cfg := ReadFromString(testFullConfig()) + cfg.Set([]string{"editor"}, "") + err := Write(cfg) + assert.NoError(t, err) + data, err := os.ReadFile(generalConfigFile()) + assert.NoError(t, err) + assert.Equal(t, "git_protocol: ssh\neditor:\nprompt: enabled\npager: less\n", string(data)) +} + func TestGet(t *testing.T) { tests := []struct { name string @@ -595,6 +607,11 @@ func TestSet(t *testing.T) { keys: []string{"johnny", "test"}, value: "dukey", }, + { + name: "set empty value", + keys: []string{"empty"}, + value: "", + }, } for _, tt := range tests {