config: multi-line "indent" function

This function prepends a number of spaces on to all but the first line
of a string containing multiple lines of text.
This commit is contained in:
Micah Hausler 2017-06-15 16:47:54 -04:00 committed by Martin Atkins
parent 4789045911
commit 7fa4b648bb
3 changed files with 50 additions and 0 deletions

View File

@ -84,6 +84,7 @@ func Funcs() map[string]ast.Function {
"floor": interpolationFuncFloor(), "floor": interpolationFuncFloor(),
"format": interpolationFuncFormat(), "format": interpolationFuncFormat(),
"formatlist": interpolationFuncFormatList(), "formatlist": interpolationFuncFormatList(),
"indent": interpolationFuncIndent(),
"index": interpolationFuncIndex(), "index": interpolationFuncIndex(),
"join": interpolationFuncJoin(), "join": interpolationFuncJoin(),
"jsonencode": interpolationFuncJSONEncode(), "jsonencode": interpolationFuncJSONEncode(),
@ -675,6 +676,21 @@ func interpolationFuncFormatList() ast.Function {
} }
} }
// interpolationFuncIndent indents a multi-line string with the
// specified number of spaces
func interpolationFuncIndent() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeInt, ast.TypeString},
ReturnType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) {
spaces := args[0].(int)
data := args[1].(string)
pad := strings.Repeat(" ", spaces)
return strings.Replace(data, "\n", "\n"+pad, -1), nil
},
}
}
// interpolationFuncIndex implements the "index" function that allows one to // interpolationFuncIndex implements the "index" function that allows one to
// find the index of a specific element in a list // find the index of a specific element in a list
func interpolationFuncIndex() ast.Function { func interpolationFuncIndex() ast.Function {

View File

@ -1354,6 +1354,34 @@ func TestInterpolateFuncIndex(t *testing.T) {
}) })
} }
func TestInterpolateFuncIndent(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${indent(4, "Fleas:
Adam
Had'em
E.E. Cummings")}`,
"Fleas:\n Adam\n Had'em\n \n E.E. Cummings",
false,
},
{
`${indent(4, "oneliner")}`,
"oneliner",
false,
},
{
`${indent(4, "#!/usr/bin/env bash
date
pwd")}`,
"#!/usr/bin/env bash\n date\n pwd",
false,
},
},
})
}
func TestInterpolateFuncJoin(t *testing.T) { func TestInterpolateFuncJoin(t *testing.T) {
testFunction(t, testFunctionConfig{ testFunction(t, testFunctionConfig{
Vars: map[string]ast.Variable{ Vars: map[string]ast.Variable{

View File

@ -257,6 +257,12 @@ The supported built-in functions are:
`formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`. `formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`.
Passing lists with different lengths to formatlist results in an error. Passing lists with different lengths to formatlist results in an error.
* `indent(numspaces, string)` - Prepends the specified number of spaces to all but the first
line of the given multi-line string. May be useful when inserting a multi-line string
into an already-indented context. The first line is not indented, to allow for the
indented string to be placed after some sort of already-indented preamble.
Example: `" \"items\": ${ indent(4, "[\n \"item1\"\n]") },"`
* `index(list, elem)` - Finds the index of a given element in a list. * `index(list, elem)` - Finds the index of a given element in a list.
This function only works on flat lists. This function only works on flat lists.
Example: `index(aws_instance.foo.*.tags.Name, "foo-test")` Example: `index(aws_instance.foo.*.tags.Name, "foo-test")`