1package goini
2
3import (
4	"path/filepath"
5	"errors"
6	"log"
7)
8
9// Suppress error if they are not otherwise used.
10var _ = log.Printf
11
12const (
13	InheritedFrom = "inherited_from" // The key of the INI path which will be inherited from
14)
15
16// LoadInheritedINI loads an INI file which inherits from another INI
17// e.g:
18//	The common.ini has contents:
19//		project=common
20//		ip=192.168.0.1
21//
22//	And the project.ini has contents:
23//		project=ppp
24//		combo=ppp
25//		inherited_from=common.ini
26//
27//	The project.ini has the same configure as below :
28//		project=ppp
29//		combo=ppp
30//		ip=192.168.0.1
31//
32func LoadInheritedINI(filename string) (*INI, error) {
33	ini := New()
34	err := ini.ParseFile(filename)
35	if err != nil {
36		return nil, err
37	}
38
39	inherited, ok := ini.Get(InheritedFrom)
40	if !ok {
41		return ini, nil
42	}
43
44	inherited = GetPathByRelativePath(filename, inherited)
45	inheritedINI, err := LoadInheritedINI(inherited)
46	if err != nil {
47		return nil, errors.New(err.Error() + " " + inherited)
48	}
49
50	ini.Merge(inheritedINI, false)
51	return ini, nil
52}
53
54// Merge merges the data in another INI (from) to this INI (ini), and
55// from INI will not be changed
56func (ini *INI) Merge(from *INI, override bool) {
57	for section, kv := range from.sections {
58		for key, value := range kv {
59			_, found := ini.SectionGet(section, key)
60			if override || !found {
61				ini.SectionSet(section, key, value)
62			}
63		}
64	}
65}
66
67// GetPathByRelativePath gets the real path according to the relative file path
68// e.g. :
69// 	relativeFilePath = /home/goini/conf/common.conf
70//	inheritedPath = app.conf
71//
72// and then the GetPathByRelativePath(relativeFilePath, inheritedPath) will
73// return /home/goini/conf/app.conf
74func GetPathByRelativePath(relativeFilePath, inheritedPath string) string {
75	if filepath.IsAbs(inheritedPath) {
76		return inheritedPath
77	}
78
79	dir, _ := filepath.Split(relativeFilePath)
80	return filepath.Join(dir, inheritedPath)
81}