/
main.go
160 lines (133 loc) · 3.54 KB
/
main.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
155
156
157
158
159
160
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"path/filepath"
"regexp"
"sort"
"strings"
"text/template"
)
var moduleTmpl = template.Must(template.New("registerModules").Funcs(template.FuncMap{
"title": strings.Title,
}).Parse(`package main
import (
"log"
{{range . -}}
"github.com/Necroforger/Fantasia/modules/{{.Name}}"
{{end}}
"github.com/Necroforger/Fantasia/system"
)
////////////////////////////////////////////
// Generated by
// tools/genmodules
////////////////////////////////////////////
// ModuleConfig ...
type ModuleConfig struct {
Inverted bool
{{range . -}}
{{title .Name}} bool
{{end}}
{{range . -}}{{if .HasConfig -}}
{{title .Name}}Config *{{.Name}}.Config
{{end}}{{end}}
}
// NewModuleConfig returns a new module configuration
func NewModuleConfig() ModuleConfig {
return ModuleConfig{
Inverted: false,
{{range . -}}
{{title .Name}}: true,
{{end}}
{{range . -}}{{if .HasConfig -}}
{{title .Name}}Config: {{.Name}}.NewConfig(),
{{end}}{{end}}
}
}
// RegisterModules builds a list of modules into the given system
func RegisterModules(s *system.System, config ModuleConfig) {
{{range . -}}
if (config.Inverted && !config.{{title .Name}}) || (!config.Inverted && config.{{title .Name}}) {
s.CommandRouter.SetCategory("{{title .Name}}")
{{- if .HasConfig}}
if config.{{title .Name}}Config != nil {
s.BuildModule(&{{.Name}}.Module{Config: config.{{title .Name}}Config })
} else {
s.BuildModule(&{{.Name}}.Module{Config: {{.Name}}.NewConfig()})
}
{{else}}
s.BuildModule(&{{.Name}}.Module{})
{{end -}}
log.Println("loaded {{.Name}} module...")
}
{{end}}
}
`))
// ModuleList ...
type ModuleList struct {
HasConfig bool
Name string
}
// ModuleListByNames ...
type ModuleListByNames []ModuleList
// Len ...
func (m ModuleListByNames) Len() int {
return len(m)
}
// Less ...
func (m ModuleListByNames) Less(a, b int) bool {
return m[a].Name < m[b].Name
}
// Swap ...
func (m ModuleListByNames) Swap(a, b int) {
m[a], m[b] = m[b], m[a]
}
func main() {
var (
output bytes.Buffer
currentDir = filepath.Dir(".")
)
modules, err := ioutil.ReadDir("vendor/github.com/Necroforger/Fantasia/modules")
if err != nil {
fmt.Println("error: modules folder does not exist")
return
}
moduleList := []ModuleList{}
for _, v := range modules {
moduleList = append(moduleList,
ModuleList{false, v.Name()})
}
// Scan over all the main package files to see if they have a Configuration available.
for i, v := range modules {
data, err := ioutil.ReadFile(filepath.Join(currentDir, "vendor/github.com/Necroforger/Fantasia/modules", v.Name(), v.Name()+".go"))
if err != nil {
fmt.Println(err)
continue
}
// Check if the file meets all the requirements for having a config
if regexp.MustCompile("(?m:^//genmodules:config)").MatchString(string(data)) &&
regexp.MustCompile("(?m:^type Config struct)").MatchString(string(data)) &&
regexp.MustCompile(`(?m:^func NewConfig())`).MatchString(string(data)) {
moduleList[i].HasConfig = true
}
}
fmt.Println(moduleList)
sort.Sort(ModuleListByNames(moduleList))
err = moduleTmpl.Execute(&output, moduleList)
if err != nil {
fmt.Println("error: template failed to execute", err)
return
}
src, err := format.Source(output.Bytes())
if err != nil {
fmt.Println("error: invalid Go generated", err)
fmt.Println(string(output.Bytes()))
return
}
err = ioutil.WriteFile(filepath.Join(currentDir, "register_modules.go"), src, 0644)
if err != nil {
fmt.Println("error: failed to output file: ", err)
}
}