summaryrefslogtreecommitdiff
path: root/templates.go
diff options
context:
space:
mode:
authorFelix Hanley <felix@userspace.com.au>2020-02-13 05:09:06 +0000
committerFelix Hanley <felix@userspace.com.au>2020-02-13 05:09:06 +0000
commit14d927947a5df3848e0fc15d3b60f9941141343f (patch)
treed3c1ead68fb7394d281a5c194c38382256849b9f /templates.go
downloadtemplates-14d927947a5df3848e0fc15d3b60f9941141343f.tar.gz
templates-14d927947a5df3848e0fc15d3b60f9941141343f.tar.bz2
Untested implementation
Diffstat (limited to 'templates.go')
-rw-r--r--templates.go140
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)
+}
+`