aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/repo_manager.py
diff options
context:
space:
mode:
authorGravatar Leo Neat <leosneat@gmail.com>2020-01-31 15:31:18 -0800
committerGravatar GitHub <noreply@github.com>2020-01-31 15:31:18 -0800
commit1a87da68c870ce09ab6ffac30589da12e7ff6a8d (patch)
tree1c3431bff2ead5c227919db2b4464ec07bac06dd /infra/repo_manager.py
parentc2fa07a0956bcfebf2b70b5df13f5ed4c4d7c7e5 (diff)
[cifuzz] - commit and pull request hook functionality (#3310)
Diffstat (limited to 'infra/repo_manager.py')
-rw-r--r--infra/repo_manager.py94
1 files changed, 51 insertions, 43 deletions
diff --git a/infra/repo_manager.py b/infra/repo_manager.py
index bb3fe237..cf98ab94 100644
--- a/infra/repo_manager.py
+++ b/infra/repo_manager.py
@@ -27,27 +27,23 @@ import shutil
import utils
-class RepoManagerError(Exception):
- """Class to describe the exceptions in RepoManager."""
-
-
class RepoManager:
"""Class to manage git repos from python.
Attributes:
- repo_url: The location of the git repo
- base_dir: The location of where the repo clone is stored locally
- repo_name: The name of the github project
- repo_dir: The location of the main repo
+ repo_url: The location of the git repo.
+ base_dir: The location of where the repo clone is stored locally.
+ repo_name: The name of the GitHub project.
+ repo_dir: The location of the main repo.
"""
def __init__(self, repo_url, base_dir, repo_name=None):
"""Constructs a repo manager class.
Args:
- repo_url: The github url needed to clone
- base_dir: The full filepath where the git repo is located
- repo_name: The name of the directory the repo is cloned to
+ repo_url: The github url needed to clone.
+ base_dir: The full file-path where the git repo is located.
+ repo_name: The name of the directory the repo is cloned to.
"""
self.repo_url = repo_url
self.base_dir = base_dir
@@ -62,7 +58,7 @@ class RepoManager:
"""Creates a clone of the repo in the specified directory.
Raises:
- RepoManagerError if the repo was not able to be cloned
+ ValueError: when the repo is not able to be cloned.
"""
if not os.path.exists(self.base_dir):
os.makedirs(self.base_dir)
@@ -70,13 +66,13 @@ class RepoManager:
out, err = utils.execute(['git', 'clone', self.repo_url, self.repo_name],
location=self.base_dir)
if not self._is_git_repo():
- raise RepoManagerError('%s is not a git repo' % self.repo_url)
+ raise ValueError('%s is not a git repo' % self.repo_url)
def _is_git_repo(self):
"""Test if the current repo dir is a git repo or not.
Returns:
- True if the current repo_dir is a valid git repo
+ True if the current repo_dir is a valid git repo.
"""
git_path = os.path.join(self.repo_dir, '.git')
return os.path.isdir(git_path)
@@ -85,19 +81,13 @@ class RepoManager:
"""Checks to see if a commit exists in the project repo.
Args:
- commit: The commit SHA you are checking
+ commit: The commit SHA you are checking.
Returns:
- True if the commit exits in the project
-
- Raises:
- ValueException: an empty string was passed in as a commit
+ True if the commit exits in the project.
"""
-
- # Handle the exception case, if empty string is passed execute will
- # raise a ValueError
if not commit.rstrip():
- raise RepoManagerError('An empty string is not a valid commit SHA')
+ return False
_, err_code = utils.execute(['git', 'cat-file', '-e', commit],
self.repo_dir)
@@ -107,7 +97,7 @@ class RepoManager:
"""Gets the current commit SHA of the repo.
Returns:
- The current active commit SHA
+ The current active commit SHA.
"""
out, _ = utils.execute(['git', 'rev-parse', 'HEAD'],
self.repo_dir,
@@ -118,20 +108,21 @@ class RepoManager:
"""Gets the list of commits(inclusive) between the old and new commits.
Args:
- old_commit: The oldest commit to be in the list
- new_commit: The newest commit to be in the list
+ old_commit: The oldest commit to be in the list.
+ new_commit: The newest commit to be in the list.
Returns:
- The list of commit SHAs from newest to oldest
+ The list of commit SHAs from newest to oldest.
Raises:
- RepoManagerError when commits dont exist
+ ValueError: When either the old or new commit does not exist.
+ RuntimeError: When there is an error getting the commit list.
"""
if not self.commit_exists(old_commit):
- raise RepoManagerError('The old commit %s does not exist' % old_commit)
+ raise ValueError('The old commit %s does not exist' % old_commit)
if not self.commit_exists(new_commit):
- raise RepoManagerError('The new commit %s does not exist' % new_commit)
+ raise ValueError('The new commit %s does not exist' % new_commit)
if old_commit == new_commit:
return [old_commit]
out, err_code = utils.execute(
@@ -139,37 +130,54 @@ class RepoManager:
commits = out.split('\n')
commits = [commit for commit in commits if commit]
if err_code or not commits:
- raise RepoManagerError('Error getting commit list between %s and %s ' %
- (old_commit, new_commit))
+ raise RuntimeError('Error getting commit list between %s and %s ' %
+ (old_commit, new_commit))
# Make sure result is inclusive
commits.append(old_commit)
return commits
+ def fetch_unshallow(self):
+ """Gets the current git repository history."""
+ git_path = os.path.join(self.repo_dir, '.git', 'shallow')
+ if os.path.exists(git_path):
+ utils.execute(['git', 'fetch', '--unshallow'],
+ self.repo_dir,
+ check_result=True)
+
+ def checkout_pr(self, pr_ref):
+ """Checks out a remote pull request.
+
+ Args:
+ pr_ref: The pull request reference to be checked out.
+ """
+ self.fetch_unshallow()
+ utils.execute(['git', 'fetch', 'origin', pr_ref],
+ self.repo_dir,
+ check_result=True)
+ utils.execute(['git', 'checkout', '-f', 'FETCH_HEAD'],
+ self.repo_dir,
+ check_result=True)
+
def checkout_commit(self, commit):
"""Checks out a specific commit from the repo.
Args:
- commit: The commit SHA to be checked out
+ commit: The commit SHA to be checked out.
Raises:
- RepoManagerError when checkout is not successful
+ RuntimeError: when checkout is not successful.
+ ValueError: when commit does not exist.
"""
+ self.fetch_unshallow()
if not self.commit_exists(commit):
- raise RepoManagerError('Commit %s does not exist in current branch' %
- commit)
-
- git_path = os.path.join(self.repo_dir, '.git', 'shallow')
- if os.path.exists(git_path):
- utils.execute(['git', 'fetch', '--unshallow'],
- self.repo_dir,
- check_result=True)
+ raise ValueError('Commit %s does not exist in current branch' % commit)
utils.execute(['git', 'checkout', '-f', commit],
self.repo_dir,
check_result=True)
utils.execute(['git', 'clean', '-fxd'], self.repo_dir, check_result=True)
if self.get_current_commit() != commit:
- raise RepoManagerError('Error checking out commit %s' % commit)
+ raise RuntimeError('Error checking out commit %s' % commit)
def remove_repo(self):
"""Attempts to remove the git repo. """