Skip to content

Commit 34c1459

Browse files
authored
Improve requirements.yml detection (#275)
Gives explicit error message about invalid requirements.yml files, especially as an unsupported format was used during the 2020 split. Closes: #274 Related: ansible-community/community-topics#230
1 parent 18aae33 commit 34c1459

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
roles: []
2+
collections: []
3+
integration_tests_dependencies: [] # <-- invalid key
4+
unit_tests_dependencies: [] # <-- invalid key

src/ansible_compat/constants.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
"""Constants used by ansible_compat."""
22

33

4+
REQUIREMENT_LOCATIONS = [
5+
"requirements.yml",
6+
"roles/requirements.yml",
7+
"collections/requirements.yml",
8+
# These is more of less the official way to store test requirements in collections so far, comments shows number of repos using this reported by https://sourcegraph.com/ at the time of writing
9+
"tests/requirements.yml", # 170
10+
"tests/integration/requirements.yml", # 3
11+
"tests/unit/requirements.yml", # 1
12+
]
13+
414
# Minimal version of Ansible we support for runtime
515
ANSIBLE_MIN_VERSION = "2.12"
616

src/ansible_compat/runtime.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
ansible_collections_path,
2323
parse_ansible_version,
2424
)
25-
from ansible_compat.constants import MSG_INVALID_FQRL, RC_ANSIBLE_OPTIONS_ERROR
25+
from ansible_compat.constants import (
26+
MSG_INVALID_FQRL,
27+
RC_ANSIBLE_OPTIONS_ERROR,
28+
REQUIREMENT_LOCATIONS,
29+
)
2630
from ansible_compat.errors import (
2731
AnsibleCommandError,
2832
AnsibleCompatError,
@@ -411,6 +415,12 @@ def install_requirements( # noqa: C901
411415
msg = f"{requirement} file is not a valid Ansible requirements file."
412416
raise InvalidPrerequisiteError(msg)
413417

418+
if isinstance(reqs_yaml, dict):
419+
for key in reqs_yaml:
420+
if key not in ("roles", "collections"):
421+
msg = f"{requirement} file is not a valid Ansible requirements file. Only 'roles' and 'collections' keys are allowed at root level. Recognized valid locations are: {', '.join(REQUIREMENT_LOCATIONS)}"
422+
raise InvalidPrerequisiteError(msg)
423+
414424
if isinstance(reqs_yaml, list) or "roles" in reqs_yaml:
415425
cmd = [
416426
"ansible-galaxy",
@@ -485,13 +495,7 @@ def prepare_environment( # noqa: C901
485495
# are part of Tower specification
486496
# https://docs.ansible.com/ansible-tower/latest/html/userguide/projects.html#ansible-galaxy-support
487497
# https://docs.ansible.com/ansible-tower/latest/html/userguide/projects.html#collections-support
488-
for req_file in [
489-
"requirements.yml",
490-
"roles/requirements.yml",
491-
"collections/requirements.yml",
492-
# These is more of less the official way to store test requirements in collections so far:
493-
"tests/requirements.yml",
494-
]:
498+
for req_file in REQUIREMENT_LOCATIONS:
495499
self.install_requirements(Path(req_file), retry=retry, offline=offline)
496500

497501
galaxy_path = Path("galaxy.yml")

test/test_runtime.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ def test_prerun_reqs_v2(caplog: pytest.LogCaptureFixture, runtime: Runtime) -> N
258258
)
259259

260260

261+
def test_prerun_reqs_broken(runtime: Runtime) -> None:
262+
"""Checks that the we report invalid requirements.yml file."""
263+
path = (Path(__file__).parent.parent / "examples" / "reqs_broken").resolve()
264+
with cwd(path), pytest.raises(InvalidPrerequisiteError):
265+
runtime.prepare_environment()
266+
267+
261268
def test__update_env_no_old_value_no_default_no_value(monkeypatch: MonkeyPatch) -> None:
262269
"""Make sure empty value does not touch environment."""
263270
monkeypatch.delenv("DUMMY_VAR", raising=False)

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ setenv =
6868
PIP_DISABLE_PIP_VERSION_CHECK = 1
6969
PIP_CONSTRAINT = {toxinidir}/requirements.txt
7070
PRE_COMMIT_COLOR = always
71-
PYTEST_REQPASS = 80
71+
PYTEST_REQPASS = 81
7272
FORCE_COLOR = 1
7373
allowlist_externals =
7474
ansible

0 commit comments

Comments
 (0)