From 213331a408bb29e284bbd5a385e5fc7bdeb6e430 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Sun, 3 May 2015 15:53:33 +0100 Subject: [PATCH] config: concat function supports lists (combines more lists into one) --- config/interpolate_funcs.go | 32 +++++-- config/interpolate_funcs_test.go | 83 ++++++++++++++++++- .../docs/configuration/interpolation.html.md | 4 +- 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/config/interpolate_funcs.go b/config/interpolate_funcs.go index bce5f8031b08..96df8b032692 100644 --- a/config/interpolate_funcs.go +++ b/config/interpolate_funcs.go @@ -18,6 +18,7 @@ var Funcs map[string]ast.Function func init() { Funcs = map[string]ast.Function{ + "concat": interpolationFuncConcat(), "element": interpolationFuncElement(), "file": interpolationFuncFile(), "format": interpolationFuncFormat(), @@ -26,10 +27,6 @@ func init() { "length": interpolationFuncLength(), "replace": interpolationFuncReplace(), "split": interpolationFuncSplit(), - - // Concat is a little useless now since we supported embeddded - // interpolations but we keep it around for backwards compat reasons. - "concat": interpolationFuncConcat(), } } @@ -45,11 +42,32 @@ func interpolationFuncConcat() ast.Function { VariadicType: ast.TypeString, Callback: func(args []interface{}) (interface{}, error) { var b bytes.Buffer - for _, v := range args { - b.WriteString(v.(string)) + var finalList []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 }, } } diff --git a/config/interpolate_funcs_test.go b/config/interpolate_funcs_test.go index c11983078c80..bcb83292efc1 100644 --- a/config/interpolate_funcs_test.go +++ b/config/interpolate_funcs_test.go @@ -5,13 +5,14 @@ import ( "io/ioutil" "os" "reflect" + "strings" "testing" "github.com/hashicorp/terraform/config/lang" "github.com/hashicorp/terraform/config/lang/ast" ) -func TestInterpolateFuncConcat(t *testing.T) { +func TestInterpolateFuncDeprecatedConcat(t *testing.T) { testFunction(t, testFunctionConfig{ 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) { tf, err := ioutil.TempFile("", "tf") if err != nil { diff --git a/website/source/docs/configuration/interpolation.html.md b/website/source/docs/configuration/interpolation.html.md index 5c3ce791d5f6..c4db6d969be5 100644 --- a/website/source/docs/configuration/interpolation.html.md +++ b/website/source/docs/configuration/interpolation.html.md @@ -72,8 +72,8 @@ are documented below. The supported built-in functions are: - * `concat(args...)` - Concatenates the values of multiple arguments into - a single string. + * `concat(list1, list2)` - Combines two or more lists into a single list. + Example: `combine(aws_instance.db.*.tags.Name, aws_instance.web.*.tags.Name)` * `element(list, index)` - Returns a single element from a list at the given index. If the index is greater than the number of