-
Notifications
You must be signed in to change notification settings - Fork 23
/
config.go
96 lines (79 loc) · 2.03 KB
/
config.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
package main
import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"gopkg.in/yaml.v2"
)
// Config holds all configuration for grobi.
type Config struct {
Rules []Rule
ExecuteAfter []string `yaml:"execute_after"`
OnFailure []string `yaml:"on_failure"`
}
// xdgConfigDir returns the config directory according to the xdg standard, see
// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html.
func xdgConfigDir() string {
if dir := os.Getenv("XDG_CONFIG_HOME"); dir != "" {
return dir
}
return filepath.Join(os.Getenv("HOME"), ".config")
}
// openConfigFile returns a reader for the config file.
func openConfigFile(name string) (io.ReadCloser, error) {
for _, filename := range []string{
name,
os.Getenv("GROBI_CONFIG"),
filepath.Join(xdgConfigDir(), "grobi.conf"),
filepath.Join(os.Getenv("HOME"), ".grobi.conf"),
"/etc/xdg/grobi.conf"} {
if filename != "" {
if f, err := os.Open(filename); err == nil {
V("reading config from %v\n", filename)
return f, nil
}
}
}
return nil, errors.New("could not find config file")
}
// readConfig returns a configuration struct read from a configuration file.
func readConfig(name string) (Config, error) {
rd, err := openConfigFile(name)
if err != nil {
return Config{}, err
}
buf, err := ioutil.ReadAll(rd)
if err != nil {
return Config{}, err
}
var cfg Config
err = yaml.Unmarshal(buf, &cfg)
if err != nil {
return Config{}, err
}
err = rd.Close()
if err != nil {
return Config{}, err
}
if err = cfg.Valid(); err != nil {
return Config{}, err
}
return cfg, nil
}
// Valid returns an error if the config is invalid, ie a pattern is malformed.
func (cfg Config) Valid() error {
for _, rule := range cfg.Rules {
for _, list := range [][]string{rule.OutputsPresent, rule.OutputsAbsent, rule.OutputsConnected, rule.OutputsDisconnected} {
for _, pat := range list {
if _, err := path.Match(pat, ""); err != nil {
return fmt.Errorf("pattern %q malformed: %v", pat, err)
}
}
}
}
return nil
}