summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorMartin Atkins <mart@degeneration.co.uk>2018-02-04 10:33:35 -0800
committerMartin Atkins <mart@degeneration.co.uk>2018-02-04 10:33:35 -0800
commit6c3ae68a0e00743020f02aa21a76f3d37ca215c9 (patch)
treedef16b4d57c473ca6cc991e9975dfda54f3f1e44 /cmd
parent1ba92ee170ac6300d0538850241a953118bc85ef (diff)
cmd/hcldec: make cty stdlib functions available to specs
In a few specific portions of the spec format it's convenient to have access to some of the functions defined in the cty stdlib. Here we allow them to be used when constructing the value for a "literal" spec and in the result expression for a "transform" spec.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/hcldec/spec-format.md27
-rw-r--r--cmd/hcldec/spec.go11
-rw-r--r--cmd/hcldec/spec_funcs.go24
3 files changed, 58 insertions, 4 deletions
diff --git a/cmd/hcldec/spec-format.md b/cmd/hcldec/spec-format.md
index 2126d69..69b21b8 100644
--- a/cmd/hcldec/spec-format.md
+++ b/cmd/hcldec/spec-format.md
@@ -274,7 +274,8 @@ literal {
`literal` spec blocks accept the following argument:
-* `value` (required) - The value to return.
+* `value` (required) - The value to return. This attribute may be an expression
+ that uses [functions](#functions).
`literal` is a leaf spec type, so no nested spec blocks are permitted.
@@ -330,6 +331,30 @@ transform {
spec. The variable `nested` is defined when evaluating this expression, with
the result value of the nested spec.
+The `result` expression may use [functions](#functions).
+
+## Functions
+
+Certain expressions within a specification may use the following functions.
+The documentation for each spec type above specifies where functions may
+be used.
+
+* `abs(number)` returns the absolute (positive) value of the given number.
+* `coalesce(vals...)` returns the first non-null value given.
+* `concat(lists...)` concatenates together all of the given lists to produce a new list.
+* `hasindex(val, idx)` returns true if the expression `val[idx]` could succeed.
+* `int(number)` returns the integer portion of the given number, rounding towards zero.
+* `jsondecode(str)` interprets the given string as JSON and returns the resulting data structure.
+* `jsonencode(val)` returns a JSON-serialized version of the given value.
+* `length(collection)` returns the number of elements in the given collection (list, set, map, object, or tuple).
+* `lower(string)` returns the given string with all uppercase letters converted to lowercase.
+* `max(numbers...)` returns the greatest of the given numbers.
+* `min(numbers...)` returns the smallest of the given numbers.
+* `reverse(string)` returns the given string with all of the characters in reverse order.
+* `strlen(string)` returns the number of characters in the given string.
+* `substr(string, offset, length)` returns the requested substring of the given string.
+* `upper(string)` returns the given string with all lowercase letters converted to uppercase.
+
## Type Expressions
Type expressions are used to describe the expected type of an attribute, as
diff --git a/cmd/hcldec/spec.go b/cmd/hcldec/spec.go
index fa09663..8010919 100644
--- a/cmd/hcldec/spec.go
+++ b/cmd/hcldec/spec.go
@@ -9,6 +9,10 @@ import (
"github.com/zclconf/go-cty/cty"
)
+var specCtx = &hcl.EvalContext{
+ Functions: specFuncs,
+}
+
func loadSpecFile(filename string) (hcldec.Spec, hcl.Diagnostics) {
file, diags := parser.ParseHCLFile(filename)
if diags.HasErrors() {
@@ -382,7 +386,7 @@ func decodeLiteralSpec(body hcl.Body) (hcldec.Spec, hcl.Diagnostics) {
}
var args content
- diags := gohcl.DecodeBody(body, nil, &args)
+ diags := gohcl.DecodeBody(body, specCtx, &args)
if diags.HasErrors() {
return errSpec, diags
}
@@ -455,8 +459,9 @@ func decodeTransformSpec(body hcl.Body) (hcldec.Spec, hcl.Diagnostics) {
}
spec := &hcldec.TransformExprSpec{
- Expr: args.Result,
- VarName: "nested",
+ Expr: args.Result,
+ VarName: "nested",
+ TransformCtx: specCtx,
}
nestedContent, nestedDiags := args.Nested.Content(specSchemaUnlabelled)
diff --git a/cmd/hcldec/spec_funcs.go b/cmd/hcldec/spec_funcs.go
new file mode 100644
index 0000000..99c8ea6
--- /dev/null
+++ b/cmd/hcldec/spec_funcs.go
@@ -0,0 +1,24 @@
+package main
+
+import (
+ "github.com/zclconf/go-cty/cty/function"
+ "github.com/zclconf/go-cty/cty/function/stdlib"
+)
+
+var specFuncs = map[string]function.Function{
+ "abs": stdlib.AbsoluteFunc,
+ "coalesce": stdlib.CoalesceFunc,
+ "concat": stdlib.ConcatFunc,
+ "hasindex": stdlib.HasIndexFunc,
+ "int": stdlib.IntFunc,
+ "jsondecode": stdlib.JSONDecodeFunc,
+ "jsonencode": stdlib.JSONEncodeFunc,
+ "length": stdlib.LengthFunc,
+ "lower": stdlib.LowerFunc,
+ "max": stdlib.MaxFunc,
+ "min": stdlib.MinFunc,
+ "reverse": stdlib.ReverseFunc,
+ "strlen": stdlib.StrlenFunc,
+ "substr": stdlib.SubstrFunc,
+ "upper": stdlib.UpperFunc,
+}