Skip to content

Commit

Permalink
Add write_exclude_list config option (#4256)
Browse files Browse the repository at this point in the history
  • Loading branch information
frq-asgard-josi authored Dec 18, 2024
1 parent 4cc05a7 commit e66997f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/ansiblelint/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class Options: # pylint: disable=too-many-instance-attributes
list_rules: bool = False
list_tags: bool = False
write_list: list[str] = field(default_factory=list)
write_exclude_list: list[str] = field(default_factory=list)
parseable: bool = False
quiet: bool = False
rulesdirs: list[Path] = field(default_factory=list)
Expand Down
7 changes: 7 additions & 0 deletions src/ansiblelint/schemas/ansible-lint-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@
"title": "Warn List",
"type": "array"
},
"write_exclude_list": {
"items": {
"type": "string"
},
"title": "Write Exclude List",
"type": "array"
},
"write_list": {
"items": {
"type": "string"
Expand Down
18 changes: 11 additions & 7 deletions src/ansiblelint/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Transformer:
def __init__(self, result: LintResult, options: Options):
"""Initialize a Transformer instance."""
self.write_set = self.effective_write_set(options.write_list)
self.write_exclude_set = self.effective_write_set(options.write_exclude_list)

self.matches: list[MatchError] = result.matches
self.files: set[Lintable] = result.files
Expand Down Expand Up @@ -150,13 +151,16 @@ def _do_transforms(
if not isinstance(match.rule, TransformMixin):
_logger.debug("%s %s", self.FIX_NA_MSG, match_id)
continue
if self.write_set != {"all"}:
rule = cast("AnsibleLintRule", match.rule)
rule_definition = set(rule.tags)
rule_definition.add(rule.id)
if rule_definition.isdisjoint(self.write_set):
_logger.debug("%s %s", self.FIX_NE_MSG, match_id)
continue
rule = cast("AnsibleLintRule", match.rule)
rule_definition = set(rule.tags)
rule_definition.add(rule.id)
if not rule_definition.isdisjoint(
self.write_exclude_set,
) or self.write_exclude_set == {"all"}:
continue
if rule_definition.isdisjoint(self.write_set) and self.write_set != {"all"}:
_logger.debug("%s %s", self.FIX_NE_MSG, match_id)
continue
if file_is_yaml and not match.yaml_path:
data = cast("CommentedMap | CommentedSeq", data)
if match.match_type == "play":
Expand Down
75 changes: 72 additions & 3 deletions test/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@
from pathlib import Path
from typing import TYPE_CHECKING, Any
from unittest import mock
from unittest.mock import Mock

import pytest

import ansiblelint.__main__ as main
from ansiblelint.app import App
from ansiblelint.config import Options
from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable
from ansiblelint.rules import TransformMixin
from ansiblelint.rules import AnsibleLintRule, TransformMixin

# noinspection PyProtectedMember
from ansiblelint.runner import LintResult, get_matches
from ansiblelint.transformer import Transformer

if TYPE_CHECKING:
from ansiblelint.config import Options
from ansiblelint.errors import MatchError
from ansiblelint.rules import RulesCollection


Expand Down Expand Up @@ -297,6 +298,74 @@ def test_effective_write_set(write_list: list[str], expected: set[str]) -> None:
assert actual == expected


@pytest.mark.parametrize(
("write_list", "write_exclude_list", "rules"),
(
(
["all"],
["none"],
[("rule-id", True), ("rule1", True), ("rule-03", True)],
),
(
["all"],
["all"],
[("rule-id", False), ("rule1", False), ("rule-03", False)],
),
(
["none"],
["none"],
[("rule-id", False), ("rule1", False), ("rule-03", False)],
),
(
["none"],
["all"],
[("rule-id", False), ("rule1", False), ("rule-03", False)],
),
(
["rule-id"],
["none"],
[("rule-id", True), ("rule1", False), ("rule-03", False)],
),
(
["rule-id"],
["all"],
[("rule-id", False), ("rule1", False), ("rule-03", False)],
),
),
)
def test_write_exclude_list(
write_list: list[str],
write_exclude_list: list[str],
rules: list[tuple[str, bool]],
) -> None:
"""Test item matching write_exclude_list are excluded correctly."""
matches: list[MatchError] = []

class TestRule(AnsibleLintRule, TransformMixin):
"""Dummy class for transformable rules."""

for rule_id, transform_expected in rules:
rule = Mock(spec=TestRule)
rule.id = rule_id
rule.tags = []
rule.transform_expected = transform_expected
match = MatchError(rule=rule)
matches.append(match)

transformer = Transformer(
LintResult(matches, set()),
Options(write_list=write_list, write_exclude_list=write_exclude_list),
)
# noinspection PyTypeChecker
Transformer._do_transforms(transformer, Mock(), "", False, matches) # noqa: SLF001

for match in matches:
if match.rule.transform_expected: # type: ignore[attr-defined]
match.rule.transform.assert_called() # type: ignore[attr-defined]
else:
match.rule.transform.assert_not_called() # type: ignore[attr-defined]


def test_pruned_err_after_fix(monkeypatch: pytest.MonkeyPatch, tmpdir: Path) -> None:
"""Test that pruned errors are not reported after fixing.
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ setenv =
PRE_COMMIT_COLOR = always
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests. (tox-extra)
PYTEST_REQPASS = 900
PYTEST_REQPASS = 906
FORCE_COLOR = 1
pre: PIP_PRE = 1
allowlist_externals =
Expand Down

0 comments on commit e66997f

Please sign in to comment.