diff options
| author | Felix Hanley <felix@userspace.com.au> | 2020-02-13 05:09:06 +0000 |
|---|---|---|
| committer | Felix Hanley <felix@userspace.com.au> | 2020-02-13 05:09:06 +0000 |
| commit | 14d927947a5df3848e0fc15d3b60f9941141343f (patch) | |
| tree | d3c1ead68fb7394d281a5c194c38382256849b9f /templates.go | |
| download | templates-14d927947a5df3848e0fc15d3b60f9941141343f.tar.gz templates-14d927947a5df3848e0fc15d3b60f9941141343f.tar.bz2 | |
Untested implementation
Diffstat (limited to 'templates.go')
| -rw-r--r-- | templates.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/templates.go b/templates.go new file mode 100644 index 0000000..30b0301 --- /dev/null +++ b/templates.go @@ -0,0 +1,140 @@ +package templates + +import ( + "bytes" + "encoding/base64" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "text/template" +) + +type Templates struct { + base string + pkg string + extension string + fName string + sources map[string]io.ReadCloser +} + +func New(opts ...Option) (*Templates, error) { + out := &Templates{ + pkg: "main", + extension: ".tmpl", + base: "./", + fName: "loadTemplate", + } + for _, o := range opts { + if err := o(out); err != nil { + return nil, err + } + } + srcs, err := readTemplates(out.base, "."+out.extension) + if err != nil { + return nil, err + } + out.sources = srcs + return out, nil +} + +type Option func(*Templates) error + +func Base(p string) Option { + return func(t *Templates) error { + var err error + t.base, err = filepath.Abs(p) + return err + } +} + +func Extension(e string) Option { + return func(t *Templates) error { + t.extension = e + return nil + } +} +func Package(p string) Option { + return func(t *Templates) error { + t.pkg = p + return nil + } +} + +func readTemplates(root, extension string) (map[string]io.ReadCloser, error) { + out := make(map[string]io.ReadCloser) + filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + if !strings.HasSuffix(path, extension) { + return nil + } + varName := strings.TrimPrefix(path, root) + varName = strings.TrimSuffix(varName, extension) + rc, err := os.Open(path) + if err != nil { + return err + } + out[varName] = rc + return nil + }) + return out, nil +} + +func (t *Templates) WriteTo(w io.Writer) (int64, error) { + tmpl, err := template.New("loader").Parse(loader) + if err != nil { + return 0, err + } + data := make(map[string]string, len(t.sources)) + for k, rc := range t.sources { + b, err := ioutil.ReadAll(rc) + if err != nil { + return 0, err + } + data[k] = base64.StdEncoding.EncodeToString(b) + } + var buf bytes.Buffer + if err := tmpl.Execute(&buf, struct { + Package string + Base string + FName string + Templates map[string]string + }{t.pkg, t.base, t.fName, data}); err != nil { + return 0, err + } + return buf.WriteTo(w) +} + +const loader = `package {{ .Package }} + +import ( + "encoding/base64" + "fmt" + "io/ioutil" +) + +func {{ .FName }}(n string) ([]byte, error) { + var templates = map[string]string { +{{ $name, $data := range .Templates }} + "{{ $name }}": ` + "`" + `{{ $data }}` + "`" + `, +{{ end }} + } + + d, ok := templates[n] + if !ok { + return nil, fmt.Errorf("template not found") + } + // Check for overriding file + b, err := ioutil.ReadFile("{{ .Base }}" + n + "{{ .Extension }}") + if err == nil && b != nil { + return b, nil + } + return base64.StdEncoding.DecodeString(d) +} +` |
