Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions hcl2/reconstructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ def _should_add_space(self, rule, current_terminal, is_block_label: bool = False
if isinstance(self._last_rule, str) and re.match(
r"^__(tuple|arguments)_(star|plus)_.*", self._last_rule
):

# string literals, decimals, and identifiers should always be
# preceded by a space if they're following a comma in a tuple or
# function arg
Expand Down Expand Up @@ -362,6 +361,10 @@ def _name_to_identifier(name: str) -> Tree:
"""Converts a string to a NAME token within an identifier rule."""
return Tree(Token("RULE", "identifier"), [Token("NAME", name)])

@staticmethod
def _is_valid_identifier(name: str) -> bool:
return re.match(r"^\w[\w\d]*$", name) is not None

@staticmethod
def _escape_interpolated_str(interp_s: str) -> str:
if interp_s.strip().startswith("<<-") or interp_s.strip().startswith("<<"):
Expand Down Expand Up @@ -620,14 +623,14 @@ def _transform_value_to_expr_term(self, value, level) -> Union[Token, Tree]:
continue

value_expr_term = self._transform_value_to_expr_term(dict_v, level + 1)
k = self._unwrap_interpolation(k)
k = self._transform_value_to_key(k, level + 1)
elements.append(
Tree(
Token("RULE", "object_elem"),
[
Tree(
Token("RULE", "object_elem_key"),
[Tree(Token("RULE", "identifier"), [Token("NAME", k)])],
[k],
),
Token("EQ", " ="),
value_expr_term,
Expand Down Expand Up @@ -732,3 +735,20 @@ def _transform_value_to_expr_term(self, value, level) -> Union[Token, Tree]:

# otherwise, we don't know the type
raise RuntimeError(f"Unknown type to transform {type(value)}")

def _transform_value_to_key(self, value, level) -> Tree:
"""
Convert any value to a suitable key for an object
"""
if self._is_valid_identifier(value):
return self._name_to_identifier(value)
expr = self._transform_value_to_expr_term(value, level)
# If the expression is a string, then return an object_elem_key of the string
if expr.data == "expr_term" and expr.children[0].data == "string":
return expr.children[0]
else:
# Otherwise return an expression
return Tree(
Token("RULE", "object_elem_key_expression"),
[Token("LPAR", "("), expr, Token("RPAR", ")")],
)
8 changes: 4 additions & 4 deletions hcl2/transformer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A Lark Transformer for transforming a Lark parse tree into a Python dict"""

import json
import re
import sys
Expand Down Expand Up @@ -103,9 +104,7 @@ def object_elem(self, args: List) -> Dict:
# into a bigger dict that is returned by the "object" function

key = str(args[0].children[0])
if not re.match(r".*?(\${).*}.*", key):
# do not strip quotes of a interpolation string
key = self.strip_quotes(key)
key = self.strip_quotes(key)

value = self.to_string_dollar(args[2])
return {key: value}
Expand All @@ -114,7 +113,8 @@ def object_elem_key_dot_accessor(self, args: List) -> str:
return "".join(args)

def object_elem_key_expression(self, args: List) -> str:
return self.to_string_dollar("".join(args))
# the first and third arguments are parentheses
return self.to_string_dollar(args[1])

def object(self, args: List) -> Dict:
args = self.strip_new_line_tokens(args)
Expand Down
10 changes: 7 additions & 3 deletions test/helpers/terraform-config-json/variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@
"foo": "${var.account}_bar",
"bar": {
"baz": 1,
"${(var.account)}": 2,
"${(format(\"key_prefix_%s\", local.foo))}": 3,
"\"prefix_${var.account}:${var.user}_suffix\"": "interpolation"
"${var.account}": 2,
"${format(\"key_prefix_%s\", local.foo)}": 3,
"prefix_${var.account}:${var.user}_suffix": "interpolation",
"${var.start}-mid-${var.end}": 4,
"a:b": 5,
"123": 6,
"${var.x + 1}": 7
},
"tuple": ["${local.foo}"],
"empty_tuple": []
Expand Down
10 changes: 7 additions & 3 deletions test/helpers/terraform-config/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ locals {
baz : 1
(var.account) : 2
(format("key_prefix_%s", local.foo)) : 3
"prefix_${var.account}:${var.user}_suffix":"interpolation",
"prefix_${var.account}:${var.user}_suffix" : "interpolation",
"${var.start}-mid-${var.end}" : 4
"a:b" : 5
123 : 6
(var.x + 1) : 7
}
tuple = [local.foo]
tuple = [local.foo]
empty_tuple = []
}

Expand Down Expand Up @@ -76,7 +80,7 @@ locals {

for_whitespace = { for i in [1, 2, 3] :
i =>
i ...
i...
}
}

Expand Down
Loading