-
Notifications
You must be signed in to change notification settings - Fork 0
/
collection.go
103 lines (84 loc) · 2.25 KB
/
collection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package settings
import (
"errors"
"fmt"
"os"
"os/user"
"path"
"runtime"
"gopkg.in/yaml.v2"
)
const defaultExtension = "yaml"
// ErrCollectionNotFound occurred when settings file cannot be found in search paths.
var ErrCollectionNotFound = errors.New("collection not found")
// Collection is a group of settings which are saved in a single yaml file.
type Collection struct {
name string
dirname string
// Extension is settings file extension, default is 'yaml'.
Extension string
// Paths is list of directories to look for settings file.
// Default values are as follows,
// - $HOME/.config
// - /etc (Non Windows)
// - /usr/local/etc (Non Windows)
SearchPaths []string
}
// Name returns name of this collection.
func (cl *Collection) Name() string {
return cl.name
}
// Load read settings file and unmarshal the content as given v.
// For example, if a collection created with directory name 'test' and named 'settings',
// with default extension, then this function will look for SEARCH_DIR/test/settings.yaml.
func (cl *Collection) Load(v interface{}) error {
if len(cl.SearchPaths) == 0 {
return nil
}
var (
filepath string
found = false
pathList = cl.SearchPaths
)
pathList = append(pathList, "")
for _, fpath := range pathList {
if fpath == "" {
filepath = fmt.Sprintf("%s.%s", cl.name, cl.Extension)
} else {
filepath = path.Join(fpath, cl.dirname, fmt.Sprintf("%s.%s", cl.name, cl.Extension))
}
if _, err := os.Stat(fpath); os.IsNotExist(err) {
continue
}
found = true
}
if !found {
return ErrCollectionNotFound
}
content, err := os.ReadFile(filepath)
if err != nil {
return err
}
return yaml.Unmarshal(content, v)
}
// NewCollection create new collection given its name and directory name.
func NewCollection(name, dirname string) (*Collection, error) {
collection := &Collection{
name: name,
dirname: dirname,
Extension: defaultExtension,
}
user, err := user.Current()
if err != nil {
return nil, err
}
os := runtime.GOOS
if os != "windows" {
collection.SearchPaths = append(collection.SearchPaths, []string{
"/etc",
"/usr/local/etc",
}...)
}
collection.SearchPaths = append(collection.SearchPaths, path.Join(user.HomeDir, ".config"))
return collection, nil
}