Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add auto-fixing implementation for no-handler rule #3732

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV:GITHUB_STEP_SUMMARY
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 822
PYTEST_REQPASS: 823
steps:
- name: Activate WSL1
if: "contains(matrix.shell, 'wsl')"
Expand Down
16 changes: 16 additions & 0 deletions examples/playbooks/transform-no-handler.transformed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Example of no-handler rule
hosts: localhost
tasks:
- name: Register result of a task
ansible.builtin.copy:
dest: /tmp/placeholder
content: Ansible made this!
mode: "0600"
register: result # <-- we register the result of the task
audgirka marked this conversation as resolved.
Show resolved Hide resolved

handlers:
- name: Second command to run
ansible.builtin.debug:
msg: The placeholder file was modified!
when: result.changed # <-- this triggers no-handler rule
15 changes: 15 additions & 0 deletions examples/playbooks/transform-no-handler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
- name: Example of no-handler rule
hosts: localhost
tasks:
- name: Register result of a task
ansible.builtin.copy:
dest: /tmp/placeholder
content: Ansible made this!
mode: "0600"
register: result # <-- we register the result of the task

- name: Second command to run
ansible.builtin.debug:
msg: The placeholder file was modified!
when: result.changed # <-- this triggers no-handler rule
34 changes: 31 additions & 3 deletions src/ansiblelint/rules/no_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
import sys
from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule
from ruamel.yaml.comments import CommentedMap, CommentedSeq

from ansiblelint.rules import AnsibleLintRule, TransformMixin
from ansiblelint.utils import Task

if TYPE_CHECKING:
from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable
from ansiblelint.utils import Task


def _changed_in_when(item: str) -> bool:
Expand All @@ -50,7 +53,7 @@ def _changed_in_when(item: str) -> bool:
)


class UseHandlerRatherThanWhenChangedRule(AnsibleLintRule):
class UseHandlerRatherThanWhenChangedRule(AnsibleLintRule, TransformMixin):
"""Tasks that run when changed should likely be handlers."""

id = "no-handler"
Expand Down Expand Up @@ -82,6 +85,31 @@ def matchtask(
result = _changed_in_when(when)
return result

def transform(
self,
match: MatchError,
lintable: Lintable,
data: CommentedMap | CommentedSeq | str,
) -> None:
if match.tag == self.id and isinstance(data, CommentedSeq):
is_fixed = False
task_name = None
if isinstance(match.task, Task):
task_name = match.task.get("name")

for item in data:
# Item is a play
# Look for handlers at the play level
if "handlers" not in item:
item["handlers"] = CommentedSeq()
for k, v in enumerate(item.get("tasks")):
if v["name"] == task_name:
item["handlers"].append(item.get("tasks").pop(k))
is_fixed = True

if is_fixed:
match.fixed = True


if "pytest" in sys.modules:
import pytest
Expand Down
6 changes: 6 additions & 0 deletions test/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def fixture_runner_result(
True,
id="partial_become",
),
pytest.param(
"examples/playbooks/transform-no-handler.yml",
1,
True,
id="transform_no_handler",
),
),
)
def test_transformer( # pylint: disable=too-many-arguments, too-many-locals
Expand Down