Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid role-name errors with galaxy roles #1321

Merged
merged 1 commit into from Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ansiblelint/_internal/rules.py
Expand Up @@ -35,6 +35,8 @@ def getmatches(self, file: "Lintable") -> List["MatchError"]:
method,
e,
)
else:
matches.extend(self.matchdir(file))
return matches

def matchlines(self, file: "Lintable") -> List["MatchError"]:
Expand All @@ -59,6 +61,10 @@ def matchplay(
"""Return matches found for a specific playbook."""
return []

def matchdir(self, lintable: "Lintable") -> List["MatchError"]:
"""Return matches for lintable folders."""
return []

def verbose(self) -> str:
"""Return a verbose representation of the rule."""
return self.id + ": " + self.shortdesc + "\n " + self.description
Expand Down
52 changes: 32 additions & 20 deletions src/ansiblelint/rules/RoleNames.py
Expand Up @@ -56,29 +56,41 @@ def __init__(self) -> None:
"""Save precompiled regex."""
self._re = re.compile(ROLE_NAME_REGEX)

def matchdir(self, lintable: "Lintable") -> List["MatchError"]:
return self.matchyaml(lintable)

def matchyaml(self, file: Lintable) -> List["MatchError"]:
result: List["MatchError"] = []
path = str(file.path).split("/")
if "tasks" in path:
role_name = _remove_prefix(path[path.index("tasks") - 1], "ansible-role-")
role_root = path[: path.index("tasks")]
meta = Path("/".join(role_root)) / "meta" / "main.yml"

if meta.is_file():
meta_data = parse_yaml_from_file(str(meta))
if meta_data:
try:
role_name = meta_data['galaxy_info']['role_name']
except KeyError:
pass
if file.kind not in ('meta', 'role'):
return result
if file.kind == 'role':
role_name = self._infer_role_name(
meta=file.path / "meta" / "main.yml", default=file.path.name
)
else:
role_name = self._infer_role_name(
meta=file.path, default=file.path.resolve().parents[1].name
)

if role_name not in self.done:
self.done.append(role_name)
if not self._re.match(role_name):
result.append(
self.create_matcherror(
filename=str(file.path),
message=self.__class__.shortdesc.format(role_name),
)
role_name = _remove_prefix(role_name, "ansible-role-")
if role_name not in self.done:
self.done.append(role_name)
if not self._re.match(role_name):
result.append(
self.create_matcherror(
filename=str(file.path),
message=self.__class__.shortdesc.format(role_name),
)
)
return result

def _infer_role_name(self, meta: Path, default: str) -> str:
if meta.is_file():
meta_data = parse_yaml_from_file(str(meta))
if meta_data:
try:
return str(meta_data['galaxy_info']['role_name'])
except KeyError:
pass
return default
2 changes: 1 addition & 1 deletion test/TestDependenciesInMeta.py
Expand Up @@ -2,7 +2,7 @@


def test_external_dependency_is_ok(default_rules_collection):
playbook_path = 'examples/roles/dependency-in-meta/meta/main.yml'.format_map(
playbook_path = 'examples/roles/dependency_in_meta/meta/main.yml'.format_map(
locals()
)
good_runner = Runner(playbook_path, rules=default_rules_collection)
Expand Down