Skip to content

Commit

Permalink
Avoid implicit templating if not play/task (#2498)
Browse files Browse the repository at this point in the history
Fixes: #2490
  • Loading branch information
ssbarnea committed Sep 26, 2022
1 parent 5aa35c7 commit 0e8dee8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ jobs:
WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV:TOX_PARALLEL_NO_SPINNER
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 714
PYTEST_REQPASS: 715

steps:
- name: Activate WSL1
Expand Down
5 changes: 5 additions & 0 deletions examples/playbooks/vars/rule_jinja_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# this should not trigger any errors because a 'when' inside
# a vars files, does not use implicit jinja.
---
foo:
when: "{{ var }}"
45 changes: 39 additions & 6 deletions src/ansiblelint/rules/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ def matchtask( # noqa: C901
tag=f"{self.id}[invalid]",
)

reformatted, details, tag = self.check_whitespace(v, key=key)
reformatted, details, tag = self.check_whitespace(
v, key=key, lintable=file
)
if reformatted != v:
return self.create_matcherror(
message=self._msg(tag=tag, value=v, reformatted=reformatted),
Expand All @@ -141,7 +143,9 @@ def matchyaml(self, file: Lintable) -> list[MatchError]:
# pylint: disable=unused-variable
for key, v, path in nested_items_path(data):
if isinstance(v, AnsibleUnicode):
reformatted, details, tag = self.check_whitespace(v, key=key)
reformatted, details, tag = self.check_whitespace(
v, key=key, lintable=file
)
if reformatted != v:
results.append(
self.create_matcherror(
Expand Down Expand Up @@ -197,7 +201,7 @@ def unlex(self, tokens: list[Token]) -> str:

# pylint: disable=too-many-branches,too-many-statements,too-many-locals
def check_whitespace( # noqa: max-complexity: 13
self, text: str, key: str
self, text: str, key: str, lintable: Lintable | None = None
) -> tuple[str, str, str]:
"""Check spacing inside given jinja2 template string.
Expand Down Expand Up @@ -228,7 +232,15 @@ def uncook(value: str, implicit: bool = False) -> str:
implicit = False

# implicit templates do not have the {{ }} wrapping
if key in KEYWORDS_WITH_IMPLICIT_TEMPLATE:
if (
key in KEYWORDS_WITH_IMPLICIT_TEMPLATE
and lintable
and lintable.kind
in (
"playbook",
"task",
)
):
implicit = True
text = cook(text, implicit=implicit)

Expand Down Expand Up @@ -545,7 +557,9 @@ def test_jinja(text: str, expected: str, tag: str) -> None:
"""Tests our ability to spot spacing errors inside jinja2 templates."""
rule = JinjaRule()

reformatted, details, returned_tag = rule.check_whitespace(text, key="name")
reformatted, details, returned_tag = rule.check_whitespace(
text, key="name", lintable=Lintable("playbook.yml")
)
assert tag == returned_tag, details
assert expected == reformatted

Expand All @@ -572,10 +586,29 @@ def test_jinja(text: str, expected: str, tag: str) -> None:
def test_jinja_implicit(text: str, expected: str, tag: str) -> None:
"""Tests our ability to spot spacing errors implicit jinja2 templates."""
rule = JinjaRule()
reformatted, details, returned_tag = rule.check_whitespace(text, key="when")
# implicit jinja2 are working only inside playbooks and tasks
lintable = Lintable(name="playbook.yml", kind="playbook")
reformatted, details, returned_tag = rule.check_whitespace(
text, key="when", lintable=lintable
)
assert tag == returned_tag, details
assert expected == reformatted

@pytest.mark.parametrize(
("lintable", "matches"),
(pytest.param("examples/playbooks/vars/rule_jinja_vars.yml", 0, id="0"),),
)
def test_jinja_file(lintable: str, matches: int) -> None:
"""Tests our ability to process var filesspot spacing errors."""
collection = RulesCollection()
collection.register(JinjaRule())
errs = Runner(lintable, rules=collection).run()
assert len(errs) == matches
for err in errs:
assert isinstance(err, JinjaRule)
assert errs[0].tag == "jinja[invalid]"
assert errs[0].rule.id == "jinja"

def test_jinja_invalid() -> None:
"""Tests our ability to spot spacing errors inside jinja2 templates."""
collection = RulesCollection()
Expand Down

0 comments on commit 0e8dee8

Please sign in to comment.