|
|
|
package bake
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
hcl "github.com/hashicorp/hcl/v2"
|
|
|
|
"github.com/hashicorp/hcl/v2/hclsimple"
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
"github.com/zclconf/go-cty/cty/function"
|
|
|
|
"github.com/zclconf/go-cty/cty/function/stdlib"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Collection of generally useful functions in cty-using applications, which
|
|
|
|
// HCL supports. These functions are available for use in HCL files.
|
|
|
|
var (
|
|
|
|
functions = map[string]function.Function{
|
|
|
|
"absolute": stdlib.AbsoluteFunc,
|
|
|
|
"add": stdlib.AddFunc,
|
|
|
|
"and": stdlib.AndFunc,
|
|
|
|
"byteslen": stdlib.BytesLenFunc,
|
|
|
|
"bytesslice": stdlib.BytesSliceFunc,
|
|
|
|
"csvdecode": stdlib.CSVDecodeFunc,
|
|
|
|
"coalesce": stdlib.CoalesceFunc,
|
|
|
|
"concat": stdlib.ConcatFunc,
|
|
|
|
"divide": stdlib.DivideFunc,
|
|
|
|
"equal": stdlib.EqualFunc,
|
|
|
|
"formatdate": stdlib.FormatDateFunc,
|
|
|
|
"format": stdlib.FormatFunc,
|
|
|
|
"formatlist": stdlib.FormatListFunc,
|
|
|
|
"greaterthan": stdlib.GreaterThanFunc,
|
|
|
|
"greaterthanorequalto": stdlib.GreaterThanOrEqualToFunc,
|
|
|
|
"hasindex": stdlib.HasIndexFunc,
|
|
|
|
"index": stdlib.IndexFunc,
|
|
|
|
"int": stdlib.IntFunc,
|
|
|
|
"jsondecode": stdlib.JSONDecodeFunc,
|
|
|
|
"jsonencode": stdlib.JSONEncodeFunc,
|
|
|
|
"length": stdlib.LengthFunc,
|
|
|
|
"lessthan": stdlib.LessThanFunc,
|
|
|
|
"lessthanorequalto": stdlib.LessThanOrEqualToFunc,
|
|
|
|
"lower": stdlib.LowerFunc,
|
|
|
|
"max": stdlib.MaxFunc,
|
|
|
|
"min": stdlib.MinFunc,
|
|
|
|
"modulo": stdlib.ModuloFunc,
|
|
|
|
"multiply": stdlib.MultiplyFunc,
|
|
|
|
"negate": stdlib.NegateFunc,
|
|
|
|
"notequal": stdlib.NotEqualFunc,
|
|
|
|
"not": stdlib.NotFunc,
|
|
|
|
"or": stdlib.OrFunc,
|
|
|
|
"range": stdlib.RangeFunc,
|
|
|
|
"regexall": stdlib.RegexAllFunc,
|
|
|
|
"regex": stdlib.RegexFunc,
|
|
|
|
"reverse": stdlib.ReverseFunc,
|
|
|
|
"sethaselement": stdlib.SetHasElementFunc,
|
|
|
|
"setintersection": stdlib.SetIntersectionFunc,
|
|
|
|
"setsubtract": stdlib.SetSubtractFunc,
|
|
|
|
"setsymmetricdifference": stdlib.SetSymmetricDifferenceFunc,
|
|
|
|
"setunion": stdlib.SetUnionFunc,
|
|
|
|
"strlen": stdlib.StrlenFunc,
|
|
|
|
"substr": stdlib.SubstrFunc,
|
|
|
|
"subtract": stdlib.SubtractFunc,
|
|
|
|
"upper": stdlib.UpperFunc,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// Used in the first pass of decoding instead of the Config struct to disallow
|
|
|
|
// interpolation while parsing variable blocks.
|
|
|
|
type staticConfig struct {
|
|
|
|
Variables []*Variable `hcl:"variable,block"`
|
|
|
|
Remain hcl.Body `hcl:",remain"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParseHCL(dt []byte, fn string) (*Config, error) {
|
|
|
|
var sc staticConfig
|
|
|
|
|
|
|
|
// Decode only variable blocks without interpolation.
|
|
|
|
if err := hclsimple.Decode(fn, dt, nil, &sc); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
variables := make(map[string]cty.Value)
|
|
|
|
|
|
|
|
// Set all variables to their default value if defined.
|
|
|
|
for _, variable := range sc.Variables {
|
|
|
|
variables[variable.Name] = cty.StringVal(variable.Default)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override default with values from environment.
|
|
|
|
for _, env := range os.Environ() {
|
|
|
|
parts := strings.SplitN(env, "=", 2)
|
|
|
|
name, value := parts[0], parts[1]
|
|
|
|
if _, ok := variables[name]; ok {
|
|
|
|
variables[name] = cty.StringVal(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := &hcl.EvalContext{
|
|
|
|
Variables: variables,
|
|
|
|
Functions: functions,
|
|
|
|
}
|
|
|
|
|
|
|
|
var c Config
|
|
|
|
|
|
|
|
// Decode with variables and functions.
|
|
|
|
if err := hclsimple.Decode(fn, dt, ctx, &c); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &c, nil
|
|
|
|
}
|