diff --git a/README.md b/README.md index 783922eb..b9c3b4b5 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ For example, this is a JSON version of an emitted RuntimeContainer struct: * *`closest $array $value`*: Returns the longest matching substring in `$array` that matches `$value` * *`coalesce ...`*: Returns the first non-nil argument. -* *`contains $map $key`*: Returns `true` if `$map` contains `$key`. Takes maps from `string` to `string`. +* *`contains $map $key`*: Returns `true` if `$map` contains `$key`. Takes maps from `string` to any type. * *`dict $key $value ...`*: Creates a map from a list of pairs. Each `$key` value must be a `string`, but the `$value` can be any type (or `nil`). Useful for passing more than one value as a pipeline context to subtemplates. * *`dir $path`*: Returns an array of filenames in the specified `$path`. * *`exists $path`*: Returns `true` if `$path` refers to an existing file or directory. Takes a string. diff --git a/template.go b/template.go index 793396d5..6c4e2c68 100644 --- a/template.go +++ b/template.go @@ -291,10 +291,20 @@ func intersect(l1, l2 []string) []string { return keys } -func contains(item map[string]string, key string) bool { - if _, ok := item[key]; ok { - return true +func contains(input interface{}, key interface{}) bool { + if input == nil { + return false + } + + val := reflect.ValueOf(input) + if val.Kind() == reflect.Map { + for _, k := range val.MapKeys() { + if k.Interface() == key { + return true + } + } } + return false } diff --git a/template_test.go b/template_test.go index 71501ada..1b991370 100644 --- a/template_test.go +++ b/template_test.go @@ -33,7 +33,7 @@ func (tests templateTestList) run(t *testing.T, prefix string) { } } -func TestContains(t *testing.T) { +func TestContainsString(t *testing.T) { env := map[string]string{ "PORT": "1234", } @@ -47,6 +47,24 @@ func TestContains(t *testing.T) { } } +func TestContainsInteger(t *testing.T) { + env := map[int]int{ + 42: 1234, + } + + if !contains(env, 42) { + t.Fail() + } + + if contains(env, "WRONG TYPE") { + t.Fail() + } + + if contains(env, 24) { + t.Fail() + } +} + func TestKeys(t *testing.T) { env := map[string]string{ "VIRTUAL_HOST": "demo.local",