8000 file: drop removed keys and sections on Reload by rhmatzeka · Pull Request #419 · 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
Diff view
22 changes: 19 additions & 3 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,24 @@ func (f *File) reload(s dataSource) error {
return f.parse(r)
}

// Reload reloads and parses all data sources.
func (f *File) Reload() (err error) {
// Reload reloads and parses all data sources. Sections and keys that are no
// longer in any data source are removed, and changes made in memory are
// discarded.
func (f *File) Reload() error {
if f.BlockMode {
f.lock.Lock()
}
f.sectionList = nil
f.sectionIndexes = nil
f.sections = make(map[string][]*Section)
if f.BlockMode {
f.lock.Unlock()
}
return f.loadSources()
}

// loadSources parses all data sources on top of the sections already in f.
func (f *File) loadSources() (err error) {
for _, s := range f.dataSources {
if err = f.reload(s); err != nil {
// In loose mode, we create an empty default section for nonexistent files.
Expand Down Expand Up @@ -329,7 +345,7 @@ func (f *File) Append(source interface{}, others ...interface{}) error {
}
f.dataSources = append(f.dataSources, ds)
}
return f.Reload()
return f.loadSources()
}

func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
Expand Down
32 changes: 32 additions & 0 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package ini
import (
"bytes"
"os"
"path/filepath"
"runtime"
"sort"
"testing"
Expand Down Expand Up @@ -535,3 +536,34 @@ v = 3
require.NoError(t, f.Reload())
assert.Equal(t, []string{"1", "2", "3"}, f.Section("slice").Key("v").ValueWithShadows())
}

// Inspired by https://github.com/go-ini/ini/issues/418
func TestReloadDropsRemovedKeysAndSections(t *testing.T) {
path := filepath.Join(t.TempDir(), "settings.ini")
require.NoError(t, os.WriteFile(path, []byte("[app]\nold = 1\nkeep = 2\n[gone]\nk = v\n"), 0600))

f, err := Load(path)
require.NoError(t, err)
require.True(t, f.Section("app").HasKey("old"))

require.NoError(t, os.WriteFile(path, []byte("[app]\nkeep = 3\n"), 0600))
require.NoError(t, f.Reload())

assert.Equal(t, map[string]string{"keep": "3"}, f.Section("app").KeysHash())
assert.False(t, f.Section("app").HasKey("old"))
assert.Equal(t, []string{DefaultSection, "app"}, f.SectionStrings())
}

func TestReloadDoesNotDuplicateNonUniqueSections(t *testing.T) {
f, err := LoadSources(LoadOptions{AllowNonUniqueSections: true}, []byte(`
[peer]
name = a
[peer]
name = b
`))
require.NoError(t, err)
require.Len(t, f.SectionStrings(), 3)

require.NoError(t, f.Reload())
assert.Equal(t, []string{DefaultSection, "peer", "peer"}, f.SectionStrings())
}
0