summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/rules/role_name.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansiblelint/rules/role_name.py')
-rw-r--r--src/ansiblelint/rules/role_name.py69
1 files changed, 66 insertions, 3 deletions
diff --git a/src/ansiblelint/rules/role_name.py b/src/ansiblelint/rules/role_name.py
index 499c086..ebe0b1a 100644
--- a/src/ansiblelint/rules/role_name.py
+++ b/src/ansiblelint/rules/role_name.py
@@ -1,4 +1,5 @@
"""Implementation of role-name rule."""
+
# Copyright (c) 2020 Gael Chamoulaud <gchamoul@redhat.com>
# Copyright (c) 2020 Sorin Sbarnea <ssbarnea@redhat.com>
#
@@ -94,6 +95,26 @@ class RoleNames(AnsibleLintRule):
if file.kind not in ("meta", "role", "playbook"):
return result
+ if file.kind == "meta":
+ for role in file.data.get("dependencies", []):
+ if isinstance(role, dict):
+ role_name = role["role"]
+ elif isinstance(role, str):
+ role_name = role
+ else:
+ msg = "Role dependency has unexpected type."
+ raise TypeError(msg)
+ if "/" in role_name:
+ result.append(
+ self.create_matcherror(
+ f"Avoid using paths when importing roles. ({role_name})",
+ filename=file,
+ lineno=role_name.ansible_pos[1],
+ tag=f"{self.id}[path]",
+ ),
+ )
+ return result
+
if file.kind == "playbook":
for play in file.data:
if "roles" in play:
@@ -143,7 +164,7 @@ class RoleNames(AnsibleLintRule):
if meta_data:
try:
return str(meta_data["galaxy_info"]["role_name"])
- except KeyError:
+ except (KeyError, TypeError):
pass
return default
@@ -151,8 +172,9 @@ class RoleNames(AnsibleLintRule):
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
+ # pylint: disable=ungrouped-imports
+ from ansiblelint.rules import RulesCollection
+ from ansiblelint.runner import Runner
@pytest.mark.parametrize(
("test_file", "failure"),
@@ -168,3 +190,44 @@ if "pytest" in sys.modules:
for result in results:
assert result.tag == "role-name[path]"
assert len(results) == failure
+
+ @pytest.mark.parametrize(
+ ("test_file", "failure"),
+ (pytest.param("examples/roles/role_with_deps_paths", 3, id="fail"),),
+ )
+ def test_role_deps_path_names(
+ default_rules_collection: RulesCollection,
+ test_file: str,
+ failure: int,
+ ) -> None:
+ """Test rule matches."""
+ results = Runner(
+ test_file,
+ rules=default_rules_collection,
+ ).run()
+ expected_errors = (
+ ("role-name[path]", 3),
+ ("role-name[path]", 9),
+ ("role-name[path]", 10),
+ )
+ assert len(expected_errors) == failure
+ for idx, result in enumerate(results):
+ assert result.tag == expected_errors[idx][0]
+ assert result.lineno == expected_errors[idx][1]
+ assert len(results) == failure
+
+ @pytest.mark.parametrize(
+ ("test_file", "failure"),
+ (pytest.param("examples/roles/test-no-deps-role", 0, id="no_deps"),),
+ )
+ def test_role_no_deps(
+ default_rules_collection: RulesCollection,
+ test_file: str,
+ failure: int,
+ ) -> None:
+ """Test role if no dependencies are present in meta/main.yml."""
+ results = Runner(
+ test_file,
+ rules=default_rules_collection,
+ ).run()
+ assert len(results) == failure