mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 19:28:54 -05:00
enhance(downloader): log git commands that failed (#3372)
This commit is contained in:
parent
29feab638a
commit
a1b95e5072
@ -38,6 +38,10 @@ class GitException(DownloaderException):
|
|||||||
Generic class for git exceptions.
|
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):
|
class InvalidRepoName(DownloaderException):
|
||||||
"""
|
"""
|
||||||
@ -138,8 +142,8 @@ class AmbiguousRevision(GitException):
|
|||||||
Thrown when specified revision is ambiguous.
|
Thrown when specified revision is ambiguous.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message: str, candidates: List[Candidate]) -> None:
|
def __init__(self, message: str, git_command: str, candidates: List[Candidate]) -> None:
|
||||||
super().__init__(message)
|
super().__init__(message, git_command)
|
||||||
self.candidates = candidates
|
self.candidates = candidates
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -203,21 +203,20 @@ class Repo(RepoJSONMixin):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
valid_exit_codes = (0, 1)
|
valid_exit_codes = (0, 1)
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_IS_ANCESTOR,
|
||||||
self.GIT_IS_ANCESTOR,
|
path=self.folder_path,
|
||||||
path=self.folder_path,
|
maybe_ancestor_rev=maybe_ancestor_rev,
|
||||||
maybe_ancestor_rev=maybe_ancestor_rev,
|
descendant_rev=descendant_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:
|
if p.returncode in valid_exit_codes:
|
||||||
return not bool(p.returncode)
|
return not bool(p.returncode)
|
||||||
raise errors.GitException(
|
raise errors.GitException(
|
||||||
f"Git failed to determine if commit {maybe_ancestor_rev}"
|
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:
|
async def is_on_branch(self) -> bool:
|
||||||
@ -253,15 +252,14 @@ class Repo(RepoJSONMixin):
|
|||||||
"""
|
"""
|
||||||
if new_rev is None:
|
if new_rev is None:
|
||||||
new_rev = self.branch
|
new_rev = self.branch
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_DIFF_FILE_STATUS, path=self.folder_path, old_rev=old_rev, new_rev=new_rev
|
||||||
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:
|
if p.returncode != 0:
|
||||||
raise errors.GitDiffError(
|
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")
|
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):
|
async with self.checkout(descendant_rev):
|
||||||
return discord.utils.get(self.available_modules, name=module_name)
|
return discord.utils.get(self.available_modules, name=module_name)
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT,
|
||||||
self.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT,
|
path=self.folder_path,
|
||||||
path=self.folder_path,
|
descendant_rev=descendant_rev,
|
||||||
descendant_rev=descendant_rev,
|
module_name=module_name,
|
||||||
module_name=module_name,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise errors.GitException(
|
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()
|
commit = p.stdout.decode().strip()
|
||||||
@ -418,19 +415,18 @@ class Repo(RepoJSONMixin):
|
|||||||
to get messages for.
|
to get messages for.
|
||||||
:return: Git commit note log
|
:return: Git commit note log
|
||||||
"""
|
"""
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_LOG,
|
||||||
self.GIT_LOG,
|
path=self.folder_path,
|
||||||
path=self.folder_path,
|
old_rev=old_rev,
|
||||||
old_rev=old_rev,
|
relative_file_path=relative_file_path,
|
||||||
relative_file_path=relative_file_path,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise errors.GitException(
|
raise errors.GitException(
|
||||||
"An exception occurred while executing git log on"
|
f"An exception occurred while executing git log on this repo: {self.folder_path}",
|
||||||
" this repo: {}".format(self.folder_path)
|
git_command,
|
||||||
)
|
)
|
||||||
|
|
||||||
return p.stdout.decode().strip()
|
return p.stdout.decode().strip()
|
||||||
@ -457,21 +453,24 @@ class Repo(RepoJSONMixin):
|
|||||||
Full sha1 object name for provided revision.
|
Full sha1 object name for provided revision.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(self.GIT_GET_FULL_SHA1, path=self.folder_path, rev=rev)
|
self.GIT_GET_FULL_SHA1, path=self.folder_path, rev=rev
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
stderr = p.stderr.decode().strip()
|
stderr = p.stderr.decode().strip()
|
||||||
ambiguous_error = f"error: short SHA1 {rev} is ambiguous\nhint: The candidates are:\n"
|
ambiguous_error = f"error: short SHA1 {rev} is ambiguous\nhint: The candidates are:\n"
|
||||||
if not stderr.startswith(ambiguous_error):
|
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 = []
|
candidates = []
|
||||||
for match in self.AMBIGUOUS_ERROR_REGEX.finditer(stderr, len(ambiguous_error)):
|
for match in self.AMBIGUOUS_ERROR_REGEX.finditer(stderr, len(ambiguous_error)):
|
||||||
candidates.append(Candidate(match["rev"], match["type"], match["desc"]))
|
candidates.append(Candidate(match["rev"], match["type"], match["desc"]))
|
||||||
if candidates:
|
if candidates:
|
||||||
raise errors.AmbiguousRevision(f"Short SHA1 {rev} is ambiguous.", candidates)
|
raise errors.AmbiguousRevision(
|
||||||
raise errors.UnknownRevision(f"Revision {rev} cannot be found.")
|
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()
|
return p.stdout.decode().strip()
|
||||||
|
|
||||||
@ -554,17 +553,14 @@ class Repo(RepoJSONMixin):
|
|||||||
return
|
return
|
||||||
exists, __ = self._existing_git_repo()
|
exists, __ = self._existing_git_repo()
|
||||||
if not exists:
|
if not exists:
|
||||||
raise errors.MissingGitRepo(
|
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
|
||||||
"A git repo does not exist at path: {}".format(self.folder_path)
|
|
||||||
)
|
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(self.GIT_CHECKOUT, path=self.folder_path, rev=rev)
|
||||||
ProcessFormatter().format(self.GIT_CHECKOUT, path=self.folder_path, rev=rev)
|
p = await self._run(git_command)
|
||||||
)
|
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise errors.UnknownRevision(
|
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()
|
await self._setup_repo()
|
||||||
@ -619,25 +615,22 @@ class Repo(RepoJSONMixin):
|
|||||||
"""
|
"""
|
||||||
exists, path = self._existing_git_repo()
|
exists, path = self._existing_git_repo()
|
||||||
if exists:
|
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:
|
if self.branch is not None:
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_CLONE, branch=self.branch, url=self.url, folder=self.folder_path
|
||||||
self.GIT_CLONE, branch=self.branch, url=self.url, folder=self.folder_path
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(
|
self.GIT_CLONE_NO_BRANCH, url=self.url, folder=self.folder_path
|
||||||
self.GIT_CLONE_NO_BRANCH, url=self.url, folder=self.folder_path
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode:
|
if p.returncode:
|
||||||
# Try cleaning up folder
|
# Try cleaning up folder
|
||||||
shutil.rmtree(str(self.folder_path), ignore_errors=True)
|
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:
|
if self.branch is None:
|
||||||
self.branch = await self.current_branch()
|
self.branch = await self.current_branch()
|
||||||
@ -657,17 +650,14 @@ class Repo(RepoJSONMixin):
|
|||||||
"""
|
"""
|
||||||
exists, __ = self._existing_git_repo()
|
exists, __ = self._existing_git_repo()
|
||||||
if not exists:
|
if not exists:
|
||||||
raise errors.MissingGitRepo(
|
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
|
||||||
"A git repo does not exist at path: {}".format(self.folder_path)
|
|
||||||
)
|
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(self.GIT_CURRENT_BRANCH, path=self.folder_path)
|
||||||
ProcessFormatter().format(self.GIT_CURRENT_BRANCH, path=self.folder_path)
|
p = await self._run(git_command)
|
||||||
)
|
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise errors.GitException(
|
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()
|
return p.stdout.decode().strip()
|
||||||
@ -683,16 +673,13 @@ class Repo(RepoJSONMixin):
|
|||||||
"""
|
"""
|
||||||
exists, __ = self._existing_git_repo()
|
exists, __ = self._existing_git_repo()
|
||||||
if not exists:
|
if not exists:
|
||||||
raise errors.MissingGitRepo(
|
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
|
||||||
"A git repo does not exist at path: {}".format(self.folder_path)
|
|
||||||
)
|
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(self.GIT_CURRENT_COMMIT, path=self.folder_path)
|
||||||
ProcessFormatter().format(self.GIT_CURRENT_COMMIT, path=self.folder_path)
|
p = await self._run(git_command)
|
||||||
)
|
|
||||||
|
|
||||||
if p.returncode != 0:
|
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()
|
return p.stdout.decode().strip()
|
||||||
|
|
||||||
@ -715,16 +702,15 @@ class Repo(RepoJSONMixin):
|
|||||||
|
|
||||||
exists, __ = self._existing_git_repo()
|
exists, __ = self._existing_git_repo()
|
||||||
if not exists:
|
if not exists:
|
||||||
raise errors.MissingGitRepo(
|
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
|
||||||
"A git repo does not exist at path: {}".format(self.folder_path)
|
|
||||||
)
|
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(self.GIT_LATEST_COMMIT, path=self.folder_path, branch=branch)
|
self.GIT_LATEST_COMMIT, path=self.folder_path, branch=branch
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode != 0:
|
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()
|
return p.stdout.decode().strip()
|
||||||
|
|
||||||
@ -751,10 +737,11 @@ class Repo(RepoJSONMixin):
|
|||||||
if folder is None:
|
if folder is None:
|
||||||
folder = self.folder_path
|
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:
|
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()
|
return p.stdout.decode().strip()
|
||||||
|
|
||||||
@ -773,19 +760,18 @@ class Repo(RepoJSONMixin):
|
|||||||
await self.checkout(branch)
|
await self.checkout(branch)
|
||||||
exists, __ = self._existing_git_repo()
|
exists, __ = self._existing_git_repo()
|
||||||
if not exists:
|
if not exists:
|
||||||
raise errors.MissingGitRepo(
|
raise errors.MissingGitRepo(f"A git repo does not exist at path: {self.folder_path}")
|
||||||
"A git repo does not exist at path: {}".format(self.folder_path)
|
|
||||||
)
|
|
||||||
|
|
||||||
p = await self._run(
|
git_command = ProcessFormatter().format(
|
||||||
ProcessFormatter().format(self.GIT_HARD_RESET, path=self.folder_path, branch=branch)
|
self.GIT_HARD_RESET, path=self.folder_path, branch=branch
|
||||||
)
|
)
|
||||||
|
p = await self._run(git_command)
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise errors.HardResetError(
|
raise errors.HardResetError(
|
||||||
"Some error occurred when trying to"
|
"Some error occurred when trying to execute a hard reset on the repo at"
|
||||||
" execute a hard reset on the repo at"
|
f" the following path: {self.folder_path}",
|
||||||
" the following path: {}".format(self.folder_path)
|
git_command,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def update(self) -> Tuple[str, str]:
|
async def update(self) -> Tuple[str, str]:
|
||||||
@ -804,12 +790,14 @@ class Repo(RepoJSONMixin):
|
|||||||
|
|
||||||
await self.hard_reset()
|
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:
|
if p.returncode != 0:
|
||||||
raise errors.UpdateError(
|
raise errors.UpdateError(
|
||||||
"Git pull returned a non zero exit code"
|
"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()
|
await self._setup_repo()
|
||||||
@ -1114,7 +1102,7 @@ class RepoManager:
|
|||||||
"""
|
"""
|
||||||
repo = self.get_repo(name)
|
repo = self.get_repo(name)
|
||||||
if repo is None:
|
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)
|
safe_delete(repo.folder_path)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user