This commit is contained in:
Jan Schumann 2016-06-10 17:11:51 +02:00 committed by James Nugent
parent b7d0bd5db7
commit df3e017f6c
2 changed files with 62 additions and 0 deletions

View File

@ -71,6 +71,7 @@ func Funcs() map[string]ast.Function {
"lower": interpolationFuncLower(),
"md5": interpolationFuncMd5(),
"uuid": interpolationFuncUUID(),
"uniq": interpolationFuncUniq(),
"replace": interpolationFuncReplace(),
"sha1": interpolationFuncSha1(),
"sha256": interpolationFuncSha256(),
@ -382,6 +383,42 @@ func interpolationFuncIndex() ast.Function {
}
}
// interpolationFuncUniq implements the "uniq" function that
// removes duplicate elements from a list.
func interpolationFuncUniq() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeList},
ReturnType: ast.TypeList,
Variadic: true,
VariadicType: ast.TypeList,
Callback: func(args []interface{}) (interface{}, error) {
var list []string
if len(args) != 1 {
return nil, fmt.Errorf("uniq() excepts only one argument.")
}
if argument, ok := args[0].([]ast.Variable); ok {
for _, element := range argument {
list = appendIfMissing(list, element.Value.(string))
}
}
return stringSliceToVariableValue(list), nil
},
}
}
// helper function to add an element to a list, if it does not already exsit
func appendIfMissing(slice []string, element string) []string {
for _, ele := range slice {
if ele == element {
return slice
}
}
return append(slice, element)
}
// interpolationFuncJoin implements the "join" function that allows
// multi-variable values to be joined by some character.
func interpolationFuncJoin() ast.Function {

View File

@ -261,6 +261,31 @@ func TestInterpolationFuncConcatListOfMaps(t *testing.T) {
}
}
func TestInterpolateFuncUniq(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
// 3 duplicates
{
`${uniq(concat(split(",", "user1,user2,user3"), split(",", "user1,user2,user3")))}`,
[]interface{}{"user1", "user2", "user3"},
false,
},
// 1 duplicate
{
`${uniq(concat(split(",", "user1,user2,user3"), split(",", "user1,user4")))}`,
[]interface{}{"user1", "user2", "user3", "user4"},
false,
},
// too many args
{
`${uniq(concat(split(",", "user1,user2,user3"), split(",", "user1,user4")), "foo")}`,
nil,
true,
},
},
})
}
func TestInterpolateFuncFile(t *testing.T) {
tf, err := ioutil.TempFile("", "tf")
if err != nil {