103 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
| package tmpl
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"gopkg.in/yaml.v2"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"text/template"
 | |
| )
 | |
| 
 | |
| type Values = map[string]interface{}
 | |
| 
 | |
| func (c *Context) createFuncMap() template.FuncMap {
 | |
| 	return template.FuncMap{
 | |
| 		"readFile":       c.ReadFile,
 | |
| 		"toYaml":         ToYaml,
 | |
| 		"fromYaml":       FromYaml,
 | |
| 		"setValueAtPath": SetValueAtPath,
 | |
| 		"requiredEnv":    RequiredEnv,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (c *Context) ReadFile(filename string) (string, error) {
 | |
| 	path := filepath.Join(c.basePath, filename)
 | |
| 
 | |
| 	bytes, err := c.readFile(path)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	return string(bytes), nil
 | |
| }
 | |
| 
 | |
| func ToYaml(v interface{}) (string, error) {
 | |
| 	data, err := yaml.Marshal(v)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	return string(data), nil
 | |
| }
 | |
| 
 | |
| func FromYaml(str string) (Values, error) {
 | |
| 	m := Values{}
 | |
| 
 | |
| 	if err := yaml.Unmarshal([]byte(str), &m); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return m, nil
 | |
| }
 | |
| 
 | |
| func SetValueAtPath(path string, value interface{}, values Values) (Values, error) {
 | |
| 	var current interface{}
 | |
| 	current = values
 | |
| 	components := strings.Split(path, ".")
 | |
| 	pathToMap := components[:len(components)-1]
 | |
| 	key := components[len(components)-1]
 | |
| 	for _, k := range pathToMap {
 | |
| 		var elem interface{}
 | |
| 
 | |
| 		switch typedCurrent := current.(type) {
 | |
| 		case map[string]interface{}:
 | |
| 			v, exists := typedCurrent[k]
 | |
| 			if !exists {
 | |
| 				return nil, fmt.Errorf("failed to set value at path \"%s\": value for key \"%s\" does not exist", path, k)
 | |
| 			}
 | |
| 			elem = v
 | |
| 		case map[interface{}]interface{}:
 | |
| 			v, exists := typedCurrent[k]
 | |
| 			if !exists {
 | |
| 				return nil, fmt.Errorf("failed to set value at path \"%s\": value for key \"%s\" does not exist", path, k)
 | |
| 			}
 | |
| 			elem = v
 | |
| 		default:
 | |
| 			return nil, fmt.Errorf("failed to set value at path \"%s\": value for key \"%s\" was not a map", path, k)
 | |
| 		}
 | |
| 
 | |
| 		switch typedElem := elem.(type) {
 | |
| 		case map[string]interface{}, map[interface{}]interface{}:
 | |
| 			current = typedElem
 | |
| 		default:
 | |
| 			return nil, fmt.Errorf("failed to set value at path \"%s\": value for key \"%s\" was not a map", path, k)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	switch typedCurrent := current.(type) {
 | |
| 	case map[string]interface{}:
 | |
| 		typedCurrent[key] = value
 | |
| 	case map[interface{}]interface{}:
 | |
| 		typedCurrent[key] = value
 | |
| 	default:
 | |
| 		return nil, fmt.Errorf("failed to set value at path \"%s\": value for key \"%s\" was not a map", path, key)
 | |
| 	}
 | |
| 	return values, nil
 | |
| }
 | |
| 
 | |
| func RequiredEnv(name string) (string, error) {
 | |
| 	if val, exists := os.LookupEnv(name); exists && len(val) > 0 {
 | |
| 		return val, nil
 | |
| 	}
 | |
| 
 | |
| 	return "", fmt.Errorf("required env var `%s` is not set", name)
 | |
| }
 |