config: concat function supports lists (combines more lists into one)

This commit is contained in:
Radek Simko 2015-05-03 15:53:33 +01:00
parent e9e41dfd05
commit 6a60fa4bfe
3 changed files with 109 additions and 10 deletions

View File

@ -19,6 +19,7 @@ var Funcs map[string]ast.Function
func init() { func init() {
Funcs = map[string]ast.Function{ Funcs = map[string]ast.Function{
"concat": interpolationFuncConcat(),
"element": interpolationFuncElement(), "element": interpolationFuncElement(),
"file": interpolationFuncFile(), "file": interpolationFuncFile(),
"format": interpolationFuncFormat(), "format": interpolationFuncFormat(),
@ -27,10 +28,6 @@ func init() {
"length": interpolationFuncLength(), "length": interpolationFuncLength(),
"replace": interpolationFuncReplace(), "replace": interpolationFuncReplace(),
"split": interpolationFuncSplit(), "split": interpolationFuncSplit(),
// Concat is a little useless now since we supported embeddded
// interpolations but we keep it around for backwards compat reasons.
"concat": interpolationFuncConcat(),
} }
} }
@ -46,11 +43,32 @@ func interpolationFuncConcat() ast.Function {
VariadicType: ast.TypeString, VariadicType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) { Callback: func(args []interface{}) (interface{}, error) {
var b bytes.Buffer var b bytes.Buffer
for _, v := range args { var finalList []string
b.WriteString(v.(string))
var isDeprecated = true
for _, arg := range args {
argument := arg.(string)
if len(argument) == 0 {
continue
} }
if strings.Contains(argument, InterpSplitDelim) {
isDeprecated = false
}
finalList = append(finalList, argument)
// Deprecated concat behaviour
b.WriteString(argument)
}
if isDeprecated {
return b.String(), nil return b.String(), nil
}
return strings.Join(finalList, InterpSplitDelim), nil
}, },
} }
} }

View File

@ -5,13 +5,14 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"reflect" "reflect"
"strings"
"testing" "testing"
"github.com/hashicorp/terraform/config/lang" "github.com/hashicorp/terraform/config/lang"
"github.com/hashicorp/terraform/config/lang/ast" "github.com/hashicorp/terraform/config/lang/ast"
) )
func TestInterpolateFuncConcat(t *testing.T) { func TestInterpolateFuncDeprecatedConcat(t *testing.T) {
testFunction(t, testFunctionConfig{ testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{ Cases: []testFunctionCase{
{ {
@ -35,6 +36,86 @@ func TestInterpolateFuncConcat(t *testing.T) {
}) })
} }
func TestInterpolateFuncConcat(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
// String + list
{
`${concat("a", split(",", "b,c"))}`,
fmt.Sprintf(
"%s%s%s%s%s",
"a",
InterpSplitDelim,
"b",
InterpSplitDelim,
"c"),
false,
},
// List + string
{
`${concat(split(",", "a,b"), "c")}`,
fmt.Sprintf(
"%s%s%s%s%s",
"a",
InterpSplitDelim,
"b",
InterpSplitDelim,
"c"),
false,
},
// Single list
{
`${concat(split(",", ",foo,"))}`,
fmt.Sprintf(
"%s%s%s",
InterpSplitDelim,
"foo",
InterpSplitDelim),
false,
},
{
`${concat(split(",", "a,b,c"))}`,
fmt.Sprintf(
"%s%s%s%s%s",
"a",
InterpSplitDelim,
"b",
InterpSplitDelim,
"c"),
false,
},
// Two lists
{
`${concat(split(",", "a,b,c"), split(",", "d,e"))}`,
strings.Join([]string{
"a", "b", "c", "d", "e",
}, InterpSplitDelim),
false,
},
// Two lists with different separators
{
`${concat(split(",", "a,b,c"), split(" ", "d e"))}`,
strings.Join([]string{
"a", "b", "c", "d", "e",
}, InterpSplitDelim),
false,
},
// More lists
{
`${concat(split(",", "a,b"), split(",", "c,d"), split(",", "e,f"), split(",", "0,1"))}`,
strings.Join([]string{
"a", "b", "c", "d", "e", "f", "0", "1",
}, InterpSplitDelim),
false,
},
},
})
}
func TestInterpolateFuncFile(t *testing.T) { func TestInterpolateFuncFile(t *testing.T) {
tf, err := ioutil.TempFile("", "tf") tf, err := ioutil.TempFile("", "tf")
if err != nil { if err != nil {

View File

@ -72,8 +72,8 @@ are documented below.
The supported built-in functions are: The supported built-in functions are:
* `concat(args...)` - Concatenates the values of multiple arguments into * `concat(list1, list2)` - Combines two or more lists into a single list.
a single string. Example: `combine(aws_instance.db.*.tags.Name, aws_instance.web.*.tags.Name)`
* `element(list, index)` - Returns a single element from a list * `element(list, index)` - Returns a single element from a list
at the given index. If the index is greater than the number of at the given index. If the index is greater than the number of