8000 key: keep empty shadows when PreserveEmptyShadows is set by team-humaki · Pull Request #399 · go-ini/ini · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
4 changes: 4 additions & 0 deletions ini.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ type LoadOptions struct {
AllowNonUniqueSections bool
// AllowDuplicateShadowValues indicates whether values for shadowed keys should be deduplicated.
AllowDuplicateShadowValues bool
// PreserveEmptyShadows indicates whether ValueWithShadows should keep empty
// assignments. Empty values are otherwise omitted (the historical default).
// systemd unit files use an empty assignment to reset prior values.
PreserveEmptyShadows bool
}

// DebugFunc is the type of function called to log parse events.
Expand Down
11 changes: 6 additions & 5 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,23 @@ func (k *Key) Value() string {
return k.value
}

// ValueWithShadows returns raw values of key and its shadows if any. Shadow
// keys with empty values are ignored from the returned list.
// ValueWithShadows returns raw values of key and its shadows if any.
// Empty values are omitted unless LoadOptions.PreserveEmptyShadows is set.
func (k *Key) ValueWithShadows() []string {
keepEmpty := k.s != nil && k.s.f != nil && k.s.f.options.PreserveEmptyShadows
if len(k.shadows) == 0 {
if k.value == "" {
if k.value == "" && !keepEmpty {
return []string{}
}
return []string{k.value}
}

vals := make([]string, 0, len(k.shadows)+1)
if k.value != "" {
if k.value != "" || keepEmpty {
vals = append(vals, k.value)
}
for _, s := range k.shadows {
if s.value != "" {
if s.value != "" || keepEmpty {
vals = append(vals, s.value)
}
}
Expand Down
39 changes: 39 additions & 0 deletions key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ func TestKey_AddShadow(t *testing.T) {
})
})

t.Run("preserve empty shadow values", func(t *testing.T) {
f := Empty(LoadOptions{
AllowShadows: true,
PreserveEmptyShadows: true,
})
require.NotNil(t, f)

k, err := f.Section("").NewKey("Environment", "FOO=bar")
require.NoError(t, err)
require.NotNil(t, k)
assert.NoError(t, k.AddShadow(""))
assert.Equal(t, []string{"FOO=bar", ""}, k.ValueWithShadows())
})

t.Run("allow duplicate shadowed values", func(t *testing.T) {
f := Empty(LoadOptions{
AllowShadows: true,
Expand Down Expand Up @@ -546,6 +560,31 @@ keyName = value2
require.NotNil(t, k)
assert.Equal(t, []string{"value1", "value2"}, k.ValueWithShadows())
})

t.Run("preserve empty assignments from file", func(t *testing.T) {
f, err := LoadSources(LoadOptions{
AllowShadows: true,
PreserveEmptyShadows: true,
}, []byte(`
[Service]
Environment=FOO=bar
Environment=
`))
require.NoError(t, err)
require.NotNil(t, f)
assert.Equal(t, []string{"FOO=bar", ""}, f.Section("Service").Key("Environment").ValueWithShadows())
})

t.Run("default still drops empty assignments from file", func(t *testing.T) {
f, err := ShadowLoad([]byte(`
[Service]
Environment=FOO=bar
Environment=
`))
require.NoError(t, err)
require.NotNil(t, f)
assert.Equal(t, []string{"FOO=bar"}, f.Section("Service").Key("Environment").ValueWithShadows())
})
}

func TestKey_StringsWithShadows(t *testing.T) {
Expand Down
0