跳转至内容

自定义代码风格检查规则

使用 Ansible-lint 定义和使用您自己的规则集。

规则定义

每个自定义规则都在一个唯一的 Python 类文件中定义。默认规则命名为 *DeprecatedVariableRule.py* 等。

每个规则都应该有一个简短的描述作为 Python 文档字符串,用三个双引号 ```"""``` 包裹在类名之后。简短描述应该简洁明了地向用户解释规则的目的。

每个规则定义都应包含以下部分:

  • id 为规则提供一个唯一的标识符。
  • description 解释规则检查的内容。
  • tags 指定一个或多个标签,用于包含或排除规则。

Match 和 matchtask 方法

每个规则定义还应该调用以下方法之一:

  • match 接收一行并返回:
  • 如果该行与测试不匹配,则返回 None 或 False。
  • 如果该行与测试匹配,则返回 True 或自定义消息。(这允许一个规则测试多种行为 - 例如,参见 *CommandsInsteadOfModulesRule*。)
  • matchtask 用于单个任务或处理程序,以便任务始终包含 *module* 键和 *module_arguments* 键。其他常见的任务修饰符,例如 *when*、*with_items* 等,如果存在于任务中,也可用作键。

以下是一个使用match方法的示例规则:

from typing import Union
from ansiblelint.rules import AnsibleLintRule


class DeprecatedVariableRule(AnsibleLintRule):
    """Deprecated variable declarations."""

    id = 'EXAMPLE002'
    description = 'Check for lines that have old style ${var} ' + \
                  'declarations'
    tags = ['deprecations']

    def match(self, line: str) -> Union[bool, str]:
        return '${' in line

以下是一个使用matchtask方法的示例规则:

"""Example implementation of a rule requiring tasks to have tags set."""

from __future__ import annotations

from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule

if TYPE_CHECKING:
    from ansiblelint.file_utils import Lintable
    from ansiblelint.utils import Task


class TaskHasTag(AnsibleLintRule):
    """Tasks must have tag."""

    id = "EXAMPLE001"
    description = "Tasks must have tag"
    tags = ["productivity", "tags"]

    def matchtask(
        self,
        task: Task,
        file: Lintable | None = None,
    ) -> bool | str:
        """Task matching method."""
        if isinstance(task, str):
            return False

        # If the task include another task or make the playbook fail
        # Don't force to have a tag
        if not set(task.keys()).isdisjoint(["include", "fail"]):
            return False

        if not set(task.keys()).isdisjoint(["include_tasks", "fail"]):
            return False

        if not set(task.keys()).isdisjoint(["import_tasks", "fail"]):
            return False

        # Task should have tags
        return "tags" not in task

matchtask 的任务参数包含许多键 - 关键的是 *action*。task['action'] 的值包含正在使用的模块以及传递的参数,既包括键值对,也包括其他参数列表(例如,与 shell 一起使用的命令)。

打包自定义规则

Ansible-lint 自动加载并启用来自 *custom* 子目录中 Python 包的自定义规则。此子目录是 Ansible-lint 安装目录的一部分,例如:

/usr/lib/python3.8/site-packages/ansiblelint/rules/custom/

要自动加载自定义规则,请执行以下操作:

  1. 将您的自定义规则打包为具有描述性名称的 Python 包。

  2. 按照以下示例配置自定义规则 Python 包的setup.cfg的 [options] 部分:

[options]
packages =
    ansiblelint.rules.custom.<your_custom_rules_subdir>
package_dir =
    ansiblelint.rules.custom.<your_custom_rules_subdir> = <your_rules_source_code_subdir>
  1. 将 Python 包安装到<ansible_lint_custom_rules_dir>/custom/<your_custom_rules_subdir>/