summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Dessaux2024-02-10 09:34:02 +0100
committerJulien Dessaux2024-03-07 00:58:47 +0100
commitc1d2b8912d333c7610f6f66c6e6f462227649f19 (patch)
treeebb72aebd03b1ba587c2d45262470e75adf408ab
parentfix(variables): fixed variable return value on error (diff)
downloadgonf-c1d2b8912d333c7610f6f66c6e6f462227649f19.tar.gz
gonf-c1d2b8912d333c7610f6f66c6e6f462227649f19.tar.bz2
gonf-c1d2b8912d333c7610f6f66c6e6f462227649f19.zip
feat(templates): generalised templating from file contents to any gonf value
-rw-r--r--gonf/files.go78
-rw-r--r--gonf/templates.go45
-rw-r--r--gonf/utils.go9
-rw-r--r--gonf/values.go36
4 files changed, 99 insertions, 69 deletions
diff --git a/gonf/files.go b/gonf/files.go
index 2401a25..ce6f6c8 100644
--- a/gonf/files.go
+++ b/gonf/files.go
@@ -5,9 +5,7 @@ import (
"crypto/sha256"
"io"
"log/slog"
- "net/url"
"os"
- "text/template"
)
// ----- Globals ---------------------------------------------------------------
@@ -19,26 +17,22 @@ func init() {
}
// ----- Public ----------------------------------------------------------------
-func File(filename string, contents []byte) *FilePromise {
- return &FilePromise{
- chain: nil,
- contents: contents,
- err: nil,
- filename: filename,
- status: PROMISED,
- templateFunctions: nil,
- useTemplate: false,
- }
+type FilePromise struct {
+ chain []Promise
+ contents Value
+ err error
+ filename Value
+ status Status
}
-type FilePromise struct {
- chain []Promise
- contents []byte
- err error
- filename string
- status Status
- templateFunctions map[string]any
- useTemplate bool
+func File(filename Value, contents Value) *FilePromise {
+ return &FilePromise{
+ chain: nil,
+ contents: contents,
+ err: nil,
+ filename: filename,
+ status: PROMISED,
+ }
}
func (f *FilePromise) IfRepaired(p ...Promise) Promise {
@@ -52,34 +46,17 @@ func (f *FilePromise) Promise() Promise {
}
func (f *FilePromise) Resolve() {
- if f.useTemplate {
- tpl := template.New(f.filename)
- tpl.Option("missingkey=error")
- tpl.Funcs(builtinTemplateFunctions)
- tpl.Funcs(f.templateFunctions)
- if ttpl, err := tpl.Parse(string(f.contents)); err != nil {
- f.status = BROKEN
- slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
- return
- } else {
- var buff bytes.Buffer
- if err := ttpl.Execute(&buff, 0 /* TODO */); err != nil {
- f.status = BROKEN
- slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
- return
- }
- f.contents = buff.Bytes()
- }
- }
+ filename := f.filename.String()
var sumFile []byte
- sumFile, f.err = sha256sumOfFile(f.filename)
+ sumFile, f.err = sha256sumOfFile(filename)
if f.err != nil {
f.status = BROKEN
return
}
- sumContents := sha256sum(f.contents)
+ contents := f.contents.Bytes()
+ sumContents := sha256sum(contents)
if !bytes.Equal(sumFile, sumContents) {
- if f.err = writeFile(f.filename, f.contents); f.err != nil {
+ if f.err = writeFile(filename, contents); f.err != nil {
f.status = BROKEN
slog.Error("file", "filename", f.filename, "status", f.status, "error", f.err)
return
@@ -95,24 +72,7 @@ func (f *FilePromise) Resolve() {
slog.Debug("file", "filename", f.filename, "status", f.status)
}
-func Template(filename string, contents []byte) *FilePromise {
- f := File(filename, contents)
- f.useTemplate = true
- return f
-}
-
-func TemplateWith(filename string, contents []byte, templateFunctions map[string]any) *FilePromise {
- f := Template(filename, contents)
- f.templateFunctions = templateFunctions
- return f
-}
-
// ----- Internal --------------------------------------------------------------
-var builtinTemplateFunctions = map[string]any{
- "encodeURIQueryParameter": url.QueryEscape,
- "var": getVariable,
-}
-
func resolveFiles() (status Status) {
status = KEPT
for _, f := range files {
diff --git a/gonf/templates.go b/gonf/templates.go
new file mode 100644
index 0000000..4d49c71
--- /dev/null
+++ b/gonf/templates.go
@@ -0,0 +1,45 @@
+package gonf
+
+import (
+ "bytes"
+ "log/slog"
+ "text/template"
+)
+
+// ----- Globals ---------------------------------------------------------------
+var templates *template.Template
+
+// ----- Init ------------------------------------------------------------------
+func init() {
+ templates = template.New("")
+ templates.Option("missingkey=error")
+ templates.Funcs(builtinTemplateFunctions)
+}
+
+// ----- Public ----------------------------------------------------------------
+type TemplateValue struct {
+ contents []byte
+ name string
+}
+
+func (t *TemplateValue) Bytes() []byte {
+ var buff bytes.Buffer
+ if err := templates.ExecuteTemplate(&buff, t.name, nil /* no data needed */); err != nil {
+ slog.Error("template", "step", "ExecuteTemplate", "name", t.name, "error", err)
+ return nil
+ }
+ return buff.Bytes()
+}
+
+func (t TemplateValue) String() string {
+ return string(t.Bytes()[:])
+}
+
+func Template(name string, contents []byte) *TemplateValue {
+ tpl := templates.New(name)
+ if _, err := tpl.Parse(string(contents)); err != nil {
+ slog.Error("template", "step", "Parse", "name", name, "error", err)
+ return nil
+ }
+ return &TemplateValue{contents, name}
+}
diff --git a/gonf/utils.go b/gonf/utils.go
index 7031062..109dbe8 100644
--- a/gonf/utils.go
+++ b/gonf/utils.go
@@ -1,6 +1,13 @@
package gonf
-import "crypto/sha256"
+import (
+ "crypto/sha256"
+)
+
+var builtinTemplateFunctions = map[string]any{
+ //"encodeURIQueryParameter": url.QueryEscape,
+ "var": getVariable,
+}
func sha256sum(contents []byte) []byte {
h := sha256.New()
diff --git a/gonf/values.go b/gonf/values.go
index 15c109b..69e4132 100644
--- a/gonf/values.go
+++ b/gonf/values.go
@@ -1,23 +1,41 @@
package gonf
type Value interface {
- Equals(Value) bool
+ Bytes() []byte
String() string
}
-// ----- String variables ------------------------------------------------------
-type StringValue struct {
- Value string
+// ----- BytesValue -----------------------------------------------------------------
+type BytesValue struct {
+ value []byte
+}
+
+func (b BytesValue) Bytes() []byte {
+ return b.value
}
-func (s StringValue) Equals(v Value) bool {
- sv, ok := v.(StringValue)
- return ok && s.Value == sv.Value
+func (b BytesValue) String() string {
+ return string(b.value[:])
}
+func Bytes(value []byte) *BytesValue {
+ return &BytesValue{value}
+}
+
+// ----- StringValue ----------------------------------------------------------------
+type StringValue struct {
+ value string
+}
+
+func (s StringValue) Bytes() []byte {
+ return []byte(s.value)
+}
func (s StringValue) String() string {
- // TODO handle interpolation
- return s.Value
+ return s.value
+}
+
+func String(value string) *StringValue {
+ return &StringValue{value}
}
// TODO lists