summaryrefslogtreecommitdiff
path: root/ext/dynblock
AgeCommit message (Collapse)Author
2024-10-08docs(ext/dynblock): recursive function call typo in detecting variables (#686)Calmon Ribeiro
2024-05-09hcldec: Allow body-derived values to be markedMartin Atkins
Similar to the previously-added UnknownBody, the new optional interface MarkedBody allows hcl.Body implementations to suggest a set of marks that ought to be applied to any value that's generated to represent the content of that body. The dynblock extension then uses this to get hcldec to mark the whole object representing any block that was generated by a dynamic block whose for_each was marked, for a better representation of the fact that a block's existence was decided based on a marked value.
2024-05-09dynblock: Preserve marks from for_each expression into resultMartin Atkins
Previously if the for_each expression was marked then expansion would fail because marked expressions are never directly iterable. Now instead we'll allow marked for_each and preserve the marks into the values produced by the resulting block as much as we can. This runs into the classic problem that HCL blocks are not values themselves and so cannot carry marks directly, but we can at least make sure that the values of any leaf arguments end up marked.
2024-02-16add missing copywrite headersRadek Simko
2024-02-14prefer iterator error over for_eachDaniel Schmidt
If the iterator is misconfigured (e.g. a string instead of a reference) it leads to follow up issues in the validation of for_each which in turn leads to misleading error messages. See hashicorp/terraform#34132 for an example.
2023-10-16ext/dynblock: Allow callers to veto for_each valuesMartin Atkins
Callers might have additional rules for what's acceptable in a for_each value for a dynamic block. For example, Terraform wants to forbid using sensitive values here because it would cause the expansion to disclose the length of the given collection. Therefore this provides a hook point for callers to insert additional checks just after the for_each expression has been evaluated and before any of the built-in checks are run. This introduces the "functional options" pattern for ExpandBlock for the first time, as a way to extend the API without breaking compatibility with existing callers. There is currently only this one option.
2023-02-28[COMPLIANCE] Add Copyright and License Headers (#586)hashicorp-copywrite[bot]
* [COMPLIANCE] Add Copyright and License Headers * add copywrite file and revert headers in testdata --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Liam Cervante <liam.cervante@hashicorp.com>
2021-07-07decode unknown blocks to ensure they are validJames Bardin
Always attempt to decode dynamic blocks to provide validation. If the iterator is unknown the value will be discarded, but the diagnostics are still useful to unsure the structure is correct.
2021-04-15dynblock UnknownBody implementationJames Bardin
Allow dynamic blocks to indicate when the entire block value is unknown
2019-10-01ext/dynblock: Go package documentationMartin Atkins
2019-09-09Unfold the "hcl" directory up into the rootMartin Atkins
The main HCL package is more visible this way, and so it's easier than having to pick it out from dozens of other package directories.
2019-09-09Change module path to github.com/hashicorp/hcl/v2Martin Atkins
This is in preparation for the first v2 release from the main HCL repository.
2019-07-22Fix typos (#85)Masayuki Morita
2019-04-30ext/dynblock: Stub out contents when for_each is unknownMartin Atkins
Previously our behavior for an unknown for_each was to produce a single block whose content was the result of evaluating content with the iterator set to cty.DynamicVal. That produced a reasonable idea of the content, but the number of blocks in the result was still not accurate, and that can present a problem for applications that use unknown values to predict the overall shape of a not-yet-complete structure. We can't return an unknown block via the HCL API, but to make that situation easier to recognize by callers we'll now go a little further and force _all_ of the leaf attributes in such a block to be unknown values, even if they are constants in the configuration. This allows a calling application that is making predictions to use a single object whose leaves are all unknown as a heuristic to recognize what is effectively an unknown set of blocks. This is still not a perfect heuristic, but is the best we can do here within the HCL API assumptions. A fundamental assumption of the HCL API is that it's possible to walk the block structure without evaluating any expressions and the dynamic block extension is intentionally subverting that assumption, so some oddities are to be expected. Calling applications that need a fully reliable sense of the final structure should not use the dynamic block extension.
2019-03-27ext/dynblock: Allow WalkVariablesChild callers to get the bodyMartin Atkins
In normal situations the block type name alone is enough to determine the appropriate schema for a child, but when callers are otherwise doing unusual pre-processing of bodies to dynamically generate schemas during decoding they are likely to need to take similar steps while analyzing for variables, to ensure that all of the references can be located in spite of the not-yet-applied pre-processing.
2019-03-18ext/dynblock: Allow interrogation of _all_ references in blocksMartin Atkins
Our API previously had a function only for retrieving the variables used in the for_each and labels arguments used during an Expand call, and expected callers to then interrogate the resulting expanded block to find the other variables required to fully decode the content. That approach is insufficient for any application that needs to know the full set of required variables before any evaluation begins, such as when a dependency graph will be constructed to allow a topological traversal through blocks while evaluating. Now we have WalkVariables, which finds both the variables used to expand _and_ the variables within any blocks. This also renames WalkForEachVariables to WalkExpandVariables since that name is more accurate with the addition of the "label" argument into the expand-time dependency set. There is also a hcldec-based helper wrapper for each of those, allowing single-shot analysis of blocks for applications that use hcldec. This is a breaking change to the dynblock package API, because the old WalkForEachVariables and ForEachVariablesHCLDec functions are no longer present.
2018-12-19ext/dynblock: Make iterator variables visible to nested block for_eachMartin Atkins
Previously we were incorrectly passing down the original forEachCtx down to nested child blocks for recursive expansion. Instead, we must use the iteration-specific constructed EvalContext, which then allows any nested dynamic blocks to use the parent's iterator variable in their for_each or labels expressions, and thus unpack nested data structures into corresponding nested block structures: dynamic "parent" { for_each = [["a", "b"], []] content { dynamic "child" { for_each = parent.value content {} } } }
2018-07-28hcl: Include Expression reference in diagnosticsMartin Atkins
If a diagnostic occurs while we're evaluating an expression, we'll now include a reference to that expression in the diagnostic object. We previously added the corresponding EvalContext here too, and so with these together it is now possible for a diagnostic renderer to see not only what was in scope when the problem occurred but also what parts of that scope the expression was relying on (via method Expression.Variables).
2018-07-28hcl: Annotate diagnostics with expression EvalContextMartin Atkins
When we're evaluating expressions, we may end up evaluating the same source-level expression a number of times in different contexts, such as in a 'for' expression, where each one may produce a different set of diagnostic messages. Now we'll attach the EvalContext to each expression diagnostic so that a diagnostic renderer can potentially show additional information to help distinguish the different iterations in rendered diagnostics.
2018-01-27hcl: UnwrapExpression and UnwrapExpressionUntilMartin Atkins
A pattern has emerged of wrapping Expression instances with other Expressions in order to subtly modify their behavior. A key example of this is in ext/dynblock, where wrap an expression in order to introduce our additional iteration variable for expressions in dynamic blocks. Rather than having each wrapper expression implement wrapping implementations for our various syntax-level-analysis functions (like ExprList and AbsTraversalForExpr), instead we define a standard mechanism to unwrap expressions back to the lowest-level object -- usually an AST node -- and then use this in all of our analyses that look at the expression's structure rather than its value.
2018-01-27ext/dynblock: ForEachVariablesHCLDec helperMartin Atkins
For applications already using hcldec, a decoder specification can be used to automatically drive the recursive variable detection walk that begins with WalkForEachVariables, allowing all "for_each" and "labels" variables in a recursive block structure to be detected in a single call.
2018-01-27ext/dynblock: A more arduous way to find variables required to expandMartin Atkins
The previous ForEachVariables method was flawed because it didn't have enough information to properly analyze child blocks. Since the core HCL API requires a schema for any body analysis, and since a schema only describes one level of configuration structure at a time, we must require callers to drive a recursive walk through their nested block structure so that the correct schema can be provided at each level. This API is rather more complex than is ideal, but is the best we can do with the HCL Body API as currently defined, and it's currently defined that way in order to properly support ambiguous syntaxes like JSON.
2018-01-27ext/dynblock: dynamic blocks extensionMartin Atkins
This extension allows an application to support dynamic generation of child blocks based on expressions in certain contexts. This is done using a new block type called "dynamic", which contains an iteration value (which must be a collection) and a specification of how to construct a child block for each element of that collection.