Skip to content
Merged
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
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exclude: >
examples/broken/encoding.yml|
examples/broken/encoding.j2|
examples/broken/yaml-with-tabs/invalid-due-tabs.yaml|
examples/broken/load-failure-invalid.yml|
examples/playbooks/collections/.*|
examples/playbooks/vars/empty.transformed.yml|
examples/playbooks/vars/empty.yml|
Expand Down
5 changes: 5 additions & 0 deletions examples/broken/load-failure-invalid.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- aaa: 1
bbb: 2
c: 3
foo: bar
25 changes: 22 additions & 3 deletions src/ansiblelint/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
from ansible.parsing.splitter import split_args
from ansible.plugins.loader import add_all_plugin_dirs
from ansible_compat.runtime import AnsibleWarning
from ruamel.yaml.parser import ParserError as RuamelParserError
from yaml.parser import ParserError
from yaml.scanner import ScannerError

import ansiblelint.skip_utils
import ansiblelint.utils
Expand Down Expand Up @@ -213,14 +216,30 @@ def _run(self) -> list[MatchError]:
self.lintables.remove(lintable)
continue
if isinstance(lintable.data, States) and lintable.exc:
line = 1
column = None
detail = ""
sub_tag = ""
lintable.exc.__class__.__name__.lower()
message = None
if lintable.exc.__cause__ and isinstance(lintable.exc.__cause__, ScannerError | ParserError | RuamelParserError):
sub_tag = "yaml"
if isinstance(lintable.exc.args, tuple):
message = lintable.exc.args[0]
detail = lintable.exc.__cause__.problem
if lintable.exc.__cause__.problem_mark:
line = lintable.exc.__cause__.problem_mark.line + 1
column = lintable.exc.__cause__.problem_mark.column + 1

matches.append(
MatchError(
lintable=lintable,
message=str(lintable.exc),
details=str(lintable.exc.__cause__),
message=message or str(lintable.exc),
details=detail or str(lintable.exc.__cause__),
rule=self.rules["load-failure"],
tag=f"load-failure[{lintable.exc.__class__.__name__.lower()}]",
lineno=line,
column=column,
tag=f"load-failure[{sub_tag or lintable.exc.__class__.__name__.lower()}]",
),
)
lintable.stop_processing = True
Expand Down
2 changes: 1 addition & 1 deletion src/ansiblelint/schemas/__store__.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json"
},
"meta": {
"etag": "ba724ad96ccb630237b908377c31796a1208265731b4b8a8fa91ffb7e52c611b",
"etag": "50a33e03b769d4574f20f192ce37dcb694361a8b30e030b2c1274f393e6595e4",
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json"
},
"meta-runtime": {
Expand Down
4 changes: 2 additions & 2 deletions src/ansiblelint/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1160,8 +1160,8 @@ def construct_mapping(
yaml.constructor.ConstructorError,
ruamel.yaml.parser.ParserError,
) as exc:
msg = f"Failed to load YAML file: {lintable.path}"
raise RuntimeError(msg) from exc
msg = "Failed to load YAML file"
raise RuntimeError(msg, lintable.path) from exc

if len(result) == 0:
return None # empty documents
Expand Down
19 changes: 19 additions & 0 deletions test/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,25 @@ def test_runner_not_found(default_rules_collection: RulesCollection) -> None:
assert result[0].tag == "load-failure[not-found]"


def test_runner_load_failure_yaml(default_rules_collection: RulesCollection) -> None:
"""Ensure load-failure[yaml] work as expected."""
checked_files: set[Lintable] = set()

filename = Path("examples/broken/load-failure-invalid.yml").resolve()
runner = Runner(
filename,
rules=default_rules_collection,
verbosity=0,
checked_files=checked_files,
)
result = runner.run()
assert len(runner.checked_files) == 1
assert len(result) == 1
assert result[0].tag == "load-failure[yaml]"
assert result[0].lineno == 5
assert result[0].column == 1


def test_runner_tmp_file(
tmp_path: Path,
default_rules_collection: RulesCollection,
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ set_env =
PIP_CONSTRAINT = {tox_root}/.config/constraints.txt
PIP_DISABLE_PIP_VERSION_CHECK = 1
PRE_COMMIT_COLOR = always
PYTEST_REQPASS = 908
PYTEST_REQPASS = 909
UV_CONSTRAINT = {tox_root}/.config/constraints.txt
deps, devel, hook, lint, pkg, pre, py310, schemas: PIP_CONSTRAINT = /dev/null
deps, devel, hook, lint, pkg, pre, py310, schemas: UV_CONSTRAINT = /dev/null
Expand Down
Loading