diff options
author | Julien Dessaux | 2024-02-10 09:34:02 +0100 |
---|---|---|
committer | Julien Dessaux | 2024-03-07 00:58:47 +0100 |
commit | c1d2b8912d333c7610f6f66c6e6f462227649f19 (patch) | |
tree | ebb72aebd03b1ba587c2d45262470e75adf408ab | |
parent | fix(variables): fixed variable return value on error (diff) | |
download | gonf-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.go | 78 | ||||
-rw-r--r-- | gonf/templates.go | 45 | ||||
-rw-r--r-- | gonf/utils.go | 9 | ||||
-rw-r--r-- | gonf/values.go | 36 |
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 |