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

support partial expression evaluation #184

Closed
martinohmann opened this issue Mar 24, 2023 · 3 comments · Fixed by #292
Closed

support partial expression evaluation #184

martinohmann opened this issue Mar 24, 2023 · 3 comments · Fixed by #292
Labels
enhancement New feature or request

Comments

@martinohmann
Copy link
Owner

martinohmann commented Mar 24, 2023

In #159 the idea came up to also support evaluating expressions partially, returning information about missing variables instead of failing.

@martinohmann martinohmann added the enhancement New feature or request label Mar 24, 2023
@denfren
Copy link
Contributor

denfren commented May 4, 2023

I just thought of an idea and have thrown together some code to illustrate it: main...denfren:hcl-rs:eval-via-extended-context

Example

foo "bar" {
  value = 42
}
attribute = foo.bar.value

When a traversal is evaluated (attribute) we introduce a new state to the context where the foo.bar block's attributes are available as as variables and at the same time we translate the traversal from foo.bar.value to just value.

@martinohmann
Copy link
Owner Author

In general I like the idea of making resolved attributes and blocks available in the context so that references to these can be resolved automatically.

However, there are some issues that need to be addressed:

  • What should be the behaviour when attribute is defined before foo in your example? E.g. if we look at terraform, it will resolve these references regardless of the order. So we probably need to roundtrip the expression evaluation again and again until not unresolved referenced are left or we hit an error that makes continuing impossible.
  • In terraform land, references to blocks are different from the block declaration. E.g. variable blocks are referenced via var, locals via local and resource blocks are referenced by the first label instead of resource. This inconsistency makes me think if we should even make this behaviour automatic. Maybe it could be opt-in, e.g. via a configuration switch in the Context type or something.

I'm currently playing around with partial evaluation support in the in-place-eval branch. It essentially tries to recursively evaluate as many expressions as possible and will collect errors it encounters along the way. Objects are evaluated in place. Maybe I can enhance this further to also automatically add variables to the context while they are discovered.

@martinohmann
Copy link
Owner Author

Another option could be to give users a way to provide a callback to the expression evaluation process so that they can decide how to handle this (e.g. add fully evaluated attributes/blocks to the context or not, and if, how the newly exposed variable should be named).

martinohmann added a commit that referenced this issue Sep 17, 2023
Closes #184.

Key difference to the existing `Evaluate::evaluate` method:

- It mutably borrows the value and tries to evaluate all nested expressions in-place.
- It returns all errors that it encounters, not just the first one.

This allows for partial expression evaluation, e.g. to support use cases where a HCL document contains variable references to other parts within the same document that themselves contain expressions that are not evaluated yet.

In this case one would:

1. Partially evaluate the document via `evaluate_in_place`.
2. Update the `Context` with newly discovered variables.
3. Repeat 1. and 2. until there are no more errors left.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants