Skip to content

Commit af45514

Browse files
authored
Add site-package to the end of inclusion path (#470)
Fixes: #469
1 parent 0af2b60 commit af45514

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

src/ansible_compat/runtime.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ def _patch_collection_paths(self) -> None:
270270
ansible-core and ade behavior and trick ansible-galaxy to install
271271
default to the venv site-packages location (isolation).
272272
"""
273+
# ansible-core normal precedence is: adjacent, local paths, configured paths, site paths
273274
collections_paths: list[str] = self.config.collections_paths.copy()
274275
if self.config.collections_scan_sys_path:
275276
for path in sys.path:
@@ -280,15 +281,13 @@ def _patch_collection_paths(self) -> None:
280281
collections_paths.append( # pylint: disable=E1101
281282
path,
282283
)
283-
# When inside a venv, we also add the site-packages to the top of the
284-
# collections path because this is the first place where ansible-core
284+
# When inside a venv, we also add the site-packages to the end of the
285+
# collections path because this is the last place where ansible-core
285286
# will look for them. This also ensures that when calling ansible-galaxy
286-
# to install content, it will be installed in the venv site-packages instead
287-
# of altering the user configuration. Matches behavior of ADE and
288-
# ensures isolation.
287+
# to install content.
289288
for path in reversed(site.getsitepackages()):
290289
if path not in collections_paths:
291-
collections_paths.insert(0, path)
290+
collections_paths.append(path)
292291

293292
if collections_paths != self.config.collections_paths:
294293
_logger.info(

test/test_runtime_scan_path.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Test the scan path functionality of the runtime."""
22

33
import json
4+
import os
5+
import subprocess
46
import textwrap
57
from pathlib import Path
68

@@ -93,3 +95,31 @@ def test_scan_sys_path(
9395
assert result["collection_path"] == str(installed_to)
9496

9597
runtime_tmp.clean()
98+
99+
100+
def test_ro_venv() -> None:
101+
"""Tests behavior when the virtual environment is read-only.
102+
103+
See Related https://github.com/ansible/ansible-compat/pull/470
104+
"""
105+
tox_work_dir = os.environ.get("TOX_WORK_DIR", ".tox")
106+
venv_path = f"{tox_work_dir}/ro"
107+
commands = [
108+
f"mkdir -p {venv_path}",
109+
f"chmod -R a+w {venv_path}",
110+
f"python -m venv --symlinks {venv_path}",
111+
f"{venv_path}/bin/python -m pip install -q -e .",
112+
f"chmod -R a-w {venv_path}",
113+
f"{venv_path}/bin/python -c \"from ansible_compat.runtime import Runtime; r = Runtime(); r.install_collection('ansible.posix:>=2.0.0')\"",
114+
]
115+
for cmd in commands:
116+
result = subprocess.run( # noqa: S602
117+
cmd,
118+
check=False,
119+
shell=True,
120+
text=True,
121+
capture_output=True,
122+
)
123+
assert (
124+
result.returncode == 0
125+
), f"Got {result.returncode} running {cmd}\n\tstderr: {result.stderr}\n\tstdout: {result.stdout}"

0 commit comments

Comments
 (0)