about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2017-02-08T10·50+0100
committerVincent Ambo <tazjin@gmail.com>2017-02-08T10·50+0100
commit9e3ee3f2bbce7c7cb2aaea3de2ffb23b17a030ca (patch)
tree47ad76bd127ee4ea631c93083147a05cabe4492f
parentbb45bfa737896c6f26ef4a816458bbfe508b8280 (diff)
feat templater: Add initial templating support
-rw-r--r--templater/templater.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/templater/templater.go b/templater/templater.go
new file mode 100644
index 000000000000..f4be1e6fa60d
--- /dev/null
+++ b/templater/templater.go
@@ -0,0 +1,97 @@
+package templater
+
+import (
+	"fmt"
+	"io/ioutil"
+	"strings"
+	"os"
+	"path"
+	"text/template"
+	"bytes"
+
+	"github.com/tazjin/kontemplate/context"
+	"github.com/polydawn/meep"
+)
+
+// Error that is caused by non-existent template files being specified
+type TemplateNotFoundError struct {
+	meep.AllTraits
+	Name string
+}
+
+// Error that is caused during templating, e.g. required value being absent or invalid template format
+type TemplatingError struct {
+	meep.AllTraits
+}
+
+func LoadAndPrepareTemplates(c *context.Context) ([]string, error) {
+	output := make([]string, 0)
+
+	for _, rs := range c.ResourceSets {
+		fmt.Fprintf(os.Stderr,"Loading resources for %s\n", rs.Name)
+
+		rp := path.Join(c.BaseDir, rs.Name)
+		files, err := ioutil.ReadDir(rp)
+
+		if err != nil {
+			return nil, meep.New(
+				&TemplateNotFoundError{Name: rs.Name},
+				meep.Cause(err),
+			)
+		}
+
+
+		for _, file := range files {
+			if !file.IsDir() && isResourceFile(file) {
+				p := path.Join(rp, file.Name())
+				o, err := templateFile(c, &rs, p)
+
+				if err != nil {
+					return nil, err
+				}
+
+				output = append(output, o)
+			}
+		}
+	}
+
+	return output, nil
+}
+
+func templateFile(c *context.Context, rs *context.ResourceSet, filename string) (string, error) {
+	tpl, err := template.ParseFiles(filename)
+
+	if err != nil {
+		return "", meep.New(
+			&TemplateNotFoundError{Name: filename},
+			meep.Cause(err),
+		)
+	}
+
+	var b bytes.Buffer
+
+	// Merge global and resourceset-specific values (don't override from global)
+	for k, v := range c.Global {
+		if _, ok := rs.Values[k]; !ok {
+			rs.Values[k] = v
+		}
+	}
+
+	err = tpl.Execute(&b, rs.Values)
+
+	if err != nil {
+		return "", meep.New(
+			&TemplatingError{},
+			meep.Cause(err),
+		)
+	}
+
+	return b.String(), nil
+}
+
+// Checks whether a file is a resource file (i.e. is YAML or JSON)
+func isResourceFile(f os.FileInfo) bool {
+	return strings.HasSuffix(f.Name(), "yaml") ||
+		strings.HasSuffix(f.Name(), "yml") ||
+		strings.HasSuffix(f.Name(), "json")
+}