/
config_file.go
154 lines (134 loc) · 4.07 KB
/
config_file.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Package userConfig eases the use of config files in a user's home directory
package userConfig
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"os"
"strconv"
"strings"
"time"
"github.com/BurntSushi/toml"
)
// GeneralConfig is the basic config structure
// All configs make with package userConfig will have this file
type GeneralConfig struct {
Name string `toml:"-"`
Path string `toml:"-"`
ConfigFiles []string `toml:"additional_config"`
RawFiles []string `toml:"raw_files"`
Values map[string]string `toml:"general"`
}
// NewGeneralConfig generates a General Config struct
func NewGeneralConfig(name, path string) (*GeneralConfig, error) {
gf := &GeneralConfig{Name: name, Path: path}
gf.ConfigFiles = []string{}
gf.RawFiles = []string{}
gf.Values = make(map[string]string)
if err := gf.Load(); err != nil {
return gf, err
}
return gf, nil
}
// Load loads config files into the config
func (gf *GeneralConfig) Load() error {
if strings.TrimSpace(gf.Name) == "" || strings.TrimSpace(gf.Path) == "" {
return errors.New("Invalid ConfigFile Name: " + gf.Path + string(os.PathSeparator) + gf.Name)
}
// Config files end with .conf
cfgPath := gf.Path + string(os.PathSeparator) + gf.Name + ".conf"
tomlData, err := ioutil.ReadFile(cfgPath)
if err != nil {
// Couldn't find the file, save a new one
if err = gf.Save(); err != nil {
return err
}
}
if _, err := toml.Decode(string(tomlData), &gf); err != nil {
return err
}
return nil
}
// Save writes the config to file(s)
func (gf *GeneralConfig) Save() error {
buf := new(bytes.Buffer)
cfgPath := gf.Path + string(os.PathSeparator) + gf.Name + ".conf"
if err := toml.NewEncoder(buf).Encode(gf); err != nil {
return err
}
return ioutil.WriteFile(cfgPath, buf.Bytes(), 0644)
}
// GetKeyList returns a list of all keys in the config file
func (gf *GeneralConfig) GetKeyList() []string {
var ret []string
for k, _ := range gf.Values {
ret = append(ret, k)
}
return ret
}
// Set sets a key/value pair in gf, if unable to save, revert to old value
// (and return the error)
func (gf *GeneralConfig) Set(k, v string) error {
oldVal := gf.Values[k]
gf.Values[k] = v
if err := gf.Save(); err != nil {
gf.Values[k] = oldVal
return err
}
return nil
}
// SetBytes at the config level sets a value in the <c.name>.conf file
func (gf *GeneralConfig) SetBytes(k string, v []byte) error {
return gf.Set(k, string(v))
}
// SetInt sets an integer value (as a string) in the config file
func (gf *GeneralConfig) SetInt(k string, v int) error {
return gf.Set(k, strconv.Itoa(v))
}
// SetDateTime sets a DateTime value (as a string) in the config file
func (gf *GeneralConfig) SetDateTime(k string, v time.Time) error {
return gf.Set(k, v.Format(time.RFC3339))
}
// SetArray sets a string slice value (as a string) in the config file
func (gf *GeneralConfig) SetArray(k string, v []string) error {
b, e := json.Marshal(v)
if e != nil {
return e
}
return gf.SetBytes(k, b)
}
// Get gets a key/value pair from gf
func (gf *GeneralConfig) Get(k string) string {
return gf.Values[k]
}
// GetInt gets a key/value pair from gf and return it as an integer
// An error if it can't be converted
func (gf *GeneralConfig) GetInt(k string) (int, error) {
return strconv.Atoi(gf.Get(k))
}
// GetDateTime gets a key/value pair from gf and returns it as a time.Time
// An error if it can't be converted
func (gf *GeneralConfig) GetDateTime(k string) (time.Time, error) {
return time.Parse(time.RFC3339, gf.Get(k))
}
// GetBytes gets a key/value pair from gf and returns it as a byte slice
// Or an error if it fails for whatever reason
func (gf *GeneralConfig) GetBytes(k string) []byte {
return []byte(gf.Get(k))
}
func (gf *GeneralConfig) GetArray(k string) ([]string, error) {
var ret []string
err := json.Unmarshal(gf.GetBytes(k), &ret)
return ret, err
}
// DeleteKey removes a key from the file
func (gf *GeneralConfig) DeleteKey(k string) error {
oldVal := gf.Get(k)
delete(gf.Values, k)
if err := gf.Save(); err != nil {
gf.Values[k] = oldVal
return err
}
return nil
}