Skip to content

Commit

Permalink
Add play level autofix for key-order rule
Browse files Browse the repository at this point in the history
  • Loading branch information
audgirka authored and ssbarnea committed Oct 10, 2023
1 parent 73a04ac commit 2f8c64d
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
env:
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 831
PYTEST_REQPASS: 832
steps:
- uses: actions/checkout@v4
with:
Expand Down
10 changes: 10 additions & 0 deletions examples/playbooks/transform-key-order-play.transformed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: This is a playbook # <-- name key should be the first one
hosts: localhost
tasks:
- name: A block
when: true
block:
- name: Display a message
ansible.builtin.debug:
msg: Hello world!
10 changes: 10 additions & 0 deletions examples/playbooks/transform-key-order-play.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- hosts: localhost
name: This is a playbook # <-- name key should be the first one
tasks:
- name: A block
when: true
block:
- name: Display a message
ansible.builtin.debug:
msg: Hello world!
37 changes: 31 additions & 6 deletions src/ansiblelint/rules/key_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import functools
import sys
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from ansiblelint.errors import RuleMatchTransformMeta
from ansiblelint.constants import ANNOTATION_KEYS, LINE_NUMBER_KEY
from ansiblelint.errors import MatchError, RuleMatchTransformMeta
from ansiblelint.rules import AnsibleLintRule, TransformMixin

if TYPE_CHECKING:
from ruamel.yaml.comments import CommentedMap, CommentedSeq

from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable
from ansiblelint.utils import Task

Expand Down Expand Up @@ -77,6 +77,25 @@ class KeyOrderRule(AnsibleLintRule, TransformMixin):
"key-order[task]": "You can improve the task key order",
}

def matchplay(self, file: Lintable, data: dict[str, Any]) -> list[MatchError]:
"""Return matches found for a specific play (entry in playbook)."""
result: list[MatchError] = []
if file.kind != "playbook":
return result
keys = [str(key) for key, val in data.items() if key not in ANNOTATION_KEYS]
sorted_keys = sorted(keys, key=functools.cmp_to_key(task_property_sorter))
if keys != sorted_keys:
result.append(
self.create_matcherror(
f"You can improve the play key order to: {', '.join(sorted_keys)}",
filename=file,
tag=f"{self.id}[play]",
lineno=data[LINE_NUMBER_KEY],
transform_meta=KeyOrderTMeta(fixed=tuple(sorted_keys)),
),
)
return result

def matchtask(
self,
task: Task,
Expand All @@ -103,9 +122,15 @@ def transform(
lintable: Lintable,
data: CommentedMap | CommentedSeq | str,
) -> None:
if match.tag == "key-order[task]":
if not isinstance(match.transform_meta, KeyOrderTMeta):
return
if not isinstance(match.transform_meta, KeyOrderTMeta):
return

if match.tag == f"{self.id}[play]":
play = self.seek(match.yaml_path, data)
for key in match.transform_meta.fixed:
play[key] = play.pop(key)
match.fixed = True
if match.tag == f"{self.id}[task]":
task = self.seek(match.yaml_path, data)
for key in match.transform_meta.fixed:
task[key] = task.pop(key)
Expand Down
6 changes: 6 additions & 0 deletions test/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ def fixture_runner_result(
True,
id="partial_become",
),
pytest.param(
"examples/playbooks/transform-key-order-play.yml",
1,
True,
id="key_order_play_transform",
),
),
)
@mock.patch.dict(os.environ, {"ANSIBLE_LINT_WRITE_TMP": "1"}, clear=True)
Expand Down

0 comments on commit 2f8c64d

Please sign in to comment.