diff --git a/docs/custom-rules.md b/docs/custom-rules.md index 20b81b3078..043dc3988b 100644 --- a/docs/custom-rules.md +++ b/docs/custom-rules.md @@ -1,32 +1,33 @@ -# Custom Rules +(defining-custom-rules)= -## Creating Custom Rules +# Custom linting rules -Rules are described using a class file per rule. Default rules are named -_DeprecatedVariableRule.py_, etc. +Define and use your own sets of rules with Ansible-lint. -Each rule definition should have the following: +## Ansible-lint rule definitions -- ID: A unique identifier +You define each custom rule in a unique Python class file. +Default rules are named _DeprecatedVariableRule.py_, etc. -- Short description: Brief description of the rule +Each rule should have a short description as a Python docstring wrapped in triple quotes `"""` immediately after the class name. +The short description should be brief and meaningfully explain the purpose of the rule to users. -- Description: What the rule is looking for +Each rule definition should have the following parts: -- Tags: One or more tags that may be used to include or exclude the rule +- `id` provides a unique identifier to the rule. +- `description` explains what the rule checks for. +- `tags` specifies one or more tags for including or excluding the rule. -- At least one of the following methods: +### Match and matchtask methods - - `match` that takes a line and returns None or False, if the line doesn't - match the test, and True or a custom message, when it does. (This allows - one rule to test multiple behaviors - see e.g. the - _CommandsInsteadOfModulesRule_.) - - `matchtask` that operates on a single task or handler, such that tasks - get standardized to always contain a _module_ key and _module_arguments_ - key. Other common task modifiers, such as _when_, _with_items_, etc., are - also available as keys, if present in the task. +Each rule definition should also invoke one of the following methods: -An example rule using `match` is: +- `match` takes a line and returns: + - None or False if the line does not match the test. + - True or a custom message if the line does match the test. (This allows one rule to test multiple behaviors - see e.g. the _CommandsInsteadOfModulesRule_.) +- `matchtask` operates on a single task or handler, such that tasks get standardized to always contain a _module_ key and _module_arguments_ key. Other common task modifiers, such as _when_, _with_items_, etc., are also available as keys if present in the task. + +The following is an example rule that uses the `match` method: ```python from ansiblelint.rules import AnsibleLintRule @@ -43,7 +44,7 @@ class DeprecatedVariableRule(AnsibleLintRule): return '${' in line ``` -An example rule using `matchtask` is: +The following is an example rule that uses the `matchtask` method: ```python from typing import TYPE_CHECKING, Any, Dict, Union @@ -88,29 +89,25 @@ In ansible-lint 3.0.0 `task['action']['module']` was renamed module as an argument. As a precaution, `task['action']['module_arguments']` was renamed `task['action']['__ansible_arguments__']`. -## Packaging Custom Rules +## Packaging custom rules -Ansible-lint provides a sub directory named _custom_ in its built-in rules, -`/usr/lib/python3.8/site-packages/ansiblelint/rules/custom/` for example, to -install custom rules since v4.3.1. The custom rules which are packaged as a -python package installed into this directory will be loaded and enabled -automatically by ansible-lint. +Ansible-lint automatically loads and enables custom rules in Python packages from the _custom_ subdirectory. +This subdirectory is part of the Ansible-lint installation directory, for example: -To make custom rules loaded automatically, you need the following: +`/usr/lib/python3.8/site-packages/ansiblelint/rules/custom/` -- Packaging your custom rules as a python package named some descriptive ones - like `ansible_lint_custom_rules_foo`. -- Make it installed into - `/custom//`. +To automatically load custom rules, do the following: -You may accomplish the second by adding some configurations into the \[options\] -section of the `setup.cfg` of your custom rules python package like the -following. +1. Package your custom rules as a Python package with a descriptive name. -``` -[options] -packages = - ansiblelint.rules.custom. -package_dir = - ansiblelint.rules.custom. = -``` +2. Configure the \[options\] section of the `setup.cfg` of your custom rules Python package as in the following example: + + ```yaml + [options] + packages = + ansiblelint.rules.custom. + package_dir = + ansiblelint.rules.custom. = + ``` + +3. Install the Python package into `/custom//`.