From 82caa49781c5dad4eb9cda5013062c7aea9a0a9e Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Thu, 25 Mar 2021 08:40:57 +0000 Subject: [PATCH] Add ability to ignore jinja2 templates Fixes issue where jinja2 templated YAML files would endup raising errors, as the YAML loader would have failed to load them. --- .pre-commit-config.yaml | 4 ++++ examples/other/some.j2.yaml | 2 ++ src/ansiblelint/config.py | 6 ++++++ src/ansiblelint/rules/__init__.py | 8 ++++++-- src/ansiblelint/utils.py | 1 + test/TestExamples.py | 1 + test/TestUtils.py | 4 ++++ 7 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 examples/other/some.j2.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f02bdf1264..55ccb08544 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,10 @@ repos: rev: v1.26.0 hooks: - id: yamllint + exclude: > + (?x)^( + examples/other/some.j2.yaml + )$ files: \.(yaml|yml)$ types: [file, yaml] entry: yamllint --strict diff --git a/examples/other/some.j2.yaml b/examples/other/some.j2.yaml new file mode 100644 index 0000000000..5d34f55281 --- /dev/null +++ b/examples/other/some.j2.yaml @@ -0,0 +1,2 @@ +# Used to validate that a templated YAML file does not confuse the linter +{% include 'port.j2' %} diff --git a/src/ansiblelint/config.py b/src/ansiblelint/config.py index 93f8b0f42d..0a3394cc9e 100644 --- a/src/ansiblelint/config.py +++ b/src/ansiblelint/config.py @@ -13,6 +13,8 @@ DEFAULT_KINDS = [ # Do not sort this list, order matters. + {"jinja2": "**/*.j2"}, # jinja2 templates are not always parsable as something else + {"jinja2": "**/*.j2.*"}, {"requirements": "**/meta/requirements.yml"}, # v1 only # https://docs.ansible.com/ansible/latest/dev_guide/collections_galaxy_meta.html {"galaxy": "**/galaxy.yml"}, # Galaxy collection meta @@ -40,6 +42,10 @@ # These assignations are only for internal use and are only inspired by # MIME/IANA model. Their purpose is to be able to process a file based on # it type, including generic processing of text files using the prefix. + { + "text/jinja2": "**/*.j2" + }, # jinja2 templates are not always parsable as something else + {"text/jinja2": "**/*.j2.*"}, {"text/json": "**/*.json"}, # standardized {"text/markdown": "**/*.md"}, # https://tools.ietf.org/html/rfc7763 {"text/rst": "**/*.rst"}, # https://en.wikipedia.org/wiki/ReStructuredText diff --git a/src/ansiblelint/rules/__init__.py b/src/ansiblelint/rules/__init__.py index 56c08cc2cd..a7d166ad53 100644 --- a/src/ansiblelint/rules/__init__.py +++ b/src/ansiblelint/rules/__init__.py @@ -89,7 +89,11 @@ def matchlines(self, file: "Lintable") -> List[MatchError]: # https://github.com/ansible-community/ansible-lint/issues/744 def matchtasks(self, file: Lintable) -> List[MatchError]: matches: List[MatchError] = [] - if not self.matchtask or file.kind not in ['handlers', 'tasks', 'playbook']: + if ( + not self.matchtask + or file.kind not in ['handlers', 'tasks', 'playbook'] + or file.base_kind != 'text/yaml' + ): return matches yaml = ansiblelint.utils.parse_yaml_linenumbers(file) @@ -136,7 +140,7 @@ def _matchplay_linenumber(play, optional_linenumber): def matchyaml(self, file: Lintable) -> List[MatchError]: matches: List[MatchError] = [] - if not self.matchplay: + if not self.matchplay or file.base_kind != 'text/yaml': return matches yaml = ansiblelint.utils.parse_yaml_linenumbers(file) diff --git a/src/ansiblelint/utils.py b/src/ansiblelint/utils.py index badbabab8f..6f0963e9f4 100644 --- a/src/ansiblelint/utils.py +++ b/src/ansiblelint/utils.py @@ -737,6 +737,7 @@ def construct_mapping(node, deep=False): loader.construct_mapping = construct_mapping data = loader.get_single_data() except (yaml.parser.ParserError, yaml.scanner.ScannerError) as e: + logging.exception(e) raise SystemExit("Failed to parse YAML in %s: %s" % (lintable.path, str(e))) return data diff --git a/test/TestExamples.py b/test/TestExamples.py index 4c9812d306..f3ca348b2e 100644 --- a/test/TestExamples.py +++ b/test/TestExamples.py @@ -64,3 +64,4 @@ def test_custom_kinds(): # .yaml-too is not a recognized extension and unless is manually defined # in our .ansible-lint config, the test would not identify it as yaml file. assert "Examining examples/other/some.yaml-too of type yaml" in result.stderr + assert "Examining examples/other/some.j2.yaml of type jinja2" in result.stderr diff --git a/test/TestUtils.py b/test/TestUtils.py index 38a780db96..252bc37a43 100644 --- a/test/TestUtils.py +++ b/test/TestUtils.py @@ -365,6 +365,10 @@ def test_is_playbook(): "tasks", ), # relative path involved ("galaxy.yml", "galaxy"), + ("foo.j2.yml", "jinja2"), + ("foo.yml.j2", "jinja2"), + ("foo.j2.yaml", "jinja2"), + ("foo.yaml.j2", "jinja2"), ), ) def test_default_kinds(monkeypatch, path: str, kind: FileType) -> None: