-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathload.go
122 lines (106 loc) · 2.37 KB
/
load.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package config
import (
"go/build"
"log"
"os"
"path/filepath"
"github.com/kyoh86/xdg"
yaml "gopkg.in/yaml.v2"
)
const (
// Filename is filename of configurations for this app.
Filename = ".richstyle"
// LocalOnlyEnvName is the name of environment variable
// to stop searching configuration files excepting current directory.
LocalOnlyEnvName = "RICHGO_LOCAL"
)
var (
// Extensions is extension choices of configurations for this app.
Extensions = []string{
"",
".yaml",
".yml",
}
// C is global configuration
C Config
)
func loadableSources() []string {
dirs := []string{}
if dir, err := os.Getwd(); err == nil {
dirs = append(dirs, dir)
}
localOnly := os.Getenv(LocalOnlyEnvName)
if localOnly != "1" {
dirs = append(dirs, build.Default.GOPATH)
dirs = appendIndirect(dirs, getEnvPath("GOROOT"))
if xdgHome := xdg.ConfigHome(); xdgHome != "" {
dirs = append(dirs, xdgHome)
}
dirs = appendIndirect(dirs, getEnvPath("HOME"))
}
paths := make([]string, 0, len(dirs)*len(Extensions))
for _, d := range dirs {
for _, e := range Extensions {
paths = append(paths, filepath.Join(d, Filename+e))
}
}
return paths
}
var loadForTest func(path string) ([]byte, error)
func load(path string) ([]byte, error) {
if loadForTest != nil {
return loadForTest(path)
}
return os.ReadFile(path)
}
// Load configurations from file
func Load() {
paths := loadableSources()
c := &defaultConfig
for _, p := range paths {
data, err := load(p)
if err != nil {
if !os.IsNotExist(err) {
log.Println("error reading from", p, ": ", err)
}
continue
}
var loaded Config
if err := yaml.Unmarshal(data, &loaded); err != nil {
log.Println("error unmarshaling yaml from", p, ": ", err)
continue
}
c = concatConfig(&loaded, c)
}
C = *actualConfig(c)
}
// Default is the default configuration
func Default() {
C = *actualConfig(&defaultConfig)
}
func appendIndirect(arr []string, ptr *string) []string {
if ptr != nil {
return append(arr, *ptr)
}
return arr
}
func getEnvPath(envName string) *string {
envPath := os.Getenv(envName)
if envPath == "" {
return nil
}
if isDir(envPath) {
return &envPath
}
return nil
}
var isDirForTest func(path string) bool
func isDir(path string) bool {
if isDirForTest != nil {
return isDirForTest(path)
}
if stat, err := os.Stat(path); err == nil && stat.IsDir() {
return true
}
return false
}