From 09291dcd7ab8bdb712507d305c9f6727ca4525fc Mon Sep 17 00:00:00 2001 From: Satoru SATOH Date: Sun, 18 Apr 2021 16:43:34 +0900 Subject: [PATCH] Allow configurations for each rule stored in ansiblelint.config.options Add ansiblelint.config.options.rules: Dict[str, Any] to store configurations for each rule and utilize them from each rule to allow customize behaviors of rules more flexibly. Signed-Off-By: Satoru SATOH --- src/ansiblelint/config.py | 8 +++++++- src/ansiblelint/rules/__init__.py | 14 ++++++++++++-- test/TestAnsibleLintRule.py | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/ansiblelint/config.py b/src/ansiblelint/config.py index 32cef06815..04dfd0d4f0 100644 --- a/src/ansiblelint/config.py +++ b/src/ansiblelint/config.py @@ -5,7 +5,7 @@ import sys from argparse import Namespace from functools import lru_cache -from typing import Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple from packaging.version import Version @@ -84,6 +84,7 @@ extra_vars=None, enable_list=[], skip_action_validation=True, + rules=dict(), # Placeholder to set and keep configurations for each rule. ) # Used to store detected tag deprecations @@ -93,6 +94,11 @@ collection_list: List[str] = [] +def get_rule_config(rule_id: str) -> Dict[str, Any]: + """Get configurations for the rule ``rule_id``.""" + return options.rules.get(rule_id, dict()) + + @lru_cache() def ansible_collections_path() -> str: """Return collection path variable for current version of Ansible.""" diff --git a/src/ansiblelint/rules/__init__.py b/src/ansiblelint/rules/__init__.py index cf55b1e719..3f5b1c178a 100644 --- a/src/ansiblelint/rules/__init__.py +++ b/src/ansiblelint/rules/__init__.py @@ -7,8 +7,9 @@ import re from argparse import Namespace from collections import defaultdict +from functools import lru_cache from importlib.abc import Loader -from typing import Iterator, List, Optional, Set, Union +from typing import Any, Dict, Iterator, List, Optional, Set, Union import ansiblelint.utils from ansiblelint._internal.rules import ( @@ -17,7 +18,7 @@ LoadingFailureRule, RuntimeErrorRule, ) -from ansiblelint.config import options +from ansiblelint.config import get_rule_config, options from ansiblelint.errors import MatchError from ansiblelint.file_utils import Lintable from ansiblelint.skip_utils import append_skipped_rules, get_rule_skips_from_line @@ -26,6 +27,15 @@ class AnsibleLintRule(BaseRule): + @property + def rule_config(self) -> Dict[str, Any]: + return get_rule_config(self.id) + + @lru_cache() + def get_config(self, key: str) -> Any: + """Return a configured value for given key string.""" + return self.rule_config.get(key, None) + def __repr__(self) -> str: """Return a AnsibleLintRule instance representation.""" return self.id + ": " + self.shortdesc diff --git a/test/TestAnsibleLintRule.py b/test/TestAnsibleLintRule.py index 8149a176ee..f9eaec9beb 100644 --- a/test/TestAnsibleLintRule.py +++ b/test/TestAnsibleLintRule.py @@ -1,3 +1,6 @@ +import pytest + +from ansiblelint.config import options from ansiblelint.rules import AnsibleLintRule @@ -5,3 +8,14 @@ def test_unjinja(): text = "{{ a }} {% b %} {# try to confuse parsing inside a comment { {{}} } #}" output = "JINJA_EXPRESSION JINJA_STATEMENT JINJA_COMMENT" assert AnsibleLintRule.unjinja(text) == output + + +@pytest.mark.parametrize('rule_config', (dict(), dict(foo=True, bar=1))) +def test_rule_config(rule_config, monkeypatch): + rule_id = 'rule-0' + monkeypatch.setattr(AnsibleLintRule, 'id', rule_id) + monkeypatch.setitem(options.rules, rule_id, rule_config) + + rule = AnsibleLintRule() + assert set(rule.rule_config.items()) == set(rule_config.items()) + assert all(rule.get_config(k) == v for k, v in rule_config.items())