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
|
package forgepb
// functions to import and export the protobuf
// data to and from config files
import (
"errors"
"os"
"path/filepath"
"go.wit.com/log"
)
// writes out the cluster information it seperate files
// to make it humanly possible to hand edit things as needed
func (m *Repos) ConfigSave() error {
if os.Getenv("FORGE_HOME") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
}
// try to backup the current cluster config files
if err := backupConfig(); err != nil {
return err
}
data, err := m.Marshal()
if err != nil {
log.Info("proto.Marshal() failed len", len(data), err)
return err
}
log.Info("proto.Marshal() worked len", len(data))
configWrite("forge.pb", data)
s := m.FormatTEXT()
configWrite("forge.text", []byte(s))
s = m.FormatJSON()
configWrite("forge.json", []byte(s))
return nil
}
func (m *Repos) ConfigLoad() error {
if os.Getenv("FORGE_HOME") == "" {
homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_HOME", fullpath)
}
var data []byte
var err error
if m == nil {
return errors.New("It's not safe to run ConfigLoad() on a nil ?")
}
if data, err = loadFile("forge.pb"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.pb file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
// try forge.text & forge.json?
}
if err = m.Unmarshal(data); err != nil {
log.Warn("broken forge.pb config file")
return err
}
log.Info("config load found", len(m.Repos), "repos")
return nil
}
// forge.db doesn't exist. try forge.text
// this lets the user hand edit the config
if data, err = loadFile("forge.text"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.text file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
}
if err = m.UnmarshalTEXT(data); err != nil {
log.Warn("broken forge.text config file")
return err
}
log.Info("config load found", len(m.Repos), "repos")
return nil
}
// forge.text doesn't exist. try forge.json
// this lets the user hand edit the config
if data, err = loadFile("forge.json"); err != nil {
// something went wrong loading the file
return err
}
if data != nil {
// this means the forge.text file exists and was read
if len(data) == 0 {
// todo: error out if the file is empty?
}
if err = m.UnmarshalJSON(data); err != nil {
log.Warn("broken forge.json config file")
return err
}
log.Info("config load found", len(m.Repos), "repos")
return nil
}
// first time user. make a template config file
return nil
}
func loadFile(filename string) ([]byte, error) {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
data, err := os.ReadFile(fullname)
if errors.Is(err, os.ErrNotExist) {
// if file does not exist, just return nil. this
// will cause ConfigLoad() to try the next config file like "forge.text"
// because the user might want to edit the .config by hand
return nil, nil
}
if err != nil {
// log.Info("open config file :", err)
return nil, err
}
return data, nil
}
func configWrite(filename string, data []byte) error {
fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename)
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666)
defer cfgfile.Close()
if err != nil {
log.Warn("open config file :", err)
return err
}
cfgfile.Write(data)
return nil
}
|