Skip to content

Commit

Permalink
Raise exception when git clone fails (#1709)
Browse files Browse the repository at this point in the history
When a git repository failed to clone, we had just been logging an error
and continuing. [The code later assumes the clone was
successful](https://github.com/google/osv.dev/blob/36c344dee7e46cc1fa5cf0dea2222552b9efe953/osv/impact.py#L321),
which was causing another exception.

Instead, just raise an exception when the clone fails to make it more
obvious what's wrong.
  • Loading branch information
michaelkedar authored Oct 10, 2023
1 parent 5d4a9cb commit 55fb414
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions osv/repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,26 @@ def _set_git_callback_env(git_callbacks):
return env


class GitCloneError(Exception):
"""Git repository clone exception."""


def clone(git_url, checkout_dir, git_callbacks=None):
"""Perform a clone."""
# Use 'git' CLI here as it's much faster than libgit2's clone.
env = _set_git_callback_env(git_callbacks)

subprocess.run(
['git', 'clone', _git_mirror(git_url), checkout_dir],
env=env,
capture_output=True,
check=True)
return pygit2.Repository(checkout_dir)
try:
# Use 'git' CLI here as it's much faster than libgit2's clone.
env = _set_git_callback_env(git_callbacks)

subprocess.run(
['git', 'clone', _git_mirror(git_url), checkout_dir],
env=env,
capture_output=True,
check=True)
return pygit2.Repository(checkout_dir)
except subprocess.CalledProcessError as e:
raise GitCloneError(f'Failed to clone repo:\n{e.stderr.decode()}') from e
except pygit2.GitError as e:
raise GitCloneError('Failed to open cloned repo') from e


def clone_with_retries(git_url, checkout_dir, git_callbacks=None, branch=None):
Expand All @@ -118,17 +127,12 @@ def clone_with_retries(git_url, checkout_dir, git_callbacks=None, branch=None):
if branch:
_checkout_branch(repo, branch)
return repo
except (pygit2.GitError, subprocess.CalledProcessError) as e:
if attempt == CLONE_TRIES - 1:
err_str = str(e)
if isinstance(e, subprocess.CalledProcessError):
# add the git output to the log
err_str = f'{err_str}\n{e.stderr.decode()}'
logging.error('Clone failed after %d attempts: %s', CLONE_TRIES,
err_str)
except GitCloneError:
shutil.rmtree(checkout_dir, ignore_errors=True)
if attempt == CLONE_TRIES - 1:
logging.error('Clone failed after %d attempts', CLONE_TRIES)
raise
time.sleep(RETRY_SLEEP_SECONDS)
continue

return None

Expand Down

0 comments on commit 55fb414

Please sign in to comment.