Merge #3239: "compact" interpolation function
This commit is contained in:
commit
3c939f9b26
|
@ -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(),
|
||||
|
@ -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
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue