diff --git a/changelogs/fragments/45475_galaxy.yml b/changelogs/fragments/45475_galaxy.yml new file mode 100644 index 00000000000..72eab141a47 --- /dev/null +++ b/changelogs/fragments/45475_galaxy.yml @@ -0,0 +1,2 @@ +bugfixes: +- galaxy - handle plus sign in user token appearing in role url (https://github.com/ansible/ansible/issues/45475). diff --git a/docs/docsite/rst/galaxy/user_guide.rst b/docs/docsite/rst/galaxy/user_guide.rst index 417138a12aa..039ec78a1b7 100644 --- a/docs/docsite/rst/galaxy/user_guide.rst +++ b/docs/docsite/rst/galaxy/user_guide.rst @@ -226,7 +226,7 @@ To install a specific version of a role from Galaxy, append a comma and the valu .. code-block:: bash - $ ansible-galaxy install geerlingguy.apache,v1.0.0 + $ ansible-galaxy install geerlingguy.apache,1.0.0 It is also possible to point directly to the git repository and specify a branch name or commit hash as the version. For example, the following will install a specific commit: diff --git a/lib/ansible/playbook/role/requirement.py b/lib/ansible/playbook/role/requirement.py index 18cea8ff0ef..59e9cf39579 100644 --- a/lib/ansible/playbook/role/requirement.py +++ b/lib/ansible/playbook/role/requirement.py @@ -105,9 +105,7 @@ class RoleRequirement(RoleDefinition): role["src"] = "git+" + role["src"] if '+' in role["src"]: - (scm, src) = role["src"].split('+') - role["scm"] = scm - role["src"] = src + role["scm"], dummy, role["src"] = role["src"].partition('+') if 'name' not in role: role["name"] = RoleRequirement.repo_url_to_role_name(role["src"]) diff --git a/test/units/galaxy/test_role_requirements.py b/test/units/galaxy/test_role_requirements.py new file mode 100644 index 00000000000..a84bbb52eda --- /dev/null +++ b/test/units/galaxy/test_role_requirements.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Copyright: (c) 2020, Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +import pytest +from ansible.playbook.role.requirement import RoleRequirement + + +def test_null_role_url(): + role = RoleRequirement.role_yaml_parse('') + assert role['src'] == '' + assert role['name'] == '' + assert role['scm'] is None + assert role['version'] is None + + +def test_git_file_role_url(): + role = RoleRequirement.role_yaml_parse('git+file:///home/bennojoy/nginx') + assert role['src'] == 'file:///home/bennojoy/nginx' + assert role['name'] == 'nginx' + assert role['scm'] == 'git' + assert role['version'] is None + + +def test_https_role_url(): + role = RoleRequirement.role_yaml_parse('https://github.com/bennojoy/nginx') + assert role['src'] == 'https://github.com/bennojoy/nginx' + assert role['name'] == 'nginx' + assert role['scm'] is None + assert role['version'] is None + + +def test_git_https_role_url(): + role = RoleRequirement.role_yaml_parse('git+https://github.com/geerlingguy/ansible-role-composer.git') + assert role['src'] == 'https://github.com/geerlingguy/ansible-role-composer.git' + assert role['name'] == 'ansible-role-composer' + assert role['scm'] == 'git' + assert role['version'] is None + + +def test_git_version_role_url(): + role = RoleRequirement.role_yaml_parse('git+https://github.com/geerlingguy/ansible-role-composer.git,main') + assert role['src'] == 'https://github.com/geerlingguy/ansible-role-composer.git' + assert role['name'] == 'ansible-role-composer' + assert role['scm'] == 'git' + assert role['version'] == 'main' + + +@pytest.mark.parametrize("url", [ + ('https://some.webserver.example.com/files/main.tar.gz'), + ('https://some.webserver.example.com/files/main.tar.bz2'), + ('https://some.webserver.example.com/files/main.tar.xz'), +]) +def test_tar_role_url(url): + role = RoleRequirement.role_yaml_parse(url) + assert role['src'] == url + assert role['name'].startswith('main') + assert role['scm'] is None + assert role['version'] is None + + +def test_git_ssh_role_url(): + role = RoleRequirement.role_yaml_parse('git@gitlab.company.com:mygroup/ansible-base.git') + assert role['src'] == 'git@gitlab.company.com:mygroup/ansible-base.git' + assert role['name'].startswith('ansible-base') + assert role['scm'] is None + assert role['version'] is None + + +def test_token_role_url(): + role = RoleRequirement.role_yaml_parse('git+https://gitlab+deploy-token-312644:_aJQ9c3HWzmRR4knBNyx@gitlab.com/akasurde/ansible-demo') + assert role['src'] == 'https://gitlab+deploy-token-312644:_aJQ9c3HWzmRR4knBNyx@gitlab.com/akasurde/ansible-demo' + assert role['name'].startswith('ansible-demo') + assert role['scm'] == 'git' + assert role['version'] is None + + +def test_token_new_style_role_url(): + role = RoleRequirement.role_yaml_parse({"src": "git+https://gitlab+deploy-token-312644:_aJQ9c3HWzmRR4knBNyx@gitlab.com/akasurde/ansible-demo"}) + assert role['src'] == 'https://gitlab+deploy-token-312644:_aJQ9c3HWzmRR4knBNyx@gitlab.com/akasurde/ansible-demo' + assert role['name'].startswith('ansible-demo') + assert role['scm'] == 'git' + assert role['version'] == ''