Add 'slice' interpolation function. (#9729)

This commit is contained in:
Kit Ewbank 2017-02-13 16:20:02 -05:00 committed by Paul Stack
parent 922eab8cfd
commit 549cff56d0
3 changed files with 101 additions and 1 deletions

View File

@ -85,6 +85,7 @@ func Funcs() map[string]ast.Function {
"sha1": interpolationFuncSha1(), "sha1": interpolationFuncSha1(),
"sha256": interpolationFuncSha256(), "sha256": interpolationFuncSha256(),
"signum": interpolationFuncSignum(), "signum": interpolationFuncSignum(),
"slice": interpolationFuncSlice(),
"sort": interpolationFuncSort(), "sort": interpolationFuncSort(),
"split": interpolationFuncSplit(), "split": interpolationFuncSplit(),
"timestamp": interpolationFuncTimestamp(), "timestamp": interpolationFuncTimestamp(),
@ -793,6 +794,42 @@ func interpolationFuncSignum() ast.Function {
} }
} }
// interpolationFuncSlice returns a portion of the input list between from, inclusive and to, exclusive.
func interpolationFuncSlice() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{
ast.TypeList, // inputList
ast.TypeInt, // from
ast.TypeInt, // to
},
ReturnType: ast.TypeList,
Variadic: false,
Callback: func(args []interface{}) (interface{}, error) {
inputList := args[0].([]ast.Variable)
from := args[1].(int)
to := args[2].(int)
if from < 0 {
return nil, fmt.Errorf("from index must be >= 0")
}
if to > len(inputList) {
return nil, fmt.Errorf("to index must be <= length of the input list")
}
if from > to {
return nil, fmt.Errorf("from index must be <= to index")
}
var outputList []ast.Variable
for i, val := range inputList {
if i >= from && i < to {
outputList = append(outputList, val)
}
}
return outputList, nil
},
}
}
// interpolationFuncSort sorts a list of a strings lexographically // interpolationFuncSort sorts a list of a strings lexographically
func interpolationFuncSort() ast.Function { func interpolationFuncSort() ast.Function {
return ast.Function{ return ast.Function{

View File

@ -1330,6 +1330,66 @@ func TestInterpolateFuncSignum(t *testing.T) {
}) })
} }
func TestInterpolateFuncSlice(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
// Negative from index
{
`${slice(list("a"), -1, 0)}`,
nil,
true,
},
// From index > to index
{
`${slice(list("a", "b", "c"), 2, 1)}`,
nil,
true,
},
// To index too large
{
`${slice(var.list_of_strings, 1, 4)}`,
nil,
true,
},
// Empty slice
{
`${slice(var.list_of_strings, 1, 1)}`,
[]interface{}{},
false,
},
{
`${slice(var.list_of_strings, 1, 2)}`,
[]interface{}{"b"},
false,
},
{
`${slice(var.list_of_strings, 0, length(var.list_of_strings) - 1)}`,
[]interface{}{"a", "b"},
false,
},
},
Vars: map[string]ast.Variable{
"var.list_of_strings": {
Type: ast.TypeList,
Value: []ast.Variable{
{
Type: ast.TypeString,
Value: "a",
},
{
Type: ast.TypeString,
Value: "b",
},
{
Type: ast.TypeString,
Value: "c",
},
},
},
},
})
}
func TestInterpolateFuncSort(t *testing.T) { func TestInterpolateFuncSort(t *testing.T) {
testFunction(t, testFunctionConfig{ testFunction(t, testFunctionConfig{
Vars: map[string]ast.Variable{ Vars: map[string]ast.Variable{

View File

@ -296,7 +296,10 @@ The supported built-in functions are:
Example: `element(split(",", var.r53_failover_policy), signum(count.index))` Example: `element(split(",", var.r53_failover_policy), signum(count.index))`
where the 0th index points to `PRIMARY` and 1st to `FAILOVER` where the 0th index points to `PRIMARY` and 1st to `FAILOVER`
* `sort(list)` - Returns a lexicographically sorted list of the strings contained in * `slice(list, from, to)` - Returns the portion of `list` between `from` (inclusive) and `to` (exclusive).
Example: `slice(var.list_of_strings, 0, length(var.list_of_strings) - 1)`
* `sort(list)` - Returns a lexographically sorted list of the strings contained in
the list passed as an argument. Sort may only be used with lists which contain only the list passed as an argument. Sort may only be used with lists which contain only
strings. strings.
Examples: `sort(aws_instance.foo.*.id)`, `sort(var.list_of_strings)` Examples: `sort(aws_instance.foo.*.id)`, `sort(var.list_of_strings)`