Skip to content

Commit 5306687

Browse files
authored
Adding regex based exports replacement (#1049)
1 parent 9311ae5 commit 5306687

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

src/rpdk/core/test.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
import json
66
import logging
77
import os
8+
import re
89
from argparse import SUPPRESS
910
from collections import OrderedDict
1011
from contextlib import contextmanager
1112
from pathlib import Path
1213
from tempfile import NamedTemporaryFile
1314

1415
import pytest
15-
from jinja2 import Environment, Template, meta
1616
from jsonschema import Draft6Validator
1717
from jsonschema.exceptions import ValidationError
1818

@@ -116,10 +116,26 @@ def get_cloudformation_exports(region_name, endpoint_url, role_arn, profile_name
116116
return exports
117117

118118

119-
def render_jinja(overrides_string, region_name, endpoint_url, role_arn, profile_name):
120-
env = Environment(autoescape=True)
121-
parsed_content = env.parse(overrides_string)
122-
variables = meta.find_undeclared_variables(parsed_content)
119+
def _stub_exports(template, exports, pattern):
120+
def __retrieve_args(match):
121+
try:
122+
export = str(match.group(1)).strip()
123+
value_to_stub = str(exports[export])
124+
except LookupError as e:
125+
LOG.error(str(e))
126+
raise ValueError(
127+
f"Export does not contain provided undeclared variable '{export}'. {e}"
128+
) from e
129+
return value_to_stub
130+
131+
return re.sub(pattern, __retrieve_args, template)
132+
133+
134+
def render_template(
135+
overrides_string, region_name, endpoint_url, role_arn, profile_name
136+
):
137+
regex = r"{{([-A-Za-z0-9:\s]+?)}}"
138+
variables = set(str(match).strip() for match in re.findall(regex, overrides_string))
123139
if variables:
124140
exports = get_cloudformation_exports(
125141
region_name, endpoint_url, role_arn, profile_name
@@ -132,8 +148,7 @@ def render_jinja(overrides_string, region_name, endpoint_url, role_arn, profile_
132148
)
133149
LOG.warning(invalid_exports_message, invalid_exports)
134150
return empty_override()
135-
overrides_template = Template(overrides_string)
136-
to_return = json.loads(overrides_template.render(exports))
151+
to_return = json.loads(_stub_exports(overrides_string, exports, regex))
137152
else:
138153
to_return = json.loads(overrides_string)
139154
return to_return
@@ -158,7 +173,7 @@ def get_overrides(root, region_name, endpoint_url, role_arn, profile_name):
158173
path = root / "overrides.json"
159174
try:
160175
with path.open("r", encoding="utf-8") as f:
161-
overrides_raw = render_jinja(
176+
overrides_raw = render_template(
162177
f.read(), region_name, endpoint_url, role_arn, profile_name
163178
)
164179
except FileNotFoundError:
@@ -195,7 +210,7 @@ def get_hook_overrides(root, region_name, endpoint_url, role_arn, profile_name):
195210
path = root / "overrides.json"
196211
try:
197212
with path.open("r", encoding="utf-8") as f:
198-
overrides_raw = render_jinja(
213+
overrides_raw = render_template(
199214
f.read(), region_name, endpoint_url, role_arn, profile_name
200215
)
201216
except FileNotFoundError:
@@ -264,7 +279,7 @@ def get_inputs(root, region_name, endpoint_url, value, role_arn, profile_name):
264279

265280
file_path = path / file
266281
with file_path.open("r", encoding="utf-8") as f:
267-
overrides_raw = render_jinja(
282+
overrides_raw = render_template(
268283
f.read(), region_name, endpoint_url, role_arn, profile_name
269284
)
270285
overrides = {}

tests/test_test.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
DEFAULT_FUNCTION,
2323
DEFAULT_PROFILE,
2424
DEFAULT_REGION,
25+
_stub_exports,
2526
_validate_sam_args,
2627
empty_hook_override,
2728
empty_override,
@@ -111,6 +112,44 @@ def _get_expected_marker_options(artifact_type):
111112
)
112113

113114

115+
@pytest.mark.parametrize(
116+
"template_string,exports,expected",
117+
[
118+
(
119+
'{"newName": "{{name}}","newLastName": {"newName": "{{ lastname }}"}}',
120+
{"name": "Jon", "lastname": "Snow"},
121+
'{"newName": "Jon","newLastName": {"newName": "Snow"}}',
122+
),
123+
(
124+
'{"newName": " {{ name }}","newLastName": {"newName": "{{ lastname } }"}}',
125+
{"name": "Jon", "lastname": "Snow"},
126+
'{"newName": " Jon","newLastName": {"newName": "{{ lastname } }"}}',
127+
),
128+
],
129+
)
130+
def test_stub_exports(template_string, exports, expected):
131+
assert expected == _stub_exports(
132+
template_string, exports, r"{{([-A-Za-z0-9:\s]+?)}}"
133+
)
134+
135+
136+
@pytest.mark.parametrize(
137+
"template_string,exports",
138+
[
139+
(
140+
'{"newName": "{{name}}","newLastName": {"newName": "{{ lastname }}"}}',
141+
{"name": "Jon"},
142+
),
143+
],
144+
)
145+
def test_stub_exports_exception(template_string, exports):
146+
with pytest.raises(ValueError) as e:
147+
_stub_exports(template_string, exports, r"{{([-A-Za-z0-9:\s]+?)}}")
148+
assert (
149+
str(e) == "Export does not contain provided undeclared variable 'lastname'"
150+
)
151+
152+
114153
def create_input_file(base, create_string, update_string, invalid_string):
115154
path = base / "inputs"
116155
os.mkdir(path, mode=0o777)

0 commit comments

Comments
 (0)