core: New interpolation function "chunklist"
This turns a list into a list of lists with each element (apart from possibly the last) being the given length.
This commit is contained in:
parent
935890ec64
commit
ed9ba576e3
|
@ -79,6 +79,7 @@ func Funcs() map[string]ast.Function {
|
|||
"dirname": interpolationFuncDirname(),
|
||||
"distinct": interpolationFuncDistinct(),
|
||||
"element": interpolationFuncElement(),
|
||||
"chunklist": interpolationFuncChunklist(),
|
||||
"file": interpolationFuncFile(),
|
||||
"matchkeys": interpolationFuncMatchKeys(),
|
||||
"flatten": interpolationFuncFlatten(),
|
||||
|
@ -1129,6 +1130,56 @@ func interpolationFuncElement() ast.Function {
|
|||
}
|
||||
}
|
||||
|
||||
// returns the `list` items chunked by `size`.
|
||||
func interpolationFuncChunklist() ast.Function {
|
||||
return ast.Function{
|
||||
ArgTypes: []ast.Type{
|
||||
ast.TypeList, // inputList
|
||||
ast.TypeInt, // size
|
||||
},
|
||||
ReturnType: ast.TypeList,
|
||||
Callback: func(args []interface{}) (interface{}, error) {
|
||||
output := make([]ast.Variable, 0)
|
||||
|
||||
values, _ := args[0].([]ast.Variable)
|
||||
size, _ := args[1].(int)
|
||||
|
||||
// errors if size is negative
|
||||
if size < 0 {
|
||||
return nil, fmt.Errorf("The size argument must be positive")
|
||||
}
|
||||
|
||||
// if size is 0, returns a list made of the initial list
|
||||
if size == 0 {
|
||||
output = append(output, ast.Variable{
|
||||
Type: ast.TypeList,
|
||||
Value: values,
|
||||
})
|
||||
return output, nil
|
||||
}
|
||||
|
||||
variables := make([]ast.Variable, 0)
|
||||
chunk := ast.Variable{
|
||||
Type: ast.TypeList,
|
||||
Value: variables,
|
||||
}
|
||||
l := len(values)
|
||||
for i, v := range values {
|
||||
variables = append(variables, v)
|
||||
|
||||
// Chunk when index isn't 0, or when reaching the values's length
|
||||
if (i+1)%size == 0 || (i+1) == l {
|
||||
chunk.Value = variables
|
||||
output = append(output, chunk)
|
||||
variables = make([]ast.Variable, 0)
|
||||
}
|
||||
}
|
||||
|
||||
return output, nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// interpolationFuncKeys implements the "keys" function that yields a list of
|
||||
// keys of map types within a Terraform configuration.
|
||||
func interpolationFuncKeys(vs map[string]ast.Variable) ast.Function {
|
||||
|
|
|
@ -2106,6 +2106,44 @@ func TestInterpolateFuncElement(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestInterpolateFuncChunklist(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
// normal usage
|
||||
{
|
||||
`${chunklist(list("a", "b", "c"), 1)}`,
|
||||
[]interface{}{
|
||||
[]interface{}{"a"},
|
||||
[]interface{}{"b"},
|
||||
[]interface{}{"c"},
|
||||
},
|
||||
false,
|
||||
},
|
||||
// `size` is pair and the list has an impair number of items
|
||||
{
|
||||
`${chunklist(list("a", "b", "c"), 2)}`,
|
||||
[]interface{}{
|
||||
[]interface{}{"a", "b"},
|
||||
[]interface{}{"c"},
|
||||
},
|
||||
false,
|
||||
},
|
||||
// list made of the same list, since size is 0
|
||||
{
|
||||
`${chunklist(list("a", "b", "c"), 0)}`,
|
||||
[]interface{}{[]interface{}{"a", "b", "c"}},
|
||||
false,
|
||||
},
|
||||
// negative size of chunks
|
||||
{
|
||||
`${chunklist(list("a", "b", "c"), -1)}`,
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestInterpolateFuncBasename(t *testing.T) {
|
||||
testFunction(t, testFunctionConfig{
|
||||
Cases: []testFunctionCase{
|
||||
|
|
|
@ -230,6 +230,11 @@ The supported built-in functions are:
|
|||
* `element(aws_subnet.foo.*.id, count.index)`
|
||||
* `element(var.list_of_strings, 2)`
|
||||
|
||||
* `chunklist(list, size)` - Returns the `list` items chunked by `size`.
|
||||
Examples:
|
||||
* `list(aws_subnet.foo.*.id, 1)`: will outputs `[["id1"], ["id2"], ["id3"]]`
|
||||
* `list(var.list_of_strings, 2)`: will outputs `[["id1", "id2"], ["id3", "id4"], ["id5"]`
|
||||
|
||||
* `file(path)` - Reads the contents of a file into the string. Variables
|
||||
in this file are _not_ interpolated. The contents of the file are
|
||||
read as-is. The `path` is interpreted relative to the working directory.
|
||||
|
|
Loading…
Reference in New Issue