From 0233c19f47f25aca238c04b9210bcf72fe010d92 Mon Sep 17 00:00:00 2001 From: Ajinkya Udgirkar Date: Mon, 26 Feb 2024 16:00:15 +0530 Subject: [PATCH] Update task name in `notify` for a task against `name[casing]` error (#4038) --- examples/playbooks/name-case.transformed.yml | 26 ++++++++++- examples/playbooks/name-case.yml | 26 ++++++++++- src/ansiblelint/rules/name.py | 48 +++++++++++++++----- src/ansiblelint/schemas/__store__.json | 2 +- test/test_transformer.py | 4 +- test/test_yaml_utils.py | 1 - 6 files changed, 90 insertions(+), 17 deletions(-) diff --git a/examples/playbooks/name-case.transformed.yml b/examples/playbooks/name-case.transformed.yml index 03b8c46e8c..b7bc0257ad 100644 --- a/examples/playbooks/name-case.transformed.yml +++ b/examples/playbooks/name-case.transformed.yml @@ -1,4 +1,28 @@ --- - name: This lacks a capitalization hosts: localhost - tasks: [] + tasks: + - name: Task that always changes + ansible.builtin.debug: + msg: I always change! + changed_when: true + notify: My handler + + - name: Task with notify as list + ansible.builtin.debug: + msg: I always change! + changed_when: true + notify: + - my handler 1 + - My handler + - my handler 2 + + handlers: + - name: My handler + ansible.builtin.debug: + msg: I never run :( + + - name: Test task for listen + ansible.builtin.debug: + msg: I never run :( + listen: My handler diff --git a/examples/playbooks/name-case.yml b/examples/playbooks/name-case.yml index 5480d2c697..65255d7976 100644 --- a/examples/playbooks/name-case.yml +++ b/examples/playbooks/name-case.yml @@ -1,4 +1,28 @@ --- - name: this lacks a capitalization hosts: localhost - tasks: [] + tasks: + - name: Task that always changes + ansible.builtin.debug: + msg: I always change! + changed_when: true + notify: my handler + + - name: Task with notify as list + ansible.builtin.debug: + msg: I always change! + changed_when: true + notify: + - my handler 1 + - my handler + - my handler 2 + + handlers: + - name: my handler + ansible.builtin.debug: + msg: I never run :( + + - name: Test task for listen + ansible.builtin.debug: + msg: I never run :( + listen: "my handler" diff --git a/src/ansiblelint/rules/name.py b/src/ansiblelint/rules/name.py index b63ad48137..2f1f87006e 100644 --- a/src/ansiblelint/rules/name.py +++ b/src/ansiblelint/rules/name.py @@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any from ansiblelint.constants import LINE_NUMBER_KEY +from ansiblelint.file_utils import Lintable from ansiblelint.rules import AnsibleLintRule, TransformMixin if TYPE_CHECKING: @@ -14,7 +15,6 @@ from ansiblelint.config import Options from ansiblelint.errors import MatchError - from ansiblelint.file_utils import Lintable from ansiblelint.utils import Task @@ -173,22 +173,48 @@ def transform( data: CommentedMap | CommentedSeq | str, ) -> None: if match.tag == "name[casing]": - target_task = self.seek(match.yaml_path, data) - # Not using capitalize(), since that rewrites the rest of the name to lower case - task_name = target_task.get("name", None) - if task_name: + + def update_task_name(task_name: str) -> str: + """Capitalize the first work of the task name.""" + # Not using capitalize(), since that rewrites the rest of the name to lower case if "|" in task_name: # if using prefix [file_name, update_task_name] = task_name.split("|") - target_task["name"] = ( - f"{file_name.strip()} | {update_task_name.strip()[:1].upper()}{update_task_name.strip()[1:]}" - ) - else: - target_task["name"] = f"{task_name[:1].upper()}{task_name[1:]}" + return f"{file_name.strip()} | {update_task_name.strip()[:1].upper()}{update_task_name.strip()[1:]}" + + return f"{task_name[:1].upper()}{task_name[1:]}" + + target_task = self.seek(match.yaml_path, data) + orig_task_name = target_task.get("name", None) + # pylint: disable=too-many-nested-blocks + if orig_task_name: + updated_task_name = update_task_name(orig_task_name) + for item in data: + if isinstance(item, dict) and "tasks" in item: + for task in item["tasks"]: + if ( + isinstance(task["notify"], str) + and orig_task_name == task["notify"] + ): + task["notify"] = updated_task_name + elif isinstance(task["notify"], list): + for idx in range(len(task["notify"])): + if orig_task_name == task["notify"][idx]: + task["notify"][idx] = updated_task_name + + if isinstance(item, dict) and "handlers" in item: + for task in item["handlers"]: + listener_task_name = task.get("listen", None) + if ( + listener_task_name + and listener_task_name == orig_task_name + ): + task["listen"] = updated_task_name + + target_task["name"] = updated_task_name match.fixed = True if "pytest" in sys.modules: - from ansiblelint.file_utils import Lintable from ansiblelint.rules import RulesCollection from ansiblelint.runner import Runner diff --git a/src/ansiblelint/schemas/__store__.json b/src/ansiblelint/schemas/__store__.json index a1c4e7c446..d23cd35a46 100644 --- a/src/ansiblelint/schemas/__store__.json +++ b/src/ansiblelint/schemas/__store__.json @@ -44,7 +44,7 @@ "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/requirements.json" }, "role-arg-spec": { - "etag": "c1eadbf5b551aeb9b8f2781728fb6d66453609b44a8921bcc65984ab3daf4bdc", + "etag": "e0f25bc37f7b43d55b8e8f41929cab803179550e237d63c1134d51dfdd985ddf", "url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/role-arg-spec.json" }, "rulebook": { diff --git a/test/test_transformer.py b/test/test_transformer.py index fabd5a3414..0fd9522e77 100644 --- a/test/test_transformer.py +++ b/test/test_transformer.py @@ -77,7 +77,7 @@ def fixture_runner_result( id="strings", ), pytest.param("examples/playbooks/vars/empty.yml", 1, False, True, id="empty"), - pytest.param("examples/playbooks/name-case.yml", 1, True, True, id="name_case"), + pytest.param("examples/playbooks/name-case.yml", 2, True, True, id="name_case"), pytest.param("examples/playbooks/fqcn.yml", 3, True, True, id="fqcn"), pytest.param( "examples/playbooks/multi_yaml_doc.yml", @@ -182,7 +182,7 @@ def fixture_runner_result( 2, True, True, - id="name_case", + id="name_case_roles", ), ), ) diff --git a/test/test_yaml_utils.py b/test/test_yaml_utils.py index a868601e10..08d9edfbbe 100644 --- a/test/test_yaml_utils.py +++ b/test/test_yaml_utils.py @@ -267,7 +267,6 @@ def test_formatted_yaml_loader_dumper( version: tuple[int, int], ) -> None: """Ensure that FormattedYAML loads/dumps formatting fixtures consistently.""" - # pylint: disable=unused-argument before_content, prettier_content, after_content = load_yaml_formatting_fixtures( fixture_filename, )