0147c3e13e
Users of kontemplate may expect variables defined on the parent resource to be inherited by children. This implements that functionality. Values defined twice are overwritten by the child's definition. Fixes #20
93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package context
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/ghodss/yaml"
|
|
"github.com/polydawn/meep"
|
|
"github.com/tazjin/kontemplate/util"
|
|
)
|
|
|
|
type ResourceSet struct {
|
|
Name string `json:"name"`
|
|
Values map[string]interface{} `json:"values"`
|
|
|
|
// Fields for resource set collections
|
|
Include []ResourceSet `json:"include"`
|
|
Parent string
|
|
}
|
|
|
|
type Context struct {
|
|
Name string `json:"context"`
|
|
Global map[string]interface{} `json:"global"`
|
|
ResourceSets []ResourceSet `json:"include"`
|
|
BaseDir string
|
|
}
|
|
|
|
type ContextLoadingError struct {
|
|
meep.AllTraits
|
|
Filename string
|
|
}
|
|
|
|
// Attempt to load and deserialise a Context from the specified file.
|
|
func LoadContextFromFile(filename string) (*Context, error) {
|
|
file, err := ioutil.ReadFile(filename)
|
|
|
|
if err != nil {
|
|
return nil, meep.New(
|
|
&ContextLoadingError{Filename: filename},
|
|
meep.Cause(err),
|
|
)
|
|
}
|
|
|
|
var c Context
|
|
|
|
if strings.HasSuffix(filename, "json") {
|
|
err = json.Unmarshal(file, &c)
|
|
} else if strings.HasSuffix(filename, "yaml") || strings.HasSuffix(filename, "yml") {
|
|
err = yaml.Unmarshal(file, &c)
|
|
} else {
|
|
return nil, meep.New(
|
|
&ContextLoadingError{Filename: filename},
|
|
meep.Cause(fmt.Errorf("File format not supported. Must be JSON or YAML.")),
|
|
)
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, meep.New(
|
|
&ContextLoadingError{Filename: filename},
|
|
meep.Cause(err),
|
|
)
|
|
}
|
|
|
|
c.ResourceSets = *flattenResourceSetCollections(&c.ResourceSets)
|
|
c.BaseDir = path.Dir(filename)
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
// Flattens resource set collections, i.e. resource sets that themselves have an additional 'include' field set.
|
|
// Those will be regarded as a short-hand for including multiple resource sets from a subfolder.
|
|
// See https://github.com/tazjin/kontemplate/issues/9 for more information.
|
|
func flattenResourceSetCollections(rs *[]ResourceSet) *[]ResourceSet {
|
|
flattened := make([]ResourceSet, 0)
|
|
|
|
for _, r := range *rs {
|
|
if len(r.Include) == 0 {
|
|
flattened = append(flattened, r)
|
|
} else {
|
|
for _, subResourceSet := range r.Include {
|
|
subResourceSet.Parent = r.Name
|
|
subResourceSet.Name = path.Join(r.Name, subResourceSet.Name)
|
|
subResourceSet.Values = *util.Merge(&r.Values, &subResourceSet.Values)
|
|
flattened = append(flattened, subResourceSet)
|
|
}
|
|
}
|
|
}
|
|
|
|
return &flattened
|
|
}
|