diff --git a/.vscode/settings.json b/.vscode/settings.json index a4369f34..9e5c799b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "source.fixAll": "explicit", "source.organizeImports": "explicit" }, - "editor.defaultFormatter": "ms-python.black-formatter", + "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true }, "editor.formatOnSave": true, @@ -40,5 +40,6 @@ "yaml.completion": true, "yaml.customTags": ["!encrypted/pkcs1-oaep scalar", "!vault scalar"], "yaml.format.enable": false, - "yaml.validate": true + "yaml.validate": true, + "cSpell.words": ["delenv"] } diff --git a/src/ansible_compat/prerun.py b/src/ansible_compat/prerun.py index 9448269d..36869f37 100644 --- a/src/ansible_compat/prerun.py +++ b/src/ansible_compat/prerun.py @@ -1,22 +1,22 @@ """Utilities for configuring ansible runtime environment.""" -import hashlib import os from pathlib import Path -def get_cache_dir(project_dir: Path) -> Path: - """Compute cache directory to be used based on project path.""" - # we only use the basename instead of the full path in order to ensure that - # we would use the same key regardless the location of the user home - # directory or where the project is clones (as long the project folder uses - # the same name). - basename = project_dir.resolve().name.encode(encoding="utf-8") - # 6 chars of entropy should be enough - cache_key = hashlib.sha256(basename).hexdigest()[:6] - cache_dir = ( - Path(os.getenv("XDG_CACHE_HOME", "~/.cache")).expanduser() - / "ansible-compat" - / cache_key - ) +def get_cache_dir(project_dir: Path, *, isolated: bool = True) -> Path: + """Compute cache directory to be used based on project path. + + Returns: + Cache directory path. + """ + if "VIRTUAL_ENV" in os.environ: + cache_dir = Path(os.environ["VIRTUAL_ENV"]) / ".ansible" + elif isolated: + cache_dir = project_dir / ".ansible" + else: + cache_dir = ( + Path(os.environ.get("ANSIBLE_HOME", "~/.ansible")).expanduser() / ".ansible" + ) + return cache_dir diff --git a/src/ansible_compat/runtime.py b/src/ansible_compat/runtime.py index ca35e021..f58e3d58 100644 --- a/src/ansible_compat/runtime.py +++ b/src/ansible_compat/runtime.py @@ -208,8 +208,8 @@ def __init__( if "PYTHONWARNINGS" not in self.environ: # pragma: no cover self.environ["PYTHONWARNINGS"] = "ignore:Blowfish has been deprecated" - if isolated: - self.cache_dir = get_cache_dir(self.project_dir) + self.cache_dir = get_cache_dir(self.project_dir, isolated=self.isolated) + self.config = AnsibleConfig(cache_dir=self.cache_dir) # Add the sys.path to the collection paths if not isolated diff --git a/test/test_prerun.py b/test/test_prerun.py index d8320884..2ec3a791 100644 --- a/test/test_prerun.py +++ b/test/test_prerun.py @@ -1,6 +1,12 @@ """Tests for ansible_compat.prerun module.""" +from __future__ import annotations + from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from _pytest.monkeypatch import MonkeyPatch from ansible_compat.prerun import get_cache_dir @@ -10,3 +16,9 @@ def test_get_cache_dir_relative() -> None: relative_path = Path() abs_path = relative_path.resolve() assert get_cache_dir(relative_path) == get_cache_dir(abs_path) + + +def test_get_cache_dir_no_isolation_no_venv(monkeypatch: MonkeyPatch) -> None: + """Test behaviors of get_cache_dir.""" + monkeypatch.delenv("VIRTUAL_ENV", raising=False) + assert get_cache_dir(Path(), isolated=False) == Path("~/.ansible").expanduser() diff --git a/test/test_runtime.py b/test/test_runtime.py index b665f3ed..19756dfa 100644 --- a/test/test_runtime.py +++ b/test/test_runtime.py @@ -652,10 +652,9 @@ def test_upgrade_collection(runtime_tmp: Runtime) -> None: runtime_tmp.require_collection("community.molecule", "0.1.0") -def test_require_collection_no_cache_dir() -> None: +def test_require_collection_not_isolated() -> None: """Check require_collection without a cache directory.""" - runtime = Runtime() - assert not runtime.cache_dir + runtime = Runtime(isolated=False) runtime.require_collection("community.molecule", "0.1.0", install=True) @@ -1022,6 +1021,11 @@ def test_runtime_has_playbook() -> None: """Tests has_playbook method.""" runtime = Runtime(require_module=True) + runtime.prepare_environment( + required_collections={"community.molecule": "0.1.0"}, + install_local=True, + ) + assert not runtime.has_playbook("this-does-not-exist.yml") # call twice to ensure cache is used: assert not runtime.has_playbook("this-does-not-exist.yml")