enhance(downloader): log git commands that failed (#3372)

This commit is contained in:
jack1142 2020-01-16 02:54:23 +01:00 committed by Michael H
parent 29feab638a
commit a1b95e5072
2 changed files with 81 additions and 89 deletions

View File

@ -38,6 +38,10 @@ class GitException(DownloaderException):
Generic class for git exceptions.
"""
def __init__(self, message: str, git_command: str) -> None:
self.git_command = git_command
super().__init__(f"Git command failed: {git_command}\nError message: {message}")
class InvalidRepoName(DownloaderException):
"""
@ -138,8 +142,8 @@ class AmbiguousRevision(GitException):
Thrown when specified revision is ambiguous.
"""
def __init__(self, message: str, candidates: List[Candidate]) -> None:
super().__init__(message)
def __init__(self, message: str, git_command: str, candidates: List[Candidate]) -> None:
super().__init__(message, git_command)
self.candidates = candidates

View File

@ -203,21 +203,20 @@ class Repo(RepoJSONMixin):
"""
valid_exit_codes = (0, 1)
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_IS_ANCESTOR,
path=self.folder_path,
maybe_ancestor_rev=maybe_ancestor_rev,
descendant_rev=descendant_rev,
),
valid_exit_codes=valid_exit_codes,
)
p = await self._run(git_command, valid_exit_codes=valid_exit_codes)
if p.returncode in valid_exit_codes:
return not bool(p.returncode)
raise errors.GitException(
f"Git failed to determine if commit {maybe_ancestor_rev}"
f" is ancestor of {descendant_rev} for repo at path: {self.folder_path}"
f" is ancestor of {descendant_rev} for repo at path: {self.folder_path}",
git_command,
)
async def is_on_branch(self) -> bool:
@ -253,15 +252,14 @@ class Repo(RepoJSONMixin):
"""
if new_rev is None:
new_rev = self.branch
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_DIFF_FILE_STATUS, path=self.folder_path, old_rev=old_rev, new_rev=new_rev
)
)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.GitDiffError(
"Git diff failed for repo at path: {}".format(self.folder_path)
f"Git diff failed for repo at path: {self.folder_path}", git_command
)
stdout = p.stdout.strip(b"\t\n\x00 ").decode().split("\x00\t")
@ -310,18 +308,17 @@ class Repo(RepoJSONMixin):
async with self.checkout(descendant_rev):
return discord.utils.get(self.available_modules, name=module_name)
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT,
path=self.folder_path,
descendant_rev=descendant_rev,
module_name=module_name,
)
)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.GitException(
"Git log failed for repo at path: {}".format(self.folder_path)
f"Git log failed for repo at path: {self.folder_path}", git_command
)
commit = p.stdout.decode().strip()
@ -418,19 +415,18 @@ class Repo(RepoJSONMixin):
to get messages for.
:return: Git commit note log
"""
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_LOG,
path=self.folder_path,
old_rev=old_rev,
relative_file_path=relative_file_path,
)
)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.GitException(
"An exception occurred while executing git log on"
" this repo: {}".format(self.folder_path)
f"An exception occurred while executing git log on this repo: {self.folder_path}",
git_command,
)
return p.stdout.decode().strip()
@ -457,21 +453,24 @@ class Repo(RepoJSONMixin):
Full sha1 object name for provided revision.
"""
p = await self._run(
ProcessFormatter().format(self.GIT_GET_FULL_SHA1, path=self.folder_path, rev=rev)
git_command = ProcessFormatter().format(
self.GIT_GET_FULL_SHA1, path=self.folder_path, rev=rev
)
p = await self._run(git_command)
if p.returncode != 0:
stderr = p.stderr.decode().strip()
ambiguous_error = f"error: short SHA1 {rev} is ambiguous\nhint: The candidates are:\n"
if not stderr.startswith(ambiguous_error):
raise errors.UnknownRevision(f"Revision {rev} cannot be found.")
raise errors.UnknownRevision(f"Revision {rev} cannot be found.", git_command)
candidates = []
for match in self.AMBIGUOUS_ERROR_REGEX.finditer(stderr, len(ambiguous_error)):
candidates.append(Candidate(match["rev"], match["type"], match["desc"]))
if candidates:
raise errors.AmbiguousRevision(f"Short SHA1 {rev} is ambiguous.", candidates)
raise errors.UnknownRevision(f"Revision {rev} cannot be found.")
raise errors.AmbiguousRevision(
f"Short SHA1 {rev} is ambiguous.", git_command, candidates
)
raise errors.UnknownRevision(f"Revision {rev} cannot be found.", git_command)
return p.stdout.decode().strip()
@ -554,17 +553,14 @@ class Repo(RepoJSONMixin):
return
exists, __ = self._existing_git_repo()
if not exists:
raise errors.MissingGitRepo(
"A git repo does not exist at path: {}".format(self.folder_path)
)
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
p = await self._run(
ProcessFormatter().format(self.GIT_CHECKOUT, path=self.folder_path, rev=rev)
)
git_command = ProcessFormatter().format(self.GIT_CHECKOUT, path=self.folder_path, rev=rev)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.UnknownRevision(
"Could not checkout to {}. This revision may not exist".format(rev)
f"Could not checkout to {rev}. This revision may not exist", git_command
)
await self._setup_repo()
@ -619,25 +615,22 @@ class Repo(RepoJSONMixin):
"""
exists, path = self._existing_git_repo()
if exists:
raise errors.ExistingGitRepo("A git repo already exists at path: {}".format(path))
raise errors.ExistingGitRepo(f"A git repo already exists at path: {path}")
if self.branch is not None:
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_CLONE, branch=self.branch, url=self.url, folder=self.folder_path
)
)
else:
p = await self._run(
ProcessFormatter().format(
git_command = ProcessFormatter().format(
self.GIT_CLONE_NO_BRANCH, url=self.url, folder=self.folder_path
)
)
p = await self._run(git_command)
if p.returncode:
# Try cleaning up folder
shutil.rmtree(str(self.folder_path), ignore_errors=True)
raise errors.CloningError("Error when running git clone.")
raise errors.CloningError("Error when running git clone.", git_command)
if self.branch is None:
self.branch = await self.current_branch()
@ -657,17 +650,14 @@ class Repo(RepoJSONMixin):
"""
exists, __ = self._existing_git_repo()
if not exists:
raise errors.MissingGitRepo(
"A git repo does not exist at path: {}".format(self.folder_path)
)
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
p = await self._run(
ProcessFormatter().format(self.GIT_CURRENT_BRANCH, path=self.folder_path)
)
git_command = ProcessFormatter().format(self.GIT_CURRENT_BRANCH, path=self.folder_path)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.GitException(
"Could not determine current branch at path: {}".format(self.folder_path)
f"Could not determine current branch at path: {self.folder_path}", git_command
)
return p.stdout.decode().strip()
@ -683,16 +673,13 @@ class Repo(RepoJSONMixin):
"""
exists, __ = self._existing_git_repo()
if not exists:
raise errors.MissingGitRepo(
"A git repo does not exist at path: {}".format(self.folder_path)
)
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
p = await self._run(
ProcessFormatter().format(self.GIT_CURRENT_COMMIT, path=self.folder_path)
)
git_command = ProcessFormatter().format(self.GIT_CURRENT_COMMIT, path=self.folder_path)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.CurrentHashError("Unable to determine commit hash.")
raise errors.CurrentHashError("Unable to determine commit hash.", git_command)
return p.stdout.decode().strip()
@ -715,16 +702,15 @@ class Repo(RepoJSONMixin):
exists, __ = self._existing_git_repo()
if not exists:
raise errors.MissingGitRepo(
"A git repo does not exist at path: {}".format(self.folder_path)
)
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
p = await self._run(
ProcessFormatter().format(self.GIT_LATEST_COMMIT, path=self.folder_path, branch=branch)
git_command = ProcessFormatter().format(
self.GIT_LATEST_COMMIT, path=self.folder_path, branch=branch
)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.CurrentHashError("Unable to determine latest commit hash.")
raise errors.CurrentHashError("Unable to determine latest commit hash.", git_command)
return p.stdout.decode().strip()
@ -751,10 +737,11 @@ class Repo(RepoJSONMixin):
if folder is None:
folder = self.folder_path
p = await self._run(ProcessFormatter().format(Repo.GIT_DISCOVER_REMOTE_URL, path=folder))
git_command = ProcessFormatter().format(Repo.GIT_DISCOVER_REMOTE_URL, path=folder)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.NoRemoteURL("Unable to discover a repo URL.")
raise errors.NoRemoteURL("Unable to discover a repo URL.", git_command)
return p.stdout.decode().strip()
@ -773,19 +760,18 @@ class Repo(RepoJSONMixin):
await self.checkout(branch)
exists, __ = self._existing_git_repo()
if not exists:
raise errors.MissingGitRepo(
"A git repo does not exist at path: {}".format(self.folder_path)
)
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
p = await self._run(
ProcessFormatter().format(self.GIT_HARD_RESET, path=self.folder_path, branch=branch)
git_command = ProcessFormatter().format(
self.GIT_HARD_RESET, path=self.folder_path, branch=branch
)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.HardResetError(
"Some error occurred when trying to"
" execute a hard reset on the repo at"
" the following path: {}".format(self.folder_path)
"Some error occurred when trying to execute a hard reset on the repo at"
f" the following path: {self.folder_path}",
git_command,
)
async def update(self) -> Tuple[str, str]:
@ -804,12 +790,14 @@ class Repo(RepoJSONMixin):
await self.hard_reset()
p = await self._run(ProcessFormatter().format(self.GIT_PULL, path=self.folder_path))
git_command = ProcessFormatter().format(self.GIT_PULL, path=self.folder_path)
p = await self._run(git_command)
if p.returncode != 0:
raise errors.UpdateError(
"Git pull returned a non zero exit code"
" for the repo located at path: {}".format(self.folder_path)
f" for the repo located at path: {self.folder_path}",
git_command,
)
await self._setup_repo()
@ -1114,7 +1102,7 @@ class RepoManager:
"""
repo = self.get_repo(name)
if repo is None:
raise errors.MissingGitRepo("There is no repo with the name {}".format(name))
raise errors.MissingGitRepo(f"There is no repo with the name {name}")
safe_delete(repo.folder_path)