Skip to content

Commit

Permalink
Apply var-spacing tests to vars files
Browse files Browse the repository at this point in the history
  • Loading branch information
notok committed Apr 7, 2022
1 parent 29ceb53 commit d5651fa
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
36 changes: 36 additions & 0 deletions examples/playbooks/vars/var-spacing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
# Should raise var-spacing at following variables.
# ".bad_var_1", ".bad_var_2", ".bad_var_3", ".invalid_multiline_nested_json", ".invalid_nested_json"
good_var_1: "{{ good_format }}"
good_var_2: "Value: {{ good_format }}"
jinja_escape_1: "{{ '{{' }}"
jinja_escape_2: docker info --format '{{ '{{' }}json .Swarm.LocalNodeState{{ '}}' }}' | tr -d '"'
jinja_whitespace_control: |
{{ good_format }}/
{{- good_format }}
{{- good_format -}}
bad_var_1: "{{bad_format}}"
bad_var_2: "Value: {{ bad_format}}"
bad_var_3: "{{bad_format }}"
# spell-checker: disable-next-line
# non_jinja_var: "data = ${lookup{$local_part}lsearch{/etc/aliases}}" # noqa var-spacing FIXME
json_inside_jinja: "{{ {'test': {'subtest': variable}} }}"
multiline_vars: # Assert that no false positive on multiline exists
cases:
case1: >-
http://example.com/{{
case1 }}
case2: >-
http://example.com/{{
case2 }}
valid_nested_json: "{{ {'dummy_2': {'nested_dummy_1': 'value_1', 'nested_dummy_2': value_2}} | combine(dummy_1) }}"
invalid_nested_json: "{{ {'dummy_2': {'nested_dummy_1': 'value_1', 'nested_dummy_2': value_2}} | combine(dummy_1)}}"

valid_multiline_nested_json: >-
{{ {'dummy_2': {'nested_dummy_1': value_1,
'nested_dummy_2': value_2}} |
combine(dummy_1) }}
invalid_multiline_nested_json: >-
{{ {'dummy_2': {'nested_dummy_1': value_1,
'nested_dummy_2': value_2}} |
combine(dummy_1)}}
69 changes: 68 additions & 1 deletion src/ansiblelint/rules/var_spacing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

import re
import sys
from typing import Any, Dict, List, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union

from ansiblelint.file_utils import Lintable
from ansiblelint.rules import AnsibleLintRule
from ansiblelint.utils import parse_yaml_from_file
from ansiblelint.yaml_utils import nested_items_path

if TYPE_CHECKING:
from ansiblelint.errors import MatchError


class VariableHasSpacesRule(AnsibleLintRule):
"""Variables should have spaces before and after: {{ var_name }}."""
Expand All @@ -33,6 +37,31 @@ def matchtask(
return self.shortdesc.format(var_name=v)
return False

def matchyaml(self, file: Lintable) -> List["MatchError"]:
"""Return matches for variables defined in vars files."""
results: List["MatchError"] = []
meta_data: Dict[str, Any] = {}

if str(file.kind) == "vars":
meta_data = parse_yaml_from_file(str(file.path))
for k, v, path in nested_items_path(meta_data):
if isinstance(v, str):
cleaned = self.exclude_json_re.sub("", v)
if bool(self.bracket_regex.search(cleaned)):
path_elem = [
f"[{i}]" if isinstance(i, int) else i for i in path + [k]
]
results.append(
self.create_matcherror(
filename=file,
message=self.shortdesc.format(var_name=v),
details=f".{'.'.join(path_elem)}",
)
)
else:
results.extend(super().matchyaml(file))
return results


if "pytest" in sys.modules:

Expand Down Expand Up @@ -69,3 +98,41 @@ def test_var_spacing(
set(error_expected_lines).symmetric_difference(set(lint_error_lines))
)
assert len(error_lines_difference) == 0

# test for vars file
@pytest.fixture(name="error_expected_details_vars")
def fixture_error_expected_details_vars() -> List[str]:
"""Return list of expected error details."""
return [
".bad_var_1",
".bad_var_2",
".bad_var_3",
".invalid_multiline_nested_json",
".invalid_nested_json",
]

@pytest.fixture(name="test_vars")
def fixture_test_vars() -> str:
"""Return test cases vars file path."""
return "examples/playbooks/vars/var-spacing.yml"

@pytest.fixture(name="lint_error_details_vars")
def fixture_lint_error_details_vars(test_vars: str) -> List[str]:
"""Get VarHasSpacesRules linting results on test_vars."""
collection = RulesCollection()
collection.register(VariableHasSpacesRule())
lintable = Lintable(test_vars)
results = Runner(lintable, rules=collection).run()
return list(map(lambda item: item.details, results))

def test_var_spacing_vars(
error_expected_details_vars: List[str], lint_error_details_vars: List[str]
) -> None:
"""Ensure that expected error details are matching found linting error details."""
# list unexpected error details or non-matching error details
error_details_difference = list(
set(error_expected_details_vars).symmetric_difference(
set(lint_error_details_vars)
)
)
assert len(error_details_difference) == 0

0 comments on commit d5651fa

Please sign in to comment.