Skip to content

Commit

Permalink
Fix collection installation with custom project_dir (#343)
Browse files Browse the repository at this point in the history
- fix bug that disregarded passed project_dir and used cwd instead
- updated test dependencies
- fixed codecov config
  • Loading branch information
ssbarnea authored Dec 29, 2023
1 parent 443ae74 commit 2726e6b
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
TOX_PARALLEL_NO_SPINNER: 1

steps:
- name: Switch to using Python 3.9 by default
- name: Switch to using Python 3.12 by default
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: "3.12"
- name: Install tox
run: python3 -m pip install --user "tox>=4.0.0"
- name: Check out src from Git
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
with:
min_python: "3.9"
max_python: "3.12"
default_python: "3.10"
other_names: |
lint
docs
Expand All @@ -32,7 +33,10 @@ jobs:
py39-ansible213
py39-ansible214
py39-ansible215
py311-devel
py310-ansible215
py311-ansible215
py312-ansible216
py312-devel
smoke
platforms: linux,macos
macos: minmax
Expand Down
23 changes: 15 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ ci:
for more information, see https://pre-commit.ci
skip:
# https://github.com/pre-commit-ci/issues/issues/55
- ccv
- pip-compile
# No docker on pre-commit.ci
- validate-config-in-container
default_language_version:
# Needed in order to make pip-compile output predictable.
python: python3.9
python: python3.10
exclude: |
(?x)^(
test/assets/.*
)$
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.0.291"
rev: "v0.1.9"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand All @@ -35,7 +36,7 @@ repos:
- prettier-plugin-toml
- prettier-plugin-sort-json
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v4.4.0
rev: v4.5.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
Expand All @@ -51,23 +52,23 @@ repos:
- id: debug-statements
language_version: python3
- repo: https://github.com/codespell-project/codespell
rev: v2.2.5
rev: v2.2.6
hooks:
- id: codespell
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.32.0
rev: v1.33.0
hooks:
- id: yamllint
files: \.(yaml|yml)$
types: [file, yaml]
entry: yamllint --strict
- repo: https://github.com/psf/black
rev: 23.9.1
rev: 23.12.1
hooks:
- id: black
language_version: python3
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
rev: v1.8.0
hooks:
- id: mypy
# empty args needed in order to match mypy cli behavior
Expand All @@ -84,7 +85,7 @@ repos:
- types-pkg_resources
- types-jsonschema>=4.4.9
- repo: https://github.com/pycqa/pylint
rev: v3.0.0b0
rev: v3.0.3
hooks:
- id: pylint
additional_dependencies:
Expand Down Expand Up @@ -117,4 +118,10 @@ repos:
rev: v1.2.0
hooks:
- id: validate-config-in-container
name: packit
alias: packit
- repo: https://github.com/mashi/codecov-validator
rev: "1.0.1"
hooks:
- id: ccv
name: codecov
6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
},
"[python]": {
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.ruff": false,
"source.organizeImports": false
"source.fixAll": "explicit",
"source.fixAll.ruff": "never",
"source.organizeImports": "never"
}
},
"editor.formatOnSave": true,
Expand Down
4 changes: 1 addition & 3 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@ codecov:
comment: false
coverage:
status:
patch: false
project:
threshold: 0.5%
patch: true # we want github annotations
21 changes: 7 additions & 14 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile --extra=docs --extra=test --output-file=requirements.txt --strip-extras --unsafe-package=ansible-core --unsafe-package=resolvelib --unsafe-package=typing_extensions pyproject.toml
Expand Down Expand Up @@ -68,7 +68,7 @@ defusedxml==0.7.1
# via
# cairosvg
# mkdocs-ansible
exceptiongroup==1.1.3
exceptiongroup==1.2.0
# via pytest
ghp-import==2.1.0
# via
Expand All @@ -87,14 +87,7 @@ idna==3.4
# mkdocs-ansible
# requests
importlib-metadata==6.8.0
# via
# build
# markdown
# mkdocs
# mkdocs-ansible
# mkdocstrings
importlib-resources==5.0.7
# via ansible-core
# via mkdocs-ansible
iniconfig==2.0.0
# via pytest
jinja2==3.1.2
Expand Down Expand Up @@ -147,7 +140,9 @@ mkdocs==1.5.3
# mkdocs-monorepo-plugin
# mkdocstrings
mkdocs-ansible==0.2.0
# via ansible-compat (pyproject.toml)
# via
# ansible-compat (pyproject.toml)
# mkdocs-ansible
mkdocs-autorefs==0.5.0
# via
# mkdocs-ansible
Expand Down Expand Up @@ -300,12 +295,10 @@ tomli==2.0.1
# pip-tools
# pyproject-hooks
# pytest
typing-extensions==4.8.0 ; python_version < "3.10"
typing-extensions==4.8.0
# via
# ansible-compat (pyproject.toml)
# black
# mkdocs-ansible
# mkdocstrings
urllib3==2.0.5
# via
# mkdocs-ansible
Expand Down
17 changes: 10 additions & 7 deletions src/ansible_compat/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def install_collection(
if isinstance(collection, Path):
collection = str(collection)
# As ansible-galaxy install is not able to automatically determine
# if the range requires a pre-release, we need to manuall add the --pre
# if the range requires a pre-release, we need to manually add the --pre
# flag when needed.
matches = version_re.search(collection)

Expand Down Expand Up @@ -614,14 +614,14 @@ def prepare_environment( # noqa: C901
destination=destination,
)

if Path("galaxy.yml").exists():
if (self.project_dir / "galaxy.yml").exists():
if destination:
# while function can return None, that would not break the logic
colpath = Path(
f"{destination}/ansible_collections/{colpath_from_path(Path.cwd())}",
f"{destination}/ansible_collections/{colpath_from_path(self.project_dir)}",
)
if colpath.is_symlink():
if os.path.realpath(colpath) == Path.cwd():
if os.path.realpath(colpath) == str(Path.cwd()):
_logger.warning(
"Found symlinked collection, skipping its installation.",
)
Expand Down Expand Up @@ -741,7 +741,7 @@ def _prepare_ansible_paths(self) -> None:
msg = "Unexpected ansible configuration"
raise RuntimeError(msg) from exc

alterations_list = [
alterations_list: list[tuple[list[str], str, bool]] = [
(library_paths, "plugins/modules", True),
(roles_path, "roles", True),
]
Expand All @@ -762,7 +762,7 @@ def _prepare_ansible_paths(self) -> None:
if must_be_present:
continue
path.mkdir(parents=True, exist_ok=True)
if path not in path_list:
if str(path) not in path_list:
path_list.insert(0, str(path))

if library_paths != self.config.DEFAULT_MODULE_PATH:
Expand Down Expand Up @@ -910,7 +910,10 @@ def _get_galaxy_role_ns(galaxy_infos: dict[str, Any]) -> str:

def _get_galaxy_role_name(galaxy_infos: dict[str, Any]) -> str:
"""Compute role name from meta/main.yml."""
return galaxy_infos.get("role_name", "")
result = galaxy_infos.get("role_name", "")
if not isinstance(result, str):
return ""
return result


def search_galaxy_paths(search_dir: Path) -> list[str]:
Expand Down
30 changes: 30 additions & 0 deletions test/collections/acme.minimal/galaxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: minimal
namespace: acme
version: 1.0.0
readme: README.md
authors:
- Red Hat
description: Sample collection to use with molecule
build_ignore:
- "*.egg-info"
- .DS_Store
- .eggs
- .gitignore
- .mypy_cache
- .pytest_cache
- .stestr
- .stestr.conf
- .tox
- .vscode
- MANIFEST.in
- build
- dist
- doc
- report.html
- setup.cfg
- setup.py
- "tests/unit/*.*"
- README.rst
- tox.ini

license_file: LICENSE
30 changes: 30 additions & 0 deletions test/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from ansible_compat.runtime import (
CompletedProcess,
Runtime,
_get_galaxy_role_name,
is_url,
search_galaxy_paths,
)
Expand Down Expand Up @@ -861,3 +862,32 @@ def test_galaxy_path(path: str, result: list[str]) -> None:
def test_is_url(name: str, result: bool) -> None:
"""Checks functionality of is_url."""
assert is_url(name) == result


def test_prepare_environment_repair_broken_symlink(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Ensure we can deal with broken symlinks in collections."""
caplog.set_level(logging.INFO)
project_dir = Path(__file__).parent / "collections" / "acme.minimal"
runtime = Runtime(isolated=True, project_dir=project_dir)
assert runtime.cache_dir
acme = runtime.cache_dir / "collections" / "ansible_collections" / "acme"
acme.mkdir(parents=True, exist_ok=True)
goodies = acme / "minimal"
rmtree(goodies, ignore_errors=True)
goodies.unlink(missing_ok=True)
goodies.symlink_to("/invalid/destination")
runtime.prepare_environment(install_local=True)
assert any(
msg.startswith("Collection is symlinked, but not pointing to")
for msg in caplog.messages
)


def test_get_galaxy_role_name_invalid() -> None:
"""Verifies that function returns empty string on invalid input."""
galaxy_infos = {
"role_name": False, # <-- invalid data, should be string
}
assert _get_galaxy_role_name(galaxy_infos) == ""
26 changes: 21 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@ envlist =
lint
pkg
docs
# matrix assumed current (implicit) is 2.13:
py{39,310,311}{,-devel,-ansible212,-ansible213,-ansible214,-ansible215}
py
py-devel
py39-ansible212
py39-ansible213
py39-ansible214
py39-ansible215
py310-ansible212
py310-ansible213
py310-ansible214
py310-ansible215
py311-ansible212
py311-ansible213
py311-ansible214
py311-ansible215
py312-ansible216

isolated_build = true
skip_missing_interpreters = True
requires =
Expand All @@ -14,18 +28,20 @@ requires =

[testenv]
description =
Run the tests with {basepython}
Run the tests
devel: ansible devel branch
ansible212: ansible-core 2.12
ansible213: ansible-core 2.13
ansible214: ansible-core 2.14
ansible215: ansible-core 2.15
ansible216: ansible-core 2.16

deps =
ansible212: ansible-core>=2.12,<2.13
ansible213: ansible-core>=2.13,<2.14
ansible214: ansible-core>=2.14,<2.15
ansible215: ansible-core>=2.15,<2.16
ansible216: ansible-core>=2.16,<2.17

devel: ansible-core @ git+https://github.com/ansible/ansible.git@c5d18c39d81e2b3b10856b2fb76747230e4fac4a # GPLv3+
# avoid installing ansible-core on -devel envs:
Expand Down Expand Up @@ -71,7 +87,7 @@ setenv =
PIP_DISABLE_PIP_VERSION_CHECK = 1
PIP_CONSTRAINT = {toxinidir}/requirements.txt
PRE_COMMIT_COLOR = always
PYTEST_REQPASS = 91
PYTEST_REQPASS = 93
FORCE_COLOR = 1
allowlist_externals =
ansible
Expand All @@ -83,7 +99,7 @@ package = editable
[testenv:lint]
description = Run all linters
# locked basepython is needed because to keep constrains.txt predictable
basepython = python3.9
basepython = python3.10
deps =
pre-commit>=2.6.0
skip_install = true
Expand Down

0 comments on commit 2726e6b

Please sign in to comment.