Allow specifying a default value to lookup()

Fixes #4474, where lookup() calls fail out the entire interpolation when
the provided key value is not found in the map. This will allow using
coalesce() along with lookup() to greatly improve module flexibility.
This commit is contained in:
David Adams 2016-05-25 19:25:15 -05:00
parent a8de40090a
commit b5d1279107
2 changed files with 42 additions and 6 deletions

View File

@ -550,16 +550,31 @@ func interpolationFuncLookup(vs map[string]ast.Variable) ast.Function {
return ast.Function{ return ast.Function{
ArgTypes: []ast.Type{ast.TypeMap, ast.TypeString}, ArgTypes: []ast.Type{ast.TypeMap, ast.TypeString},
ReturnType: ast.TypeString, ReturnType: ast.TypeString,
Variadic: true,
VariadicType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) { Callback: func(args []interface{}) (interface{}, error) {
defaultValue := ""
defaultValueSet := false
if len(args) > 2 {
defaultValue = args[2].(string)
defaultValueSet = true
}
if len(args) > 3 {
return "", fmt.Errorf("lookup() takes no more than three arguments")
}
index := args[1].(string) index := args[1].(string)
mapVar := args[0].(map[string]ast.Variable) mapVar := args[0].(map[string]ast.Variable)
v, ok := mapVar[index] v, ok := mapVar[index]
if !ok { if !ok {
if defaultValueSet {
return defaultValue, nil
} else {
return "", fmt.Errorf( return "", fmt.Errorf(
"lookup failed to find '%s'", "lookup failed to find '%s'",
args[1].(string)) args[1].(string))
} }
}
if v.Type != ast.TypeString { if v.Type != ast.TypeString {
return "", fmt.Errorf( return "", fmt.Errorf(
"lookup for '%s' has bad type %s", "lookup for '%s' has bad type %s",

View File

@ -713,12 +713,33 @@ func TestInterpolateFuncLookup(t *testing.T) {
true, true,
}, },
// Supplied default with valid key
{
`${lookup(var.foo, "bar", "")}`,
"baz",
false,
},
// Supplied default with invalid key
{
`${lookup(var.foo, "zip", "")}`,
"",
false,
},
// Too many args // Too many args
{ {
`${lookup(var.foo, "bar", "baz")}`, `${lookup(var.foo, "bar", "", "abc")}`,
nil, nil,
true, true,
}, },
// Non-empty default
{
`${lookup(var.foo, "zap", "xyz")}`,
"xyz",
false,
},
}, },
}) })
} }