summaryrefslogtreecommitdiff
path: root/template.go
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2022-05-28 09:44:56 -0400
committerDave Henderson <dhenderson@gmail.com>2022-06-12 16:56:00 -0400
commit13b0d86d7630a89dc94b0a172b2d04ba8a236875 (patch)
tree5c5a39d70efdc30f8df19a71edab828244701e73 /template.go
parent0158ecc5e479c514898f406db63454e3570c56c6 (diff)
New gomplate.Renderer interface
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'template.go')
-rw-r--r--template.go93
1 files changed, 29 insertions, 64 deletions
diff --git a/template.go b/template.go
index 81ecbf14..2d67cf3c 100644
--- a/template.go
+++ b/template.go
@@ -5,7 +5,6 @@ import (
"fmt"
"io"
"io/fs"
- "io/ioutil"
"os"
"path"
"path/filepath"
@@ -27,15 +26,6 @@ const gomplateignore = ".gomplateignore"
// for overriding in tests
var aferoFS = afero.NewOsFs()
-// tplate - models a gomplate template file...
-type tplate struct {
- name string
- target io.Writer
- contents string
- mode os.FileMode
- modeOverride bool
-}
-
func addTmplFuncs(f template.FuncMap, root *template.Template, tctx interface{}, path string) {
t := tmpl.New(root, tctx, path)
tns := func() *tmpl.Template { return t }
@@ -74,24 +64,23 @@ func FSProviderFromContext(ctx context.Context) fsimpl.FSProvider {
return nil
}
-// toGoTemplate - parses t.contents as a Go template named t.name with the
-// configured funcMap, delimiters, and nested templates.
-func (t *tplate) toGoTemplate(ctx context.Context, g *gomplate) (tmpl *template.Template, err error) {
- tmpl = template.New(t.name)
+// parseTemplate - parses text as a Go template with the given name and options
+func parseTemplate(ctx context.Context, name, text string, funcs template.FuncMap, tmplctx interface{}, nested config.Templates, leftDelim, rightDelim string) (tmpl *template.Template, err error) {
+ tmpl = template.New(name)
tmpl.Option("missingkey=error")
- funcMap := copyFuncMap(g.funcMap)
+ funcMap := copyFuncMap(funcs)
// the "tmpl" funcs get added here because they need access to the root template and context
- addTmplFuncs(funcMap, tmpl, g.tmplctx, t.name)
+ addTmplFuncs(funcMap, tmpl, tmplctx, name)
tmpl.Funcs(funcMap)
- tmpl.Delims(g.leftDelim, g.rightDelim)
- _, err = tmpl.Parse(t.contents)
+ tmpl.Delims(leftDelim, rightDelim)
+ _, err = tmpl.Parse(text)
if err != nil {
return nil, err
}
- err = parseNestedTemplates(ctx, g.nestedTemplates, tmpl)
+ err = parseNestedTemplates(ctx, nested, tmpl)
if err != nil {
return nil, fmt.Errorf("parse nested templates: %w", err)
}
@@ -181,29 +170,9 @@ func parseNestedTemplate(ctx context.Context, fsys fs.FS, alias, fname string, t
return nil
}
-// loadContents - reads the template
-func (t *tplate) loadContents(in io.Reader) ([]byte, error) {
- if in == nil {
- f, err := aferoFS.OpenFile(t.name, os.O_RDONLY, 0)
- if err != nil {
- return nil, fmt.Errorf("failed to open %s: %w", t.name, err)
- }
- // nolint: errcheck
- defer f.Close()
- in = f
- }
-
- b, err := ioutil.ReadAll(in)
- if err != nil {
- return nil, fmt.Errorf("failed to load contents of %s: %w", t.name, err)
- }
-
- return b, nil
-}
-
-// gatherTemplates - gather and prepare input template(s) and output file(s) for rendering
+// gatherTemplates - gather and prepare templates for rendering
// nolint: gocyclo
-func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(context.Context, string) (string, error)) (templates []*tplate, err error) {
+func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(context.Context, string) (string, error)) (templates []Template, err error) {
mode, modeOverride, err := cfg.GetMode()
if err != nil {
return nil, err
@@ -219,12 +188,10 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
return nil, oerr
}
- templates = []*tplate{{
- name: "<arg>",
- contents: cfg.Input,
- target: target,
- mode: mode,
- modeOverride: modeOverride,
+ templates = []Template{{
+ Name: "<arg>",
+ Text: cfg.Input,
+ Writer: target,
}}
case cfg.InputDir != "":
// input dirs presume output dirs are set too
@@ -233,9 +200,9 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
return nil, err
}
case cfg.Input == "":
- templates = make([]*tplate, len(cfg.InputFiles))
+ templates = make([]Template, len(cfg.InputFiles))
for i := range cfg.InputFiles {
- templates[i], err = fileToTemplates(cfg, cfg.InputFiles[i], cfg.OutputFiles[i], mode, modeOverride)
+ templates[i], err = fileToTemplate(cfg, cfg.InputFiles[i], cfg.OutputFiles[i], mode, modeOverride)
if err != nil {
return nil, err
}
@@ -248,7 +215,7 @@ func gatherTemplates(ctx context.Context, cfg *config.Config, outFileNamer func(
// walkDir - given an input dir `dir` and an output dir `outDir`, and a list
// of .gomplateignore and exclude globs (if any), walk the input directory and create a list of
// tplate objects, and an error, if any.
-func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer func(context.Context, string) (string, error), excludeGlob []string, mode os.FileMode, modeOverride bool) ([]*tplate, error) {
+func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer func(context.Context, string) (string, error), excludeGlob []string, mode os.FileMode, modeOverride bool) ([]Template, error) {
dir = filepath.Clean(dir)
dirStat, err := aferoFS.Stat(dir)
@@ -257,7 +224,7 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
}
dirMode := dirStat.Mode()
- templates := make([]*tplate, 0)
+ templates := make([]Template, 0)
matcher := xignore.NewMatcher(aferoFS)
// work around bug in xignore - a basedir of '.' doesn't work
@@ -283,7 +250,7 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
return nil, err
}
- tpl, err := fileToTemplates(cfg, inFile, outFile, mode, modeOverride)
+ tpl, err := fileToTemplate(cfg, inFile, outFile, mode, modeOverride)
if err != nil {
return nil, err
}
@@ -299,21 +266,21 @@ func walkDir(ctx context.Context, cfg *config.Config, dir string, outFileNamer f
return templates, nil
}
-func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMode, modeOverride bool) (*tplate, error) {
+func fileToTemplate(cfg *config.Config, inFile, outFile string, mode os.FileMode, modeOverride bool) (Template, error) {
source := ""
//nolint:nestif
if inFile == "-" {
b, err := io.ReadAll(cfg.Stdin)
if err != nil {
- return nil, fmt.Errorf("failed to read from stdin: %w", err)
+ return Template{}, fmt.Errorf("failed to read from stdin: %w", err)
}
source = string(b)
} else {
si, err := aferoFS.Stat(inFile)
if err != nil {
- return nil, err
+ return Template{}, err
}
if mode == 0 {
mode = si.Mode()
@@ -323,7 +290,7 @@ func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMod
// file descriptors.
f, err := aferoFS.OpenFile(inFile, os.O_RDONLY, 0)
if err != nil {
- return nil, fmt.Errorf("failed to open %s: %w", inFile, err)
+ return Template{}, fmt.Errorf("failed to open %s: %w", inFile, err)
}
//nolint: errcheck
@@ -331,7 +298,7 @@ func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMod
b, err := io.ReadAll(f)
if err != nil {
- return nil, fmt.Errorf("failed to read %s: %w", inFile, err)
+ return Template{}, fmt.Errorf("failed to read %s: %w", inFile, err)
}
source = string(b)
@@ -341,15 +308,13 @@ func fileToTemplates(cfg *config.Config, inFile, outFile string, mode os.FileMod
// caller later
target, err := openOutFile(outFile, 0755, mode, modeOverride, cfg.Stdout, cfg.SuppressEmpty)
if err != nil {
- return nil, err
+ return Template{}, err
}
- tmpl := &tplate{
- name: inFile,
- contents: source,
- target: target,
- mode: mode,
- modeOverride: modeOverride,
+ tmpl := Template{
+ Name: inFile,
+ Text: source,
+ Writer: target,
}
return tmpl, nil