diff --git a/examples/rules/TaskHasTag.py b/examples/rules/TaskHasTag.py index 24394eabdd..c5e4d66792 100644 --- a/examples/rules/TaskHasTag.py +++ b/examples/rules/TaskHasTag.py @@ -1,8 +1,13 @@ """Example implementation of a rule requiring tasks to have tags set.""" -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class TaskHasTag(AnsibleLintRule): """Tasks must have tag.""" @@ -12,7 +17,9 @@ class TaskHasTag(AnsibleLintRule): description = 'Tasks must have tag' tags = ['productivity', 'tags'] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: """Task matching method.""" if isinstance(task, str): return False diff --git a/src/ansiblelint/_internal/rules.py b/src/ansiblelint/_internal/rules.py index a241fa9646..268922966c 100644 --- a/src/ansiblelint/_internal/rules.py +++ b/src/ansiblelint/_internal/rules.py @@ -2,6 +2,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union if TYPE_CHECKING: + from typing import Optional + from ansiblelint.constants import odict from ansiblelint.errors import MatchError from ansiblelint.file_utils import Lintable @@ -43,7 +45,9 @@ def matchlines(self, file: "Lintable") -> List["MatchError"]: """Return matches found for a specific line.""" return [] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: "Optional[Lintable]" = None + ) -> Union[bool, str]: """Confirm if current rule is matching a specific task.""" return False diff --git a/src/ansiblelint/rules/CommandHasChangesCheckRule.py b/src/ansiblelint/rules/CommandHasChangesCheckRule.py index 6926dc90fa..27761687f0 100644 --- a/src/ansiblelint/rules/CommandHasChangesCheckRule.py +++ b/src/ansiblelint/rules/CommandHasChangesCheckRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class CommandHasChangesCheckRule(AnsibleLintRule): id = 'no-changed-when' @@ -38,7 +43,9 @@ class CommandHasChangesCheckRule(AnsibleLintRule): _commands = ['command', 'shell', 'raw'] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task["__ansible_action_type__"] == 'task': if task["action"]["__ansible_module__"] in self._commands: return ( diff --git a/src/ansiblelint/rules/CommandsInsteadOfArgumentsRule.py b/src/ansiblelint/rules/CommandsInsteadOfArgumentsRule.py index e1bb05314d..0eedf4ca4c 100644 --- a/src/ansiblelint/rules/CommandsInsteadOfArgumentsRule.py +++ b/src/ansiblelint/rules/CommandsInsteadOfArgumentsRule.py @@ -19,11 +19,16 @@ # THE SOFTWARE. import os -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import convert_to_boolean, get_first_cmd_arg +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class CommandsInsteadOfArgumentsRule(AnsibleLintRule): id = 'deprecated-command-syntax' @@ -47,7 +52,9 @@ class CommandsInsteadOfArgumentsRule(AnsibleLintRule): 'rm': 'state=absent', } - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task["action"]["__ansible_module__"] in self._commands: first_cmd_arg = get_first_cmd_arg(task) if not first_cmd_arg: diff --git a/src/ansiblelint/rules/CommandsInsteadOfModulesRule.py b/src/ansiblelint/rules/CommandsInsteadOfModulesRule.py index 402f248196..1a76f6a00b 100644 --- a/src/ansiblelint/rules/CommandsInsteadOfModulesRule.py +++ b/src/ansiblelint/rules/CommandsInsteadOfModulesRule.py @@ -19,11 +19,16 @@ # THE SOFTWARE. import os -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import convert_to_boolean, get_first_cmd_arg +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class CommandsInsteadOfModulesRule(AnsibleLintRule): id = 'command-instead-of-module' @@ -59,7 +64,9 @@ class CommandsInsteadOfModulesRule(AnsibleLintRule): 'yum': 'yum', } - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task['action']['__ansible_module__'] not in self._commands: return False diff --git a/src/ansiblelint/rules/ComparisonToEmptyStringRule.py b/src/ansiblelint/rules/ComparisonToEmptyStringRule.py index c16813cf39..34b1d093b8 100644 --- a/src/ansiblelint/rules/ComparisonToEmptyStringRule.py +++ b/src/ansiblelint/rules/ComparisonToEmptyStringRule.py @@ -3,11 +3,16 @@ import re import sys -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import nested_items +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class ComparisonToEmptyStringRule(AnsibleLintRule): id = 'empty-string-compare' @@ -22,7 +27,9 @@ class ComparisonToEmptyStringRule(AnsibleLintRule): empty_string_compare = re.compile("[=!]= ?(\"{2}|'{2})") - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: for k, v, _ in nested_items(task): if k == 'when': if isinstance(v, str): diff --git a/src/ansiblelint/rules/ComparisonToLiteralBoolRule.py b/src/ansiblelint/rules/ComparisonToLiteralBoolRule.py index 840205800e..717d97c1f4 100644 --- a/src/ansiblelint/rules/ComparisonToLiteralBoolRule.py +++ b/src/ansiblelint/rules/ComparisonToLiteralBoolRule.py @@ -2,11 +2,16 @@ # Copyright (c) 2018-2021, Ansible Project import re -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import nested_items +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class ComparisonToLiteralBoolRule(AnsibleLintRule): id = 'literal-compare' @@ -21,7 +26,9 @@ class ComparisonToLiteralBoolRule(AnsibleLintRule): literal_bool_compare = re.compile("[=!]= ?(True|true|False|false)") - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: for k, v, _ in nested_items(task): if k == 'when': if isinstance(v, str): diff --git a/src/ansiblelint/rules/DeprecatedModuleRule.py b/src/ansiblelint/rules/DeprecatedModuleRule.py index 00adeff5c1..d4cece99ac 100644 --- a/src/ansiblelint/rules/DeprecatedModuleRule.py +++ b/src/ansiblelint/rules/DeprecatedModuleRule.py @@ -1,9 +1,14 @@ # Copyright (c) 2018, Ansible Project -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class DeprecatedModuleRule(AnsibleLintRule): id = 'deprecated-module' @@ -60,7 +65,9 @@ class DeprecatedModuleRule(AnsibleLintRule): 'include', ] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: module = task["action"]["__ansible_module__"] if module in self._modules: message = '{0} {1}' diff --git a/src/ansiblelint/rules/EnvVarsInCommandRule.py b/src/ansiblelint/rules/EnvVarsInCommandRule.py index 8e511be2a5..dab1bd1039 100644 --- a/src/ansiblelint/rules/EnvVarsInCommandRule.py +++ b/src/ansiblelint/rules/EnvVarsInCommandRule.py @@ -18,11 +18,16 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import FILENAME_KEY, LINE_NUMBER_KEY, get_first_cmd_arg +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class EnvVarsInCommandRule(AnsibleLintRule): id = 'inline-env-var' @@ -51,7 +56,9 @@ class EnvVarsInCommandRule(AnsibleLintRule): FILENAME_KEY, ] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task["action"]["__ansible_module__"] in ['command']: first_cmd_arg = get_first_cmd_arg(task) if not first_cmd_arg: diff --git a/src/ansiblelint/rules/GitHasVersionRule.py b/src/ansiblelint/rules/GitHasVersionRule.py index e3578c898b..b80e75ee2e 100644 --- a/src/ansiblelint/rules/GitHasVersionRule.py +++ b/src/ansiblelint/rules/GitHasVersionRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class GitHasVersionRule(AnsibleLintRule): id = 'git-latest' @@ -34,7 +39,9 @@ class GitHasVersionRule(AnsibleLintRule): tags = ['idempotency'] version_added = 'historic' - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: return bool( task['action']['__ansible_module__'] == 'git' and task['action'].get('version', 'HEAD') == 'HEAD' diff --git a/src/ansiblelint/rules/MercurialHasRevisionRule.py b/src/ansiblelint/rules/MercurialHasRevisionRule.py index 67ce3812f9..8327c6b1a6 100644 --- a/src/ansiblelint/rules/MercurialHasRevisionRule.py +++ b/src/ansiblelint/rules/MercurialHasRevisionRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class MercurialHasRevisionRule(AnsibleLintRule): id = 'hg-latest' @@ -34,7 +39,9 @@ class MercurialHasRevisionRule(AnsibleLintRule): tags = ['idempotency'] version_added = 'historic' - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: return bool( task['action']['__ansible_module__'] == 'hg' and task['action'].get('revision', 'default') == 'default' diff --git a/src/ansiblelint/rules/MissingFilePermissionsRule.py b/src/ansiblelint/rules/MissingFilePermissionsRule.py index 9a8475bb24..b0674b638c 100644 --- a/src/ansiblelint/rules/MissingFilePermissionsRule.py +++ b/src/ansiblelint/rules/MissingFilePermissionsRule.py @@ -17,10 +17,16 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + + # Despite documentation mentioning 'preserve' only these modules support it: _modules_with_preserve = ( 'copy', @@ -60,7 +66,9 @@ class MissingFilePermissionsRule(AnsibleLintRule): 'lineinfile': False, } - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: module = task["action"]["__ansible_module__"] mode = task['action'].get('mode', None) diff --git a/src/ansiblelint/rules/NestedJinjaRule.py b/src/ansiblelint/rules/NestedJinjaRule.py index 73792ae00e..997fc23ce2 100644 --- a/src/ansiblelint/rules/NestedJinjaRule.py +++ b/src/ansiblelint/rules/NestedJinjaRule.py @@ -22,10 +22,15 @@ # THE SOFTWARE. import re -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class NestedJinjaRule(AnsibleLintRule): id = 'no-jinja-nesting' @@ -42,8 +47,9 @@ class NestedJinjaRule(AnsibleLintRule): pattern = re.compile(r"{{(?:[^{}]*)?[^'\"]{{") - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: - + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: command = "".join( str(value) # task properties are stored in the 'action' key diff --git a/src/ansiblelint/rules/NoFormattingInWhenRule.py b/src/ansiblelint/rules/NoFormattingInWhenRule.py index 18e4b7854e..20516d5ab7 100644 --- a/src/ansiblelint/rules/NoFormattingInWhenRule.py +++ b/src/ansiblelint/rules/NoFormattingInWhenRule.py @@ -3,6 +3,8 @@ from ansiblelint.rules import AnsibleLintRule if TYPE_CHECKING: + from typing import Optional + from ansiblelint.constants import odict from ansiblelint.errors import MatchError from ansiblelint.file_utils import Lintable @@ -31,7 +33,7 @@ def matchplay( if 'roles' not in data or data['roles'] is None: return errors for role in data['roles']: - if self.matchtask(role): + if self.matchtask(role, file=file): errors.append(self.create_matcherror(details=str({'when': role}))) if isinstance(data, list): for play_item in data: @@ -40,5 +42,7 @@ def matchplay( errors = errors + sub_errors return errors - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: return 'when' in task and not self._is_valid(task['when']) diff --git a/src/ansiblelint/rules/NoTabsRule.py b/src/ansiblelint/rules/NoTabsRule.py index df6c684f53..4dba350ea3 100644 --- a/src/ansiblelint/rules/NoTabsRule.py +++ b/src/ansiblelint/rules/NoTabsRule.py @@ -1,11 +1,16 @@ # Copyright (c) 2016, Will Thames and contributors # Copyright (c) 2018, Ansible Project import sys -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import nested_items +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class NoTabsRule(AnsibleLintRule): id = 'no-tabs' @@ -21,7 +26,9 @@ class NoTabsRule(AnsibleLintRule): ("lineinfile", "line"), ] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: for k, v, parent in nested_items(task): if isinstance(k, str) and '\t' in k: return True diff --git a/src/ansiblelint/rules/OctalPermissionsRule.py b/src/ansiblelint/rules/OctalPermissionsRule.py index 181b2b95d6..48a0d96f85 100644 --- a/src/ansiblelint/rules/OctalPermissionsRule.py +++ b/src/ansiblelint/rules/OctalPermissionsRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class OctalPermissionsRule(AnsibleLintRule): id = 'risky-octal' @@ -80,7 +85,9 @@ def is_invalid_permission(self, mode: int) -> bool: or group_more_generous_than_user ) - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task["action"]["__ansible_module__"] in self._modules: mode = task['action'].get('mode', None) diff --git a/src/ansiblelint/rules/PackageIsNotLatestRule.py b/src/ansiblelint/rules/PackageIsNotLatestRule.py index f911d73ed4..088ad8905d 100644 --- a/src/ansiblelint/rules/PackageIsNotLatestRule.py +++ b/src/ansiblelint/rules/PackageIsNotLatestRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class PackageIsNotLatestRule(AnsibleLintRule): id = 'package-latest' @@ -62,7 +67,9 @@ class PackageIsNotLatestRule(AnsibleLintRule): 'zypper', ] - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: return ( task['action']['__ansible_module__'] in self._package_managers and not task['action'].get('version') diff --git a/src/ansiblelint/rules/RoleRelativePath.py b/src/ansiblelint/rules/RoleRelativePath.py index 7996bfc106..1018d37f0d 100644 --- a/src/ansiblelint/rules/RoleRelativePath.py +++ b/src/ansiblelint/rules/RoleRelativePath.py @@ -1,10 +1,15 @@ # Copyright (c) 2016, Tsukinowa Inc. # Copyright (c) 2018, Ansible Project -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class RoleRelativePath(AnsibleLintRule): id = 'no-relative-paths' @@ -23,7 +28,9 @@ class RoleRelativePath(AnsibleLintRule): 'win_template': 'win_templates', } - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: module = task['action']['__ansible_module__'] if module not in self._module_to_path_folder: return False diff --git a/src/ansiblelint/rules/ShellWithoutPipefail.py b/src/ansiblelint/rules/ShellWithoutPipefail.py index 8895979287..9710154e7e 100644 --- a/src/ansiblelint/rules/ShellWithoutPipefail.py +++ b/src/ansiblelint/rules/ShellWithoutPipefail.py @@ -1,9 +1,14 @@ import re -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import convert_to_boolean +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class ShellWithoutPipefail(AnsibleLintRule): id = 'risky-shell-pipe' @@ -23,7 +28,9 @@ class ShellWithoutPipefail(AnsibleLintRule): _pipefail_re = re.compile(r"^\s*set.*[+-][A-z]*o\s*pipefail", re.M) _pipe_re = re.compile(r"(? Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: if task["__ansible_action_type__"] != "task": return False diff --git a/src/ansiblelint/rules/TaskHasNameRule.py b/src/ansiblelint/rules/TaskHasNameRule.py index a26a76d41a..e7ef87d405 100644 --- a/src/ansiblelint/rules/TaskHasNameRule.py +++ b/src/ansiblelint/rules/TaskHasNameRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class TaskHasNameRule(AnsibleLintRule): id = 'unnamed-task' @@ -34,5 +39,7 @@ class TaskHasNameRule(AnsibleLintRule): tags = ['idiom'] version_added = 'historic' - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: return not task.get('name') diff --git a/src/ansiblelint/rules/TaskNoLocalAction.py b/src/ansiblelint/rules/TaskNoLocalAction.py index 04afaa13ad..e07967027f 100644 --- a/src/ansiblelint/rules/TaskNoLocalAction.py +++ b/src/ansiblelint/rules/TaskNoLocalAction.py @@ -1,6 +1,5 @@ # Copyright (c) 2016, Tsukinowa Inc. # Copyright (c) 2018, Ansible Project - from ansiblelint.rules import AnsibleLintRule diff --git a/src/ansiblelint/rules/UseCommandInsteadOfShellRule.py b/src/ansiblelint/rules/UseCommandInsteadOfShellRule.py index 283b6fde0d..0d18d3bee3 100644 --- a/src/ansiblelint/rules/UseCommandInsteadOfShellRule.py +++ b/src/ansiblelint/rules/UseCommandInsteadOfShellRule.py @@ -18,10 +18,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class UseCommandInsteadOfShellRule(AnsibleLintRule): id = 'command-instead-of-shell' @@ -35,7 +40,9 @@ class UseCommandInsteadOfShellRule(AnsibleLintRule): tags = ['command-shell', 'idiom'] version_added = 'historic' - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: # Use unjinja so that we don't match on jinja filters # rather than pipes if task["action"]["__ansible_module__"] == 'shell': diff --git a/src/ansiblelint/rules/UseHandlerRatherThanWhenChangedRule.py b/src/ansiblelint/rules/UseHandlerRatherThanWhenChangedRule.py index ae564aafd1..3f15564849 100644 --- a/src/ansiblelint/rules/UseHandlerRatherThanWhenChangedRule.py +++ b/src/ansiblelint/rules/UseHandlerRatherThanWhenChangedRule.py @@ -19,8 +19,9 @@ # THE SOFTWARE. import sys -from typing import Any, Dict, Union +from typing import Any, Dict, Optional, Union +from ansiblelint.file_utils import Lintable from ansiblelint.rules import AnsibleLintRule @@ -52,7 +53,9 @@ class UseHandlerRatherThanWhenChangedRule(AnsibleLintRule): tags = ['idiom'] version_added = 'historic' - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: Optional[Lintable] = None + ) -> Union[bool, str]: if task["__ansible_action_type__"] != 'task': return False @@ -68,7 +71,6 @@ def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: 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/rules/UsingBareVariablesIsDeprecatedRule.py b/src/ansiblelint/rules/UsingBareVariablesIsDeprecatedRule.py index e7d09e34c7..9c8e18e069 100644 --- a/src/ansiblelint/rules/UsingBareVariablesIsDeprecatedRule.py +++ b/src/ansiblelint/rules/UsingBareVariablesIsDeprecatedRule.py @@ -20,10 +20,15 @@ import os import re -from typing import Any, Dict, Union +from typing import TYPE_CHECKING, Any, Dict, Union from ansiblelint.rules import AnsibleLintRule +if TYPE_CHECKING: + from typing import Optional + + from ansiblelint.file_utils import Lintable + class UsingBareVariablesIsDeprecatedRule(AnsibleLintRule): id = 'deprecated-bare-vars' @@ -40,7 +45,9 @@ class UsingBareVariablesIsDeprecatedRule(AnsibleLintRule): _jinja = re.compile(r"{{.*}}", re.DOTALL) _glob = re.compile('[][*?]') - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: 'Optional[Lintable]' = None + ) -> Union[bool, str]: loop_type = next((key for key in task if key.startswith("with_")), None) if loop_type: if loop_type in [ diff --git a/src/ansiblelint/rules/VariableHasSpacesRule.py b/src/ansiblelint/rules/VariableHasSpacesRule.py index f424bd0b58..e1af823172 100644 --- a/src/ansiblelint/rules/VariableHasSpacesRule.py +++ b/src/ansiblelint/rules/VariableHasSpacesRule.py @@ -3,8 +3,9 @@ import re import sys -from typing import Any, Dict, Union +from typing import Any, Dict, Optional, Union +from ansiblelint.file_utils import Lintable from ansiblelint.rules import AnsibleLintRule from ansiblelint.utils import nested_items @@ -21,7 +22,9 @@ class VariableHasSpacesRule(AnsibleLintRule): bracket_regex = re.compile(r"{{[^{\n' -]|[^ '\n}-]}}", re.MULTILINE | re.DOTALL) exclude_json_re = re.compile(r"[^{]{'\w+': ?[^{]{.*?}}") - def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: + def matchtask( + self, task: Dict[str, Any], file: Optional[Lintable] = None + ) -> Union[bool, str]: for k, v, _ in nested_items(task): if isinstance(v, str): cleaned = self.exclude_json_re.sub("", v) @@ -32,7 +35,6 @@ def matchtask(self, task: Dict[str, Any]) -> Union[bool, str]: 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/rules/__init__.py b/src/ansiblelint/rules/__init__.py index 0da25e4ef0..cf55b1e719 100644 --- a/src/ansiblelint/rules/__init__.py +++ b/src/ansiblelint/rules/__init__.py @@ -114,7 +114,7 @@ def matchtasks(self, file: Lintable) -> List[MatchError]: if 'action' not in task: continue - result = self.matchtask(task) + result = self.matchtask(task, file=file) if not result: continue