diff --git a/changelogs/fragments/81901-galaxy-requirements-format.yml b/changelogs/fragments/81901-galaxy-requirements-format.yml new file mode 100644 index 00000000000..2e57a955503 --- /dev/null +++ b/changelogs/fragments/81901-galaxy-requirements-format.yml @@ -0,0 +1,2 @@ +bugfixes: +- ansible-galaxy - Provide a better error message when using a requirements file with an invalid format - https://github.com/ansible/ansible/issues/81901 diff --git a/lib/ansible/cli/galaxy.py b/lib/ansible/cli/galaxy.py index 65dd8aa4ff6..9ceef136d00 100755 --- a/lib/ansible/cli/galaxy.py +++ b/lib/ansible/cli/galaxy.py @@ -835,7 +835,7 @@ class GalaxyCLI(CLI): for role_req in file_requirements: requirements['roles'] += parse_role_req(role_req) - else: + elif isinstance(file_requirements, dict): # Newer format with a collections and/or roles key extra_keys = set(file_requirements.keys()).difference(set(['roles', 'collections'])) if extra_keys: @@ -854,6 +854,9 @@ class GalaxyCLI(CLI): for collection_req in file_requirements.get('collections') or [] ] + else: + raise AnsibleError(f"Expecting requirements yaml to be a list or dictionary but got {type(file_requirements).__name__}") + return requirements def _init_coll_req_dict(self, coll_req): diff --git a/test/units/cli/test_galaxy.py b/test/units/cli/test_galaxy.py index f783abb9b95..80a2dfae25f 100644 --- a/test/units/cli/test_galaxy.py +++ b/test/units/cli/test_galaxy.py @@ -771,6 +771,20 @@ def test_collection_install_with_names(collection_install): assert mock_install.call_args[0][6] is False # force_deps +def test_collection_install_with_invalid_requirements_format(collection_install): + output_dir = collection_install[2] + + requirements_file = os.path.join(output_dir, 'requirements.yml') + with open(requirements_file, 'wb') as req_obj: + req_obj.write(b'"invalid"') + + galaxy_args = ['ansible-galaxy', 'collection', 'install', '--requirements-file', requirements_file, + '--collections-path', output_dir] + + with pytest.raises(AnsibleError, match="Expecting requirements yaml to be a list or dictionary but got str"): + GalaxyCLI(args=galaxy_args).run() + + def test_collection_install_with_requirements_file(collection_install): mock_install, mock_warning, output_dir = collection_install