Skip to content
Merged
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
3 changes: 3 additions & 0 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ func newFile(dataSources []dataSource, opts LoadOptions) *File {
if len(opts.KeyValueDelimiterOnWrite) == 0 {
opts.KeyValueDelimiterOnWrite = "="
}
if len(opts.ChildSectionDelimiter) == 0 {
opts.ChildSectionDelimiter = "."
}

return &File{
BlockMode: true,
Expand Down
2 changes: 2 additions & 0 deletions ini.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ type LoadOptions struct {
KeyValueDelimiters string
// KeyValueDelimiters is the delimiter that are used to separate key and value output. By default, it is "=".
KeyValueDelimiterOnWrite string
// ChildSectionDelimiter is the delimiter that is used to separate child sections. By default, it is ".".
ChildSectionDelimiter string
// PreserveSurroundedQuote indicates whether to preserve surrounded quote (single and double quotes).
PreserveSurroundedQuote bool
// DebugFunc is called to collect debug information (currently only useful to debug parsing Python-style multiline values).
Expand Down
62 changes: 62 additions & 0 deletions ini_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,68 @@ GITHUB = U;n;k;n;w;o;n
})
})
})

Convey("with `ChildSectionDelimiter` ':'", func() {
Convey("Get all keys of parent sections", func() {
f := ini.Empty(ini.LoadOptions{ChildSectionDelimiter: ":"})
So(f, ShouldNotBeNil)

k, err := f.Section("package").NewKey("NAME", "ini")
So(err, ShouldBeNil)
So(k, ShouldNotBeNil)
k, err = f.Section("package").NewKey("VERSION", "v1")
So(err, ShouldBeNil)
So(k, ShouldNotBeNil)
k, err = f.Section("package").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
So(err, ShouldBeNil)
So(k, ShouldNotBeNil)

keys := f.Section("package:sub:sub2").ParentKeys()
names := []string{"NAME", "VERSION", "IMPORT_PATH"}
So(len(keys), ShouldEqual, len(names))
for i, name := range names {
So(keys[i].Name(), ShouldEqual, name)
}
})

Convey("Getting and setting values", func() {
f, err := ini.LoadSources(ini.LoadOptions{ChildSectionDelimiter: ":"}, fullConf)
So(err, ShouldBeNil)
So(f, ShouldNotBeNil)

Convey("Get parent-keys that are available to the child section", func() {
parentKeys := f.Section("package:sub").ParentKeys()
So(parentKeys, ShouldNotBeNil)
for _, k := range parentKeys {
So(k.Name(), ShouldEqual, "CLONE_URL")
}
})

Convey("Get parent section value", func() {
So(f.Section("package:sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1")
So(f.Section("package:fake:sub").Key("CLONE_URL").String(), ShouldEqual, "https://gopkg.in/ini.v1")
})
})

Convey("Get child sections by parent name", func() {
f, err := ini.LoadSources(ini.LoadOptions{ChildSectionDelimiter: ":"}, []byte(`
[node]
[node:biz1]
[node:biz2]
[node.biz3]
[node.bizN]
`))
So(err, ShouldBeNil)
So(f, ShouldNotBeNil)

children := f.ChildSections("node")
names := []string{"node:biz1", "node:biz2"}
So(len(children), ShouldEqual, len(names))
for i, name := range names {
So(children[i].Name(), ShouldEqual, name)
}
})
})
})
}

Expand Down
6 changes: 3 additions & 3 deletions section.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (s *Section) GetKey(name string) (*Key, error) {
// Check if it is a child-section.
sname := s.name
for {
if i := strings.LastIndex(sname, "."); i > -1 {
if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 {
sname = sname[:i]
sec, err := s.f.GetSection(sname)
if err != nil {
Expand Down Expand Up @@ -188,7 +188,7 @@ func (s *Section) ParentKeys() []*Key {
var parentKeys []*Key
sname := s.name
for {
if i := strings.LastIndex(sname, "."); i > -1 {
if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 {
sname = sname[:i]
sec, err := s.f.GetSection(sname)
if err != nil {
Expand Down Expand Up @@ -245,7 +245,7 @@ func (s *Section) DeleteKey(name string) {
// For example, "[parent.child1]" and "[parent.child12]" are child sections
// of section "[parent]".
func (s *Section) ChildSections() []*Section {
prefix := s.name + "."
prefix := s.name + s.f.options.ChildSectionDelimiter
children := make([]*Section, 0, 3)
for _, name := range s.f.sectionList {
if strings.HasPrefix(name, prefix) {
Expand Down