summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/rules/literal_compare.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/ansiblelint/rules/literal_compare.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/ansiblelint/rules/literal_compare.py b/src/ansiblelint/rules/literal_compare.py
new file mode 100644
index 0000000..1129d1d
--- /dev/null
+++ b/src/ansiblelint/rules/literal_compare.py
@@ -0,0 +1,86 @@
+"""Implementation of the literal-compare rule."""
+# Copyright (c) 2016, Will Thames and contributors
+# Copyright (c) 2018-2021, Ansible Project
+
+from __future__ import annotations
+
+import re
+import sys
+from typing import TYPE_CHECKING
+
+from ansiblelint.rules import AnsibleLintRule
+from ansiblelint.yaml_utils import nested_items_path
+
+if TYPE_CHECKING:
+ from ansiblelint.file_utils import Lintable
+ from ansiblelint.utils import Task
+
+
+class ComparisonToLiteralBoolRule(AnsibleLintRule):
+ """Don't compare to literal True/False."""
+
+ id = "literal-compare"
+ description = (
+ "Use ``when: var`` rather than ``when: var == True`` "
+ "(or conversely ``when: not var``)"
+ )
+ severity = "HIGH"
+ tags = ["idiom"]
+ version_added = "v4.0.0"
+
+ literal_bool_compare = re.compile("[=!]= ?(True|true|False|false)")
+
+ def matchtask(
+ self,
+ task: Task,
+ file: Lintable | None = None,
+ ) -> bool | str:
+ for k, v, _ in nested_items_path(task):
+ if k == "when":
+ if isinstance(v, str):
+ if self.literal_bool_compare.search(v):
+ return True
+ elif isinstance(v, bool):
+ pass
+ else:
+ for item in v:
+ if isinstance(item, str) and self.literal_bool_compare.search(
+ item,
+ ):
+ return True
+
+ return False
+
+
+if "pytest" in sys.modules:
+ import pytest
+
+ from ansiblelint.rules import RulesCollection # pylint: disable=ungrouped-imports
+ from ansiblelint.runner import Runner # pylint: disable=ungrouped-imports
+
+ @pytest.mark.parametrize(
+ ("test_file", "failures"),
+ (
+ pytest.param(
+ "examples/playbooks/rule_literal_compare_fail.yml",
+ 3,
+ id="fail",
+ ),
+ pytest.param(
+ "examples/playbooks/rule_literal_compare_pass.yml",
+ 0,
+ id="pass",
+ ),
+ ),
+ )
+ def test_literal_compare(
+ default_rules_collection: RulesCollection,
+ test_file: str,
+ failures: int,
+ ) -> None:
+ """Test rule matches."""
+ # Enable checking of loop variable prefixes in roles
+ results = Runner(test_file, rules=default_rules_collection).run()
+ for result in results:
+ assert result.rule.id == "literal-compare"
+ assert len(results) == failures