Skip to content

Commit

Permalink
Merge #3239: "compact" interpolation function
Browse files Browse the repository at this point in the history
  • Loading branch information
apparentlymart committed Oct 10, 2015
2 parents 8c0714f + 16b11e4 commit 3c939f9
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 9 deletions.
17 changes: 17 additions & 0 deletions config/interpolate_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var Funcs map[string]ast.Function

func init() {
Funcs = map[string]ast.Function{
"compact": interpolationFuncCompact(),
"concat": interpolationFuncConcat(),
"element": interpolationFuncElement(),
"file": interpolationFuncFile(),
Expand All @@ -35,6 +36,22 @@ func init() {
}
}

// interpolationFuncCompact strips a list of multi-variable values
// (e.g. as returned by "split") of any empty strings.
func interpolationFuncCompact() ast.Function {
return ast.Function{
ArgTypes: []ast.Type{ast.TypeString},
ReturnType: ast.TypeString,
Variadic: false,
Callback: func(args []interface{}) (interface{}, error) {
if !IsStringList(args[0].(string)) {
return args[0].(string), nil
}
return StringList(args[0].(string)).Compact().String(), nil
},
}
}

// interpolationFuncConcat implements the "concat" function that
// concatenates multiple strings. This isn't actually necessary anymore
// since our language supports string concat natively, but for backwards
Expand Down
27 changes: 27 additions & 0 deletions config/interpolate_funcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@ import (
"github.com/hashicorp/terraform/config/lang/ast"
)

func TestInterpolateFuncCompact(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
// empty string within array
{
`${compact(split(",", "a,,b"))}`,
NewStringList([]string{"a", "b"}).String(),
false,
},

// empty string at the end of array
{
`${compact(split(",", "a,b,"))}`,
NewStringList([]string{"a", "b"}).String(),
false,
},

// single empty string
{
`${compact(split(",", ""))}`,
NewStringList([]string{}).String(),
false,
},
},
})
}

func TestInterpolateFuncDeprecatedConcat(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
Expand Down
21 changes: 17 additions & 4 deletions config/string_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ type StringList string
// ["", ""] => SLDSLDSLD
const stringListDelim = `B780FFEC-B661-4EB8-9236-A01737AD98B6`

// Takes a Stringlist and returns one without empty strings in it
func (sl StringList) Compact() StringList {
parts := sl.Slice()

newlist := []string{}
// drop the empty strings
for i := range parts {
if parts[i] != "" {
newlist = append(newlist, parts[i])
}
}
return NewStringList(newlist)
}

// Build a StringList from a slice
func NewStringList(parts []string) StringList {
// We have to special case the empty list representation
Expand Down Expand Up @@ -55,11 +69,10 @@ func (sl StringList) Length() int {
func (sl StringList) Slice() []string {
parts := strings.Split(string(sl), stringListDelim)

switch len(parts) {
case 0, 1:
// split on an empty StringList will have a length of 2, since there is
// always at least one deliminator
if len(parts) <= 2 {
return []string{}
case 2:
return []string{""}
}

// strip empty elements generated by leading and trailing delimiters
Expand Down
23 changes: 23 additions & 0 deletions config/string_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,26 @@ func TestStringList_element(t *testing.T) {
list, expected, actual)
}
}

func TestStringList_empty_slice(t *testing.T) {
expected := []string{}
l := NewStringList(expected)
actual := l.Slice()

if !reflect.DeepEqual(expected, actual) {
t.Fatalf("Expected %q, got %q", expected, actual)
}
}

func TestStringList_empty_slice_length(t *testing.T) {
list := []string{}
l := NewStringList([]string{})
actual := l.Length()

expected := 0

if actual != expected {
t.Fatalf("Expected length of %q to be %d, got %d",
list, expected, actual)
}
}
5 changes: 0 additions & 5 deletions terraform/interpolate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,6 @@ func TestInterpolator_resourceMultiAttributesWithResourceCount(t *testing.T) {
Value: config.NewStringList([]string{}).String(),
Type: ast.TypeString,
})
// Zero + zero elements
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.nothing", ast.Variable{
Value: config.NewStringList([]string{"", ""}).String(),
Type: ast.TypeString,
})
// Zero + 1 element
testInterpolate(t, i, scope, "aws_route53_zone.terra.*.special", ast.Variable{
Value: config.NewStringList([]string{"extra"}).String(),
Expand Down

0 comments on commit 3c939f9

Please sign in to comment.