Skip to content

Commit

Permalink
Avoid galaxy install failure with already symlinked collections (#166)
Browse files Browse the repository at this point in the history
* Avoid galaxy install failure with already symlinked collections

Fixes: #165

* chore: auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
ssbarnea and pre-commit-ci[bot] committed Sep 23, 2022
1 parent a986b49 commit eb771f5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
19 changes: 19 additions & 0 deletions src/ansible_compat/loaders.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
"""Utilities for loading various files."""
from __future__ import annotations

import os
from typing import Any

import yaml

from ansible_compat.errors import InvalidPrerequisiteError


def yaml_from_file(filepath: str) -> Any:
"""Return a loaded YAML file."""
with open(filepath, encoding="utf-8") as content:
return yaml.load(content, Loader=yaml.FullLoader)


def colpath_from_path(filepath: str) -> str | None:
"""Return a FQCN from a path."""
galaxy_file = f"{filepath}/galaxy.yml"
if os.path.exists(galaxy_file):
galaxy = yaml_from_file(galaxy_file)
for k in ("namespace", "name"):
if k not in galaxy:
raise InvalidPrerequisiteError(
f"{galaxy_file} is missing the following mandatory field {k}"
)
return f"{galaxy['namespace']}/{galaxy['name']}"
return None
19 changes: 17 additions & 2 deletions src/ansible_compat/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
InvalidPrerequisiteError,
MissingAnsibleError,
)
from ansible_compat.loaders import yaml_from_file
from ansible_compat.loaders import colpath_from_path, yaml_from_file
from ansible_compat.prerun import get_cache_dir

if TYPE_CHECKING:
Expand Down Expand Up @@ -315,7 +315,7 @@ def install_requirements(self, requirement: str, retry: bool = False) -> None:
_logger.error(run.stdout)
raise AnsibleCommandError(run)

def prepare_environment(
def prepare_environment( # noqa: C901
self,
required_collections: Optional[Dict[str, str]] = None,
retry: bool = False,
Expand Down Expand Up @@ -352,6 +352,21 @@ def prepare_environment(
return

if os.path.exists("galaxy.yml"):
if destination:
# while function can return None, that would not break the logic
colpath = f"{destination}/ansible_collections/{colpath_from_path(os.getcwd())}"
if os.path.islink(colpath):
if os.path.realpath(colpath) == os.getcwd():
_logger.warning(
"Found symlinked collection, skipping its installation."
)
return
_logger.warning(
"Collection is symlinked, but not pointing to %s directory, so we will remove it.",
os.getcwd(),
)
os.unlink(colpath)

# molecule scenario within a collection
self.install_collection_from_disk(".", destination=destination)
elif pathlib.Path().resolve().parent.name == "roles" and os.path.exists(
Expand Down
21 changes: 12 additions & 9 deletions test/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,16 +643,19 @@ def test_install_collection_from_disk_fail() -> None:
"""Tests that we fail to install a broken collection."""
with remember_cwd("test/collections/acme.broken"):
runtime = Runtime(isolated=True)
exception: Type[Exception]
if runtime.version_in_range(upper="2.11"):
exception = AnsibleCommandError
msg = "Got 1 exit code while running: ansible-galaxy collection build"
else:
exception = InvalidPrerequisiteError
msg = "is missing the following mandatory"
with pytest.raises(exception, match=msg):
# this should call install_collection_from_disk(".")
with pytest.raises(RuntimeError) as exc_info:
runtime.prepare_environment(install_local=True)
# based on version of Ansible used, we might get a different error,
# but both errors should be considered acceptable
assert exc_info.type in (
RuntimeError,
AnsibleCompatError,
AnsibleCommandError,
InvalidPrerequisiteError,
)
assert exc_info.match(
"(is missing the following mandatory|Got 1 exit code while running: ansible-galaxy collection build)"
)


def test_prepare_environment_offline_role() -> None:
Expand Down

0 comments on commit eb771f5

Please sign in to comment.