* Fix traceback installing collections from git repos if git is not installed
(cherry picked from commit 477c55b0d2)
This commit is contained in:
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Fix traceback when installing a collection from a git repository and git is not installed (https://github.com/ansible/ansible/issues/77479).
|
||||
@ -38,6 +38,7 @@ from ansible.galaxy import get_collections_galaxy_meta_info
|
||||
from ansible.galaxy.dependency_resolution.dataclasses import _GALAXY_YAML
|
||||
from ansible.galaxy.user_agent import user_agent
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.yaml import yaml_load
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError
|
||||
from ansible.module_utils.six.moves.urllib.parse import urldefrag
|
||||
@ -350,11 +351,19 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
|
||||
prefix=to_bytes(name, errors='surrogate_or_strict'),
|
||||
) # type: bytes
|
||||
|
||||
try:
|
||||
git_executable = get_bin_path('git')
|
||||
except ValueError as err:
|
||||
raise AnsibleError(
|
||||
"Could not find git executable to extract the collection from the Git repository `{repo_url!s}`.".
|
||||
format(repo_url=to_native(git_url))
|
||||
) from err
|
||||
|
||||
# Perform a shallow clone if simply cloning HEAD
|
||||
if version == 'HEAD':
|
||||
git_clone_cmd = 'git', 'clone', '--depth=1', git_url, to_text(b_checkout_path)
|
||||
git_clone_cmd = git_executable, 'clone', '--depth=1', git_url, to_text(b_checkout_path)
|
||||
else:
|
||||
git_clone_cmd = 'git', 'clone', git_url, to_text(b_checkout_path)
|
||||
git_clone_cmd = git_executable, 'clone', git_url, to_text(b_checkout_path)
|
||||
# FIXME: '--branch', version
|
||||
|
||||
try:
|
||||
@ -368,7 +377,7 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
|
||||
proc_err,
|
||||
)
|
||||
|
||||
git_switch_cmd = 'git', 'checkout', to_text(version)
|
||||
git_switch_cmd = git_executable, 'checkout', to_text(version)
|
||||
try:
|
||||
subprocess.check_call(git_switch_cmd, cwd=b_checkout_path)
|
||||
except subprocess.CalledProcessError as proc_err:
|
||||
|
||||
@ -18,6 +18,7 @@ import yaml
|
||||
|
||||
from io import BytesIO, StringIO
|
||||
from units.compat.mock import MagicMock
|
||||
from unittest import mock
|
||||
|
||||
import ansible.module_utils.six.moves.urllib.error as urllib_error
|
||||
|
||||
@ -27,6 +28,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.galaxy import collection, api, dependency_resolution
|
||||
from ansible.galaxy.dependency_resolution.dataclasses import Candidate, Requirement
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.utils import context_objects as co
|
||||
from ansible.utils.display import Display
|
||||
|
||||
@ -171,6 +173,22 @@ def galaxy_server():
|
||||
return galaxy_api
|
||||
|
||||
|
||||
def test_concrete_artifact_manager_scm_no_executable(monkeypatch):
|
||||
url = 'https://github.com/org/repo'
|
||||
version = 'commitish'
|
||||
mock_subprocess_check_call = MagicMock()
|
||||
monkeypatch.setattr(collection.concrete_artifact_manager.subprocess, 'check_call', mock_subprocess_check_call)
|
||||
mock_mkdtemp = MagicMock(return_value='')
|
||||
monkeypatch.setattr(collection.concrete_artifact_manager, 'mkdtemp', mock_mkdtemp)
|
||||
|
||||
error = re.escape(
|
||||
"Could not find git executable to extract the collection from the Git repository `https://github.com/org/repo`"
|
||||
)
|
||||
with mock.patch.dict(os.environ, {"PATH": ""}):
|
||||
with pytest.raises(AnsibleError, match=error):
|
||||
collection.concrete_artifact_manager._extract_collection_from_git(url, version, b'path')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url,version,trailing_slash',
|
||||
[
|
||||
@ -193,10 +211,12 @@ def test_concrete_artifact_manager_scm_cmd(url, version, trailing_slash, monkeyp
|
||||
repo = 'https://github.com/org/repo'
|
||||
if trailing_slash:
|
||||
repo += '/'
|
||||
clone_cmd = ('git', 'clone', repo, '')
|
||||
|
||||
git_executable = get_bin_path('git')
|
||||
clone_cmd = (git_executable, 'clone', repo, '')
|
||||
|
||||
assert mock_subprocess_check_call.call_args_list[0].args[0] == clone_cmd
|
||||
assert mock_subprocess_check_call.call_args_list[1].args[0] == ('git', 'checkout', 'commitish')
|
||||
assert mock_subprocess_check_call.call_args_list[1].args[0] == (git_executable, 'checkout', 'commitish')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -222,10 +242,11 @@ def test_concrete_artifact_manager_scm_cmd_shallow(url, version, trailing_slash,
|
||||
repo = 'https://github.com/org/repo'
|
||||
if trailing_slash:
|
||||
repo += '/'
|
||||
shallow_clone_cmd = ('git', 'clone', '--depth=1', repo, '')
|
||||
git_executable = get_bin_path('git')
|
||||
shallow_clone_cmd = (git_executable, 'clone', '--depth=1', repo, '')
|
||||
|
||||
assert mock_subprocess_check_call.call_args_list[0].args[0] == shallow_clone_cmd
|
||||
assert mock_subprocess_check_call.call_args_list[1].args[0] == ('git', 'checkout', 'HEAD')
|
||||
assert mock_subprocess_check_call.call_args_list[1].args[0] == (git_executable, 'checkout', 'HEAD')
|
||||
|
||||
|
||||
def test_build_requirement_from_path(collection_artifact):
|
||||
|
||||
Reference in New Issue
Block a user