Skip to content

Commit 0811894

Browse files
authored
Improve output with broken multiline playbooks (#4506)
1 parent 5314965 commit 0811894

File tree

7 files changed

+22
-16
lines changed

7 files changed

+22
-16
lines changed

src/ansiblelint/__main__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ def main(argv: list[str] | None = None) -> int:
280280
if argv is None: # pragma: no cover
281281
argv = sys.argv
282282

283+
warnings.simplefilter(
284+
"ignore", ResourceWarning
285+
) # suppress "enable tracemalloc to get the object allocation traceback"
283286
with warnings.catch_warnings(record=True) as warns:
284287
# do not use "ignore" as we will miss to collect them
285288
warnings.simplefilter(action="default")

src/ansiblelint/file_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ def is_owned_by_ansible(self) -> bool:
407407
def failed(self) -> bool:
408408
"""Return true if we already found syntax-check errors on this file."""
409409
return any(
410-
match.rule.id in ("syntax-check", "load-failure") for match in self.matches
410+
match.rule.id in ("syntax-check", "load-failure", "internal-error")
411+
for match in self.matches
411412
)
412413

413414
@property

src/ansiblelint/rules/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ def matchyaml(self, file: Lintable) -> list[MatchError]:
241241
yaml = [yaml]
242242

243243
for play in yaml:
244-
# Bug #849
245-
if play is None:
244+
# Bug #849 and #4492
245+
if play is None or not hasattr(play, "get"):
246246
continue
247247

248248
if self.id in play.get(SKIPPED_RULES_KEY, ()):

src/ansiblelint/runner.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,12 @@ def worker(lintable: Lintable) -> list[MatchError]:
270270
# do our processing only when ansible syntax check passed in order
271271
# to avoid causing runtime exceptions. Our processing is not as
272272
# resilient to be able process garbage.
273-
matches.extend(self._emit_matches(files))
273+
matches.extend(
274+
self._emit_matches([file for file in files if not file.failed()])
275+
)
274276

275277
# remove duplicates from files list
276-
files = [value for n, value in enumerate(files) if value not in files[:n]]
278+
files = list(dict.fromkeys(files))
277279

278280
for file in self.lintables:
279281
if file in self.checked_files or not file.kind or file.failed():
@@ -296,7 +298,7 @@ def worker(lintable: Lintable) -> list[MatchError]:
296298

297299
return sorted(set(matches))
298300

299-
# pylint: disable=too-many-locals
301+
# pylint: disable=too-many-locals,too-many-statements
300302
def _get_ansible_syntax_check_matches(
301303
self,
302304
lintable: Lintable,
@@ -432,6 +434,7 @@ def _get_ansible_syntax_check_matches(
432434
f"Unexpected error code {run.returncode} from "
433435
f"execution of: {' '.join(cmd)}"
434436
)
437+
filename.failed()
435438
results.append(
436439
MatchError(
437440
message=message,
@@ -461,6 +464,8 @@ def _emit_matches(self, files: list[Lintable]) -> Generator[MatchError, None, No
461464
while visited != self.lintables:
462465
for lintable in self.lintables - visited:
463466
visited.add(lintable)
467+
if lintable.failed():
468+
continue
464469
if not lintable.path.exists():
465470
continue
466471
try:
@@ -498,9 +503,9 @@ def find_children(self, lintable: Lintable) -> list[Lintable]:
498503
try:
499504
playbook_ds = ansiblelint.utils.parse_yaml_from_file(str(lintable.path))
500505
except AnsibleError as exc:
501-
msg = f"Loading {lintable.filename} caused an {type(exc).__name__} exception: {exc}, file was ignored."
502-
_logger.exception(msg)
503-
return []
506+
raise MatchError(
507+
lintable=lintable, rule=self.rules["load-failure"]
508+
) from exc
504509
results = []
505510
# playbook_ds can be an AnsibleUnicode string, which we consider invalid
506511
if isinstance(playbook_ds, str):

src/ansiblelint/skip_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,5 +316,8 @@ def is_nested_task(task: dict[str, Any]) -> bool:
316316
# Cannot really trust the input
317317
if isinstance(task, str):
318318
return False
319+
# https://github.com/ansible/ansible-lint/issues/4492
320+
if not hasattr(task, "get"):
321+
return False
319322

320323
return any(task.get(key) for key in NESTED_TASK_KEYS)

test/rules/test_syntax_check.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@
2727
pytest.param(
2828
"examples/playbooks/conflicting_action2.yml",
2929
[
30-
(
31-
"parser-error",
32-
1,
33-
None,
34-
"conflicting action statements: block, include_role",
35-
),
3630
(
3731
"syntax-check[specific]",
3832
5,

test/test_import_tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
4,
1616
id="0",
1717
),
18-
pytest.param("examples/playbooks/test_import_with_malformed.yml", 2, 2, id="1"),
18+
pytest.param("examples/playbooks/test_import_with_malformed.yml", 1, 1, id="1"),
1919
),
2020
)
2121
def test_import_tasks(

0 commit comments

Comments
 (0)