diff --git a/redbot/cogs/downloader/errors.py b/redbot/cogs/downloader/errors.py index efd31bedd..ee0c6ab2e 100644 --- a/redbot/cogs/downloader/errors.py +++ b/redbot/cogs/downloader/errors.py @@ -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 diff --git a/redbot/cogs/downloader/repo_manager.py b/redbot/cogs/downloader/repo_manager.py index 9c28a7a76..fe786ef98 100644 --- a/redbot/cogs/downloader/repo_manager.py +++ b/redbot/cogs/downloader/repo_manager.py @@ -203,21 +203,20 @@ class Repo(RepoJSONMixin): """ valid_exit_codes = (0, 1) - p = await self._run( - 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, + git_command = ProcessFormatter().format( + self.GIT_IS_ANCESTOR, + path=self.folder_path, + maybe_ancestor_rev=maybe_ancestor_rev, + descendant_rev=descendant_rev, ) + 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( - self.GIT_DIFF_FILE_STATUS, path=self.folder_path, old_rev=old_rev, new_rev=new_rev - ) + 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( - self.GIT_GET_LAST_MODULE_OCCURRENCE_COMMIT, - path=self.folder_path, - descendant_rev=descendant_rev, - module_name=module_name, - ) + 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( - self.GIT_LOG, - path=self.folder_path, - old_rev=old_rev, - relative_file_path=relative_file_path, - ) + 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( - self.GIT_CLONE, branch=self.branch, url=self.url, folder=self.folder_path - ) + git_command = ProcessFormatter().format( + self.GIT_CLONE, branch=self.branch, url=self.url, folder=self.folder_path ) else: - p = await self._run( - ProcessFormatter().format( - self.GIT_CLONE_NO_BRANCH, url=self.url, folder=self.folder_path - ) + 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]: @@ -795,7 +781,7 @@ class Repo(RepoJSONMixin): ------- `tuple` of `str` :py:code`(old commit hash, new commit hash)` - + Raises ------- `UpdateError` - if git pull results with non-zero exit code @@ -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)