Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lang/funcs: Add "anytrue" function #26498

Merged
merged 3 commits into from
Oct 23, 2020

Conversation

artburkart
Copy link
Contributor

This commit adds an anytrue function to Terraform configuration. It's
mostly a complement to the recently introduced alltrue function.

This commit adds an `anytrue` function to Terraform configuration. It's
mostly a complement to the recently introduced `alltrue` function.
@codecov
Copy link

codecov bot commented Oct 7, 2020

Codecov Report

Merging #26498 into master will increase coverage by 0.00%.
The diff coverage is 76.47%.

Impacted Files Coverage Δ
lang/funcs/collection.go 77.77% <75.00%> (-0.59%) ⬇️
lang/functions.go 93.44% <100.00%> (+0.05%) ⬆️
terraform/evaluate.go 50.56% <0.00%> (+0.22%) ⬆️

@apparentlymart
Copy link
Contributor

Thanks for opening this PR, @artburkart!

What you've written here looks like a good thing we could move forward with. I think there are some opportunities to simplify it further, if you'd be interested:

  • Since it's ultimately converting all of the list/tuple/set elements to bool anyway, I think we could eliminate some manual type checking/conversion code by declaring the parameter as being of type cty.List(cty.Bool). Then everything will already be a bool by the time we get into the Impl function and we won't need to type-check the argument anymore.

    (While thinking about that it also occurred to me that it would be possible in principle to type it as cty.Set(cty.Bool) and then check if the resulting set has cty.True in it at all, but the need to still handle unknown values makes that not as simple as it first appears, and I think the interpretation as a list makes the intent a little clearer.)

  • The cty.Value type has an Or method that handles unknown values automatically because it is an operation method rather than an integration method, so I think the main loop could be simpler if written to use that instead of the direct equality check:

    result := cty.False
    for it := args[0].ElementIterator(); it.Next(); {
        _, v := it.Element()
        if v.IsNull() {
            // (return error)
        }
        result = result.Or(v)
    }
    return result, nil

    The Or method handles unknown values automatically, so result would end up being cty.UnknownVal(cty.Bool) if it encounters any unknown values along the way. This Or method is also the implementation of the main language's || operator, so this really would make it a "OR of a dynamic number of values" operation as I'd been conceptualizing it in lang/funcs: Add "alltrue" function #25656, ensuring that it'd behaves in the same way as the operator.

  • The functions infrastructure already guarantees that args[0] won't itself be null or unknown (the parameter isn't marked as AllowNull: true or AllowUnknown: true), so we don't need to explicitly re-check those. The automatic handling done by the functions infrastructure is only shallow though, so we do still need to handle the list elements being null or unknown via something like I showed in the previous point.

What do you think? 🤔

@artburkart
Copy link
Contributor Author

That sounds valid to me. Thanks for the explanatory links and code snippet. I'll give it a shot. 👍

Rather than manually type check, lean on cty to do it for us. Also, use
"Or" and "And" operation methods rather than integration methods, since
we're not working on the boundary between cty and the native Go type
system.
@artburkart
Copy link
Contributor Author

Is this more along the lines of what you were looking for?

@apparentlymart
Copy link
Contributor

This looks good to me, @artburkart! Thanks for working with me on this.

My one remaining note is that I think the explicit check for length == 0 doesn't seem to be needed anymore, because the situations where the loop iterates zero times would produce the same results, I think? Not a big deal, but where possible I try to avoid using cty's "integration methods" because the operation methods (the ones that return another cty.Value) automatically take care of various cty-specific concerns like things being unknown. (I don't think such concerns apply here, but we have some past experience with future enhancements inadvertently introducing such concerns but us not realizing that we needed to handle them.)

If you're ready to mark this as "Ready for review" then I'd love to merge it, either way.

@artburkart artburkart marked this pull request as ready for review October 23, 2020 19:27
@artburkart
Copy link
Contributor Author

@apparentlymart — I've removed the LengthInt check. Thanks for the feedback. 👍

Copy link
Contributor

@apparentlymart apparentlymart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @artburkart! This looks great and I'm going to merge it now.

I'm also going to backport it into the v0.14 branch so it can be included in the forthcoming v0.14.0 release (because the main branch is now v0.15), because I think it makes sense to release both alltrue and anytrue together.

@apparentlymart apparentlymart merged commit d4716a6 into hashicorp:master Oct 23, 2020
@artburkart artburkart deleted the anytrue-function branch October 23, 2020 21:41
@artburkart
Copy link
Contributor Author

That sounds great 👍

@pkolyvas pkolyvas added the custom-conditions Feedback on variable validation, preconditions. postconditions, checks, and test assertions label Oct 27, 2020
@ghost
Copy link

ghost commented Nov 23, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
custom-conditions Feedback on variable validation, preconditions. postconditions, checks, and test assertions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants