Skip to content

Commit

Permalink
hcl2template: add anytrue function
Browse files Browse the repository at this point in the history
this function add the hcl2 anytrue function which takes a collection and
return true if any of the element is true.
  • Loading branch information
mogrogan committed Dec 20, 2024
1 parent c26999b commit 0e25a9d
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 0 deletions.
44 changes: 44 additions & 0 deletions hcl2template/function/anytrue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package function

import (
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
)

// AnyTrue constructs a function that returns true if a single element of
// the list is true. If the list is empty, return false.
var AnyTrue = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "list",
Type: cty.List(cty.Bool),
},
},
Type: function.StaticReturnType(cty.Bool),
RefineResult: refineNotNull,
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
result := cty.False
var hasUnknown bool
for it := args[0].ElementIterator(); it.Next(); {
_, v := it.Element()
if !v.IsKnown() {
hasUnknown = true
continue
}
if v.IsNull() {
continue
}
result = result.Or(v)
if result.True() {
return cty.True, nil
}
}
if hasUnknown {
return cty.UnknownVal(cty.Bool), nil
}
return result, nil
},
})
89 changes: 89 additions & 0 deletions hcl2template/function/anytrue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package function

import (
"fmt"
"testing"

"github.com/zclconf/go-cty/cty"
)

func TestAnyTrue(t *testing.T) {
tests := []struct {
Collection cty.Value
Want cty.Value
Err bool
}{
{
cty.ListValEmpty(cty.Bool),
cty.False,
false,
},
{
cty.ListVal([]cty.Value{cty.True}),
cty.True,
false,
},
{
cty.ListVal([]cty.Value{cty.False}),
cty.False,
false,
},
{
cty.ListVal([]cty.Value{cty.True, cty.False}),
cty.True,
false,
},
{
cty.ListVal([]cty.Value{cty.False, cty.True}),
cty.True,
false,
},
{
cty.ListVal([]cty.Value{cty.True, cty.NullVal(cty.Bool)}),
cty.True,
false,
},
{
cty.ListVal([]cty.Value{cty.UnknownVal(cty.Bool)}),
cty.UnknownVal(cty.Bool).RefineNotNull(),
false,
},
{
cty.ListVal([]cty.Value{
cty.UnknownVal(cty.Bool),
cty.UnknownVal(cty.Bool),
}),
cty.UnknownVal(cty.Bool).RefineNotNull(),
false,
},
{
cty.UnknownVal(cty.List(cty.Bool)),
cty.UnknownVal(cty.Bool).RefineNotNull(),
false,
},
{
cty.NullVal(cty.List(cty.Bool)),
cty.NilVal,
true,
},
}

for _, tc := range tests {
t.Run(fmt.Sprintf("anytrue(%#v)", tc.Collection), func(t *testing.T) {
got, err := AnyTrue.Call([]cty.Value{tc.Collection})

if tc.Err && err == nil {
t.Fatal("succeeded; want error")
}
if !tc.Err && err != nil {
t.Fatalf("unexpected error: %s", err)
}
if !got.RawEquals(tc.Want) {
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, tc.Want)
}
})
}
}
1 change: 1 addition & 0 deletions hcl2template/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func Functions(basedir string) map[string]function.Function {
"abs": stdlib.AbsoluteFunc,
"abspath": filesystem.AbsPathFunc,
"alltrue": pkrfunction.AllTrue,
"anytrue": pkrfunction.AnyTrue,
"aws_secretsmanager": pkrfunction.AWSSecret,
"basename": filesystem.BasenameFunc,
"base64decode": encoding.Base64DecodeFunc,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
page_title: anytrue - Functions - Configuration Language
description: |-
The anytrue function determines whether any element of a collection
is true or "true". If the collection is empty, it returns false.
---

# `anytrue` Function

`anytrue` returns `true` if any element in a given collection is `true`
or `"true"`. It also returns `false` if the collection is empty.

```hcl
anytrue(list)
```

## Examples

```command
> anytrue(["true"])
true
> anytrue([true])
true
> anytrue([true, false])
true
> anytrue([])
false
```
4 changes: 4 additions & 0 deletions website/data/docs-nav-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@
"title": "alltrue",
"path": "templates/hcl_templates/functions/collection/alltrue"
},
{
"title": "anytrue",
"path": "templates/hcl_templates/functions/collection/anytrue"
},
{
"title": "chunklist",
"path": "templates/hcl_templates/functions/collection/chunklist"
Expand Down

0 comments on commit 0e25a9d

Please sign in to comment.