131 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package templater
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io/ioutil"
 | |
| 	"os"
 | |
| 	"path"
 | |
| 	"strings"
 | |
| 	"text/template"
 | |
| 
 | |
| 	"github.com/polydawn/meep"
 | |
| 	"github.com/tazjin/kontemplate/context"
 | |
| )
 | |
| 
 | |
| // 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(limit *[]string, c *context.Context) (output []string, err error) {
 | |
| 	for _, rs := range c.ResourceSets {
 | |
| 		if resourceSetIncluded(limit, &rs.Name) {
 | |
| 			err = processResourceSet(c, &rs, &output)
 | |
| 
 | |
| 			if err != nil {
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func resourceSetIncluded(limit *[]string, resourceSetName *string) bool {
 | |
| 	if len(*limit) == 0 {
 | |
| 		return true
 | |
| 	}
 | |
| 
 | |
| 	for _, name := range *limit {
 | |
| 		if name == *resourceSetName {
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func processResourceSet(c *context.Context, rs *context.ResourceSet, output *[]string) error {
 | |
| 	fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
 | |
| 
 | |
| 	rp := path.Join(c.BaseDir, rs.Name)
 | |
| 	files, err := ioutil.ReadDir(rp)
 | |
| 
 | |
| 	err = processFiles(c, rs, rp, files, output)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return meep.New(
 | |
| 			&TemplateNotFoundError{Name: rs.Name},
 | |
| 			meep.Cause(err),
 | |
| 		)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func processFiles(c *context.Context, rs *context.ResourceSet, rp string, files []os.FileInfo, output *[]string) error {
 | |
| 	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 err
 | |
| 			}
 | |
| 
 | |
| 			*output = append(*output, o)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 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
 | |
| 
 | |
| 	// Guard against empty map before merging keys
 | |
| 	if rs.Values == nil {
 | |
| 		rs.Values = make(map[string]interface{}, 0)
 | |
| 	}
 | |
| 
 | |
| 	// 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")
 | |
| }
 |