forked from hypnoglow/dotbro
/
configuration.go
134 lines (104 loc) · 2.53 KB
/
configuration.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
123
124
125
126
127
128
129
130
131
132
133
134
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"github.com/BurntSushi/toml"
)
// Configuration represents data from config file and additional parameters.
type Configuration struct {
Directories directories
Mapping map[string]string
Files files
Filepath string
}
type directories struct {
Dotfiles string `toml:"dotfiles" json:"dotfiles"`
Sources string `toml:"sources" json:"sources"`
Destination string
Backup string
}
type files struct {
Excludes []string
}
func processConf(c Configuration) Configuration {
c.Directories.Dotfiles = processAbsDir(
"directories.dotfiles_root",
c.Directories.Dotfiles,
path.Dir(c.Filepath),
)
c.Directories.Sources = processRelDir(
"directories.dotfiles_source",
c.Directories.Sources,
"",
)
c.Directories.Destination = processAbsDir(
"directories.destination",
c.Directories.Destination,
os.Getenv("HOME"),
)
c.Directories.Backup = processAbsDir(
"directories.backup",
c.Directories.Backup,
os.Getenv("HOME")+"/.dotfiles~",
)
return c
}
func processAbsDir(name string, dir string, defaultValue string) string {
if dir == "" {
return defaultValue
}
// parse possible ENV variable
dir = os.ExpandEnv(dir)
if !path.IsAbs(dir) {
outError("'%s' must be an absolute path.", name)
exit(1)
}
return dir
}
func processRelDir(name string, dir string, defaultValue string) string {
if dir == "" {
return defaultValue
}
// parse possible ENV variable
dir = os.ExpandEnv(dir)
if path.IsAbs(dir) {
outError("'%s' must be relative path (to 'directories.dotfiles_root').\n", name)
exit(1)
}
return dir
}
func fromTOML(filename string) (conf Configuration, err error) {
logger.msg("Parsing config file %s", filename)
if _, err := toml.DecodeFile(filename, &conf); err != nil {
return conf, err
}
conf.Filepath = filename
conf = processConf(conf)
return conf, nil
}
func fromJSON(filename string) (conf Configuration, err error) {
file, err := ioutil.ReadFile(filename)
if err != nil {
return conf, err
}
logger.msg("Parsing config file %s", filename)
json.Unmarshal(file, &conf)
conf.Filepath = filename
conf = processConf(conf)
return conf, nil
}
func configurationFromFile(filename string) (conf Configuration, err error) {
switch filepath.Ext(filename) {
case ".toml":
return fromTOML(filename)
case ".json":
return fromJSON(filename)
default:
err = fmt.Errorf("Cannot read config file %s : unknown extension. Supported: conf, toml.", filename)
return conf, err
}
}