-
Notifications
You must be signed in to change notification settings - Fork 8
/
template.go
131 lines (104 loc) · 2.96 KB
/
template.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
package main
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/cbroglie/mustache"
"golang.org/x/exp/slices"
yaml "gopkg.in/yaml.v3"
)
type template struct {
Name string `yaml:"-"`
Dir string `yaml:"-"`
Filename string `yaml:"filename"`
Extension string `yaml:"extension"`
OutputDir string `yaml:"output"`
SupportedSystems []string `yaml:"supported-systems"`
}
func templatesFromFile(templatesDir string) ([]*template, error) {
data, err := ioutil.ReadFile(filepath.Join(templateDir, "templates", "config.yaml"))
if err != nil {
return nil, err
}
out := make(map[string]*template)
err = yaml.Unmarshal(data, out)
if err != nil {
return nil, err
}
ret := []*template{}
for k, t := range out {
t.Name = k
t.Dir = templatesDir
if t.Filename == "" {
log.Info("Filename missing from theme config block, inferring from OutputDir and Extension")
if t.OutputDir == "" {
log.Warn("OutputDir missing from theme config block")
t.OutputDir = "."
}
if t.Extension == "" {
return nil, errors.New("Extension missing from theme config block")
}
t.Filename = fmt.Sprintf("%s/{{ scheme-system }}-{{ scheme-slug }}%s", t.OutputDir, t.Extension)
}
if len(t.SupportedSystems) == 0 {
log.Warn("Systems not set in theme config block, inferring base16")
t.SupportedSystems = []string{"base16"}
}
log.Debugf("Found template %q in dir %q", t.Name, t.Dir)
ret = append(ret, t)
}
return ret, nil
}
func (t *template) Render(schemes []*ColorScheme) error {
m, err := mustache.ParseFile(filepath.Join(t.Dir, "templates", t.Name+".mustache"))
if err != nil {
return err
}
outputDir := filepath.Join(t.Dir, t.OutputDir)
stat, err := os.Stat(outputDir)
if err != nil {
log.Warnf("Directory %s does not exist. Creating.", outputDir)
err = os.MkdirAll(outputDir, os.ModePerm)
if err != nil {
return err
}
} else if !stat.IsDir() {
return fmt.Errorf("Output dir %s is not a dir", outputDir)
}
var templateRendered bool
for _, scheme := range schemes {
templateVariables := scheme.TemplateVariables()
// If the scheme's system wasn't in this template's supported systems
// list, we skip it.
if !slices.Contains(t.SupportedSystems, scheme.System) {
continue
}
filenameTemplate, err := mustache.ParseString(t.Filename)
if err != nil {
return err
}
fileName, err := filenameTemplate.Render(templateVariables)
if err != nil {
return err
}
rendered, err := m.Render(templateVariables)
if err != nil {
return err
}
// We use 666 as the filemode here rather than 777 because we don't want
// it executable by default.
err = os.WriteFile(fileName, []byte(rendered), 0666)
if err != nil {
return err
}
templateRendered = true
}
// We want to ensure at least 1 valid scheme exists for each template being
// rendered.
if !templateRendered {
return errors.New("No valid schemes for template")
}
return nil
}