Skip to content

Commit

Permalink
Refactor install_galaxy_role
Browse files Browse the repository at this point in the history
  • Loading branch information
ssbarnea committed Jul 28, 2021
1 parent 00090fa commit d1dad46
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 18 deletions.
Empty file added galaxy.yml
Empty file.
47 changes: 31 additions & 16 deletions src/ansible_compat/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ def prepare_environment(
)

self._prepare_ansible_paths()
_install_galaxy_role(self.project_dir)
# install role if current project looks like a standalone role
_install_galaxy_role(self.project_dir, ignore_errors=True)

def require_collection( # noqa: C901
self,
Expand Down Expand Up @@ -335,22 +336,36 @@ def _prepare_ansible_paths(self) -> None:
)


def _install_galaxy_role(project_dir: str, role_name_check: int = 0) -> None:
def _install_galaxy_role(
project_dir: str, role_name_check: int = 0, ignore_errors: bool = False
) -> None:
"""Detect standalone galaxy role and installs it.
role_name_check levels:
0: exit with error if name is not compliant (default)
1: warn if name is not compliant
2: bypass any name checking
:param: role_name_check: logic to used to check role name
0: exit with error if name is not compliant (default)
1: warn if name is not compliant
2: bypass any name checking
:param: ignore_errors: if True, bypass installing invalid roles.
Our implementation aims to match ansible-galaxy's behaviour for installing
roles from a tarball or scm. For example ansible-galaxy will install a role
that has both galaxy.yml and meta/main.yml present but empty. Also missing
galaxy.yml is accepted but missing meta/main.yml is not.
"""
yaml = None
galaxy_info = {}
meta_filename = os.path.join(project_dir, 'meta', 'main.yml')
if not os.path.exists(meta_filename):
return
yaml = yaml_from_file(meta_filename)
if 'galaxy_info' not in yaml:
return

fqrn = _get_role_fqrn(yaml['galaxy_info'], project_dir)
if ignore_errors:
if not os.path.exists(meta_filename):
return
yaml = yaml_from_file(meta_filename)

if yaml and 'galaxy_info' in yaml:
galaxy_info = yaml['galaxy_info']

fqrn = _get_role_fqrn(galaxy_info, project_dir)

if role_name_check in [0, 1]:
if not re.match(r"[a-z0-9][a-z0-9_]+\.[a-z][a-z0-9_]+$", fqrn):
Expand All @@ -359,12 +374,12 @@ def _install_galaxy_role(project_dir: str, role_name_check: int = 0) -> None:
_logger.warning(msg)
else:
_logger.error(msg)
raise InvalidPrerequisiteError()
raise InvalidPrerequisiteError(msg)
else:
# when 'role-name' is in skip_list, we stick to plain role names
if 'role_name' in yaml['galaxy_info']:
role_namespace = _get_galaxy_role_ns(yaml['galaxy_info'])
role_name = _get_galaxy_role_name(yaml['galaxy_info'])
if 'role_name' in galaxy_info:
role_namespace = _get_galaxy_role_ns(galaxy_info)
role_name = _get_galaxy_role_name(galaxy_info)
fqrn = f"{role_namespace}{role_name}"
else:
fqrn = pathlib.Path(project_dir).absolute().name
Expand Down
14 changes: 13 additions & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Pytest fixtures."""
import pathlib
from typing import Generator

import pytest
Expand All @@ -9,7 +10,18 @@
@pytest.fixture
# pylint: disable=unused-argument
def runtime(scope: str = "session") -> Generator[Runtime, None, None]:
"""Runtime fixture."""
"""Isolated runtime fixture."""
instance = Runtime(isolated=True)
yield instance
instance.clean()


@pytest.fixture
# pylint: disable=unused-argument
def runtime_tmp(
tmp_path: pathlib.Path, scope: str = "session"
) -> Generator[Runtime, None, None]:
"""Isolated runtime fixture using a temp directory."""
instance = Runtime(project_dir=str(tmp_path), isolated=True)
yield instance
instance.clean()
21 changes: 20 additions & 1 deletion test/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
AnsibleCompatError,
InvalidPrerequisiteError,
)
from ansible_compat.runtime import CompletedProcess, Runtime, _update_env
from ansible_compat.runtime import (
CompletedProcess,
Runtime,
_install_galaxy_role,
_update_env,
)


def test_runtime_version(runtime: Runtime) -> None:
Expand Down Expand Up @@ -420,3 +425,17 @@ def test_install_collection_fail(runtime: Runtime) -> None:
runtime.install_collection("containers.podman:>=9999.0")
assert pytest_wrapped_e.type == InvalidPrerequisiteError
assert pytest_wrapped_e.value.code == INVALID_PREREQUISITES_RC


def test_install_galaxy_role(runtime_tmp: Runtime) -> None:
"""Check install role with empty galaxy file."""
pathlib.Path(f'{runtime_tmp.project_dir}/galaxy.yml').touch()
pathlib.Path(f'{runtime_tmp.project_dir}/meta').mkdir()
pathlib.Path(f'{runtime_tmp.project_dir}/meta/main.yml').touch()
# this should only raise a warning
_install_galaxy_role(runtime_tmp.project_dir, role_name_check=1)
# this should raise an error
with pytest.raises(
InvalidPrerequisiteError, match="does not follow current galaxy requirements"
):
_install_galaxy_role(runtime_tmp.project_dir, role_name_check=0)

0 comments on commit d1dad46

Please sign in to comment.