Merge pull request #7128 from hashicorp/f-interpolation-func-sort

core: Add sort() interpolation function
This commit is contained in:
James Nugent 2016-06-11 18:13:07 +01:00 committed by GitHub
commit 82c729b9ac
3 changed files with 68 additions and 0 deletions

View File

@ -75,6 +75,7 @@ func Funcs() map[string]ast.Function {
"sha1": interpolationFuncSha1(), "sha1": interpolationFuncSha1(),
"sha256": interpolationFuncSha256(), "sha256": interpolationFuncSha256(),
"signum": interpolationFuncSignum(), "signum": interpolationFuncSignum(),
"sort": interpolationFuncSort(),
"split": interpolationFuncSplit(), "split": interpolationFuncSplit(),
"trimspace": interpolationFuncTrimSpace(), "trimspace": interpolationFuncTrimSpace(),
"upper": interpolationFuncUpper(), "upper": interpolationFuncUpper(),
@ -529,6 +530,34 @@ func interpolationFuncSignum() ast.Function {
} }
} }
// interpolationFuncSort sorts a list of a strings lexographically
func interpolationFuncSort() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeList},
ReturnType: ast.TypeList,
Variadic: false,
Callback: func(args []interface{}) (interface{}, error) {
inputList := args[0].([]ast.Variable)
// Ensure that all the list members are strings and
// create a string slice from them
members := make([]string, len(inputList))
for i, val := range inputList {
if val.Type != ast.TypeString {
return nil, fmt.Errorf(
"sort() may only be used with lists of strings - %s at index %d",
val.Type.String(), i)
}
members[i] = val.Value.(string)
}
sort.Strings(members)
return stringSliceToVariableValue(members), nil
},
}
}
// interpolationFuncSplit implements the "split" function that allows // interpolationFuncSplit implements the "split" function that allows
// strings to split into multi-variable values // strings to split into multi-variable values
func interpolationFuncSplit() ast.Function { func interpolationFuncSplit() ast.Function {

View File

@ -638,6 +638,40 @@ func TestInterpolateFuncSignum(t *testing.T) {
}) })
} }
func TestInterpolateFuncSort(t *testing.T) {
testFunction(t, testFunctionConfig{
Vars: map[string]ast.Variable{
"var.strings": ast.Variable{
Type: ast.TypeList,
Value: []ast.Variable{
{Type: ast.TypeString, Value: "c"},
{Type: ast.TypeString, Value: "a"},
{Type: ast.TypeString, Value: "b"},
},
},
"var.notstrings": ast.Variable{
Type: ast.TypeList,
Value: []ast.Variable{
{Type: ast.TypeList, Value: []ast.Variable{}},
{Type: ast.TypeString, Value: "b"},
},
},
},
Cases: []testFunctionCase{
{
`${sort(var.strings)}`,
[]interface{}{"a", "b", "c"},
false,
},
{
`${sort(var.notstrings)}`,
nil,
true,
},
},
})
}
func TestInterpolateFuncSplit(t *testing.T) { func TestInterpolateFuncSplit(t *testing.T) {
testFunction(t, testFunctionConfig{ testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{ Cases: []testFunctionCase{

View File

@ -195,6 +195,11 @@ 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 lexographically sorted list of the strings contained in
the list passed as an argument. Sort may only be used with lists which contain only
strings.
Examples: `sort(aws_instance.foo.*.id)`, `sort(var.list_of_strings)`
* `split(delim, string)` - Splits the string previously created by `join` * `split(delim, string)` - Splits the string previously created by `join`
back into a list. This is useful for pushing lists through module back into a list. This is useful for pushing lists through module
outputs since they currently only support string values. Depending on the outputs since they currently only support string values. Depending on the