mirror of
https://github.com/ansible/ansible.git
synced 2026-08-03 08:03:05 +02:00
ansible-galaxy: Clone git collections using shallow clones (#75722)
* ansible-galaxy: Clone git collections using shallow clones This ensures the collection obtained via git url is a result of a shallow git clone (git clone --depth=1). The git history of the collection is not used by ansible, and as such, cloning the entire history of the repo is unnecessary. Signed-off-by: Tomas Babej <tomas@tbabej.com> * ansible-galaxy: Only perform shallow clones on non-versioned git urls In general, the version can be anything we can checkout (branch, tag, but also a commit hash). In particular for commit hashes we cannot perform a shallow clone. Err on the safe side and only perform shallow clones for non-versioned git urls (cloning HEAD). * galaxy-install: Make shallow cloning compatible with older Python versions Signed-off-by: Tomas Babej <tomas@tbabej.com> * Pass args as a tuple Add tests for the git command created from different repo and version combinations * changelog Co-authored-by: Tomas Babej <tomas@tbabej.com>
This commit is contained in:
co-authored by
Tomas Babej
parent
724800cd3f
commit
7ecc227488
@@ -0,0 +1,5 @@
|
||||
minor_changes:
|
||||
- >-
|
||||
ansible-galaxy - Installing a collection from a git repository
|
||||
without specifying a version (or using the version ``HEAD``)
|
||||
will clone the repository using --depth=1.
|
||||
@@ -347,8 +347,14 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
|
||||
dir=b_path,
|
||||
prefix=to_bytes(name, errors='surrogate_or_strict'),
|
||||
) # type: bytes
|
||||
git_clone_cmd = 'git', 'clone', git_url, to_text(b_checkout_path)
|
||||
# FIXME: '--depth', '1', '--branch', version
|
||||
|
||||
# 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)
|
||||
else:
|
||||
git_clone_cmd = 'git', 'clone', git_url, to_text(b_checkout_path)
|
||||
# FIXME: '--branch', version
|
||||
|
||||
try:
|
||||
subprocess.check_call(git_clone_cmd)
|
||||
except subprocess.CalledProcessError as proc_err:
|
||||
|
||||
@@ -171,6 +171,63 @@ def galaxy_server():
|
||||
return galaxy_api
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url,version,trailing_slash',
|
||||
[
|
||||
('https://github.com/org/repo', 'commitish', False),
|
||||
('https://github.com/org/repo,commitish', None, False),
|
||||
('https://github.com/org/repo/,commitish', None, True),
|
||||
('https://github.com/org/repo#,commitish', None, False),
|
||||
]
|
||||
)
|
||||
def test_concrete_artifact_manager_scm_cmd(url, version, trailing_slash, monkeypatch):
|
||||
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)
|
||||
|
||||
collection.concrete_artifact_manager._extract_collection_from_git(url, version, b'path')
|
||||
|
||||
assert mock_subprocess_check_call.call_count == 2
|
||||
|
||||
repo = 'https://github.com/org/repo'
|
||||
if trailing_slash:
|
||||
repo += '/'
|
||||
clone_cmd = ('git', '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')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'url,version,trailing_slash',
|
||||
[
|
||||
('https://github.com/org/repo', 'HEAD', False),
|
||||
('https://github.com/org/repo,HEAD', None, False),
|
||||
('https://github.com/org/repo/,HEAD', None, True),
|
||||
('https://github.com/org/repo#,HEAD', None, False),
|
||||
('https://github.com/org/repo', None, False),
|
||||
]
|
||||
)
|
||||
def test_concrete_artifact_manager_scm_cmd_shallow(url, version, trailing_slash, monkeypatch):
|
||||
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)
|
||||
|
||||
collection.concrete_artifact_manager._extract_collection_from_git(url, version, b'path')
|
||||
|
||||
assert mock_subprocess_check_call.call_count == 2
|
||||
|
||||
repo = 'https://github.com/org/repo'
|
||||
if trailing_slash:
|
||||
repo += '/'
|
||||
shallow_clone_cmd = ('git', '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')
|
||||
|
||||
|
||||
def test_build_requirement_from_path(collection_artifact):
|
||||
tmp_path = os.path.join(os.path.split(collection_artifact[1])[0], b'temp')
|
||||
concrete_artifact_cm = collection.concrete_artifact_manager.ConcreteArtifactsManager(tmp_path, validate_certs=False)
|
||||
|
||||
Reference in New Issue
Block a user