diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 91ff7b4..cb9d274 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -144,3 +144,5 @@ description: Run ansible-lint with Polymath settings entry: polymath_code_standard ansible types: [file] + # Each process installs ansible/requirements.yml into the same cache, so all files go to one process. + require_serial: true diff --git a/CHANGELOG.md b/CHANGELOG.md index fb27f03..b99bcf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project are documented in this file. Releases follow semantic versioning as described in [DEVELOPING.md](./DEVELOPING.md). +## 2.7.1 + +### Fixed + +- `polymath-ansible` resolves collections that the repo develops under `ansible/collections/`. + Since 2.3.0 only the `.polymath-ansible/` cache was on the collections path. + Syntax-check reported the repo's own roles and playbooks as not found, unless the playbook sat beside a `collections/` directory. +- `polymath-ansible` runs as a single process. + Under `--all-files`, parallel runs installed `ansible/requirements.yml` into the same cache at once and failed with "Directory not empty". + ## 2.7.0 Minor bump: a new check in `polymath-general`. diff --git a/README.md b/README.md index 01a5afd..c184ed1 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Use only the hooks that apply to your project. --- repos: - repo: https://github.com/polymathrobotics/polymath_code_standard - rev: v2.7.0 + rev: v2.7.1 hooks: # File hygiene for all staged files - id: polymath-general @@ -330,6 +330,7 @@ No arguments. Installs Ansible collections and roles from `ansible/requirements.yml` and runs `ansible-lint` with Polymath's configuration. Dependencies are cached in `.polymath-ansible/` (automatically gitignored) and only reinstalled when `requirements.yml` changes. +Collections the repo develops itself under `ansible/collections/` resolve from the working tree. No arguments. diff --git a/polymath_code_standard/checkers/ansible/__init__.py b/polymath_code_standard/checkers/ansible/__init__.py index 2900ffb..ad05e45 100644 --- a/polymath_code_standard/checkers/ansible/__init__.py +++ b/polymath_code_standard/checkers/ansible/__init__.py @@ -4,6 +4,7 @@ import hashlib import importlib.resources import json +import os from pathlib import Path import yaml @@ -13,6 +14,9 @@ # Config files bundled alongside this checker CONFIG_DIR = importlib.resources.files(__package__) +# Where a repo keeps the collections it develops itself, so its playbooks resolve them from the working tree. +REPO_COLLECTIONS_DIR = Path('ansible/collections') + # Where a repo declares the collections and roles its playbooks import. REQUIREMENTS = Path('ansible/requirements.yml') @@ -67,7 +71,7 @@ def run(self, args: argparse.Namespace) -> list[Result]: args.files, name='ansible-lint', env={ - 'ANSIBLE_COLLECTIONS_PATH': str(COLLECTIONS_DIR), + 'ANSIBLE_COLLECTIONS_PATH': os.pathsep.join([str(REPO_COLLECTIONS_DIR), str(COLLECTIONS_DIR)]), 'ANSIBLE_ROLES_PATH': str(ROLES_DIR), }, ) diff --git a/pyproject.toml b/pyproject.toml index 9e175ea..0a925c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "polymath-code-standard" -version = "2.7.0" +version = "2.7.1" description = "Polymath Code Standard pre-commit hooks" requires-python = ">=3.10" dependencies = [ diff --git a/tests/test_ansible.py b/tests/test_ansible.py index 20fd0e7..413e6f2 100644 --- a/tests/test_ansible.py +++ b/tests/test_ansible.py @@ -58,6 +58,22 @@ def test_ansible_installs_requirements(tmp_path, monkeypatch): assert ansible_checker.AnsibleGroup._install_requirements() == [] +def test_ansible_resolves_repo_collection(tmp_path, monkeypatch): + """A playbook resolves a collection the repo develops under ansible/collections.""" + role = tmp_path / 'ansible' / 'collections' / 'ansible_collections' / 'acme' / 'local' / 'roles' / 'greet' + (role / 'tasks').mkdir(parents=True) + (role / 'tasks' / 'main.yml').write_text('---\n- name: Greet\n ansible.builtin.debug:\n msg: hello\n') + # Ansible finds a collections/ directory beside the playbook by itself, so nest the playbook away from it. + scenario = tmp_path / 'ansible' / 'scenarios' / 'greet' + scenario.mkdir(parents=True) + (scenario / 'converge.yml').write_text( + '---\n- name: Greet some computer\n hosts: all\n roles:\n - role: acme.local.greet\n' + ) + monkeypatch.chdir(tmp_path) + + assert runner.main(['ansible', 'ansible/scenarios/greet/converge.yml']) == 0 + + def test_ansible_stamp_tracks_requirements(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) (tmp_path / 'ansible').mkdir() diff --git a/uv.lock b/uv.lock index d6244ed..7e3bcd0 100644 --- a/uv.lock +++ b/uv.lock @@ -829,7 +829,7 @@ wheels = [ [[package]] name = "polymath-code-standard" -version = "2.7.0" +version = "2.7.1" source = { editable = "." } dependencies = [ { name = "ansible-lint" },