Skip to content

Commit

Permalink
feat(ux): improve ux for git specific errors
Browse files Browse the repository at this point in the history
  • Loading branch information
abn committed Jan 23, 2025
1 parent 4f75197 commit 51e1308
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 18 deletions.
87 changes: 72 additions & 15 deletions src/poetry/vcs/git/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from dulwich.refs import ANNOTATED_TAG_SUFFIX
from dulwich.repo import Repo

from poetry.console.exceptions import PoetryConsoleError
from poetry.console.exceptions import PoetryRuntimeError
from poetry.utils.authenticator import get_default_authenticator
from poetry.utils.helpers import remove_directory

Expand All @@ -36,6 +36,30 @@
# A relative URL by definition starts with ../ or ./
RELATIVE_SUBMODULE_REGEX = re.compile(r"^\.{1,2}/")

# Common error messages
ERROR_MESSAGE_NOTE = (
"<b>Note:</> This error arises from interacting with "
"the specified vcs source and is likely not a "
"Poetry issue."
)
ERROR_MESSAGE_PROBLEMS_SECTION_START = (
"This issue could be caused by any of the following;\n\n"
"- there are network issues in this environment"
)
ERROR_MESSAGE_BAD_REVISION = (
"- the revision ({revision}) you have specified\n"
" - was misspelled\n"
" - is invalid (must be a sha or symref)\n"
" - is not present on remote"
)
ERROR_MESSAGE_BAD_REMOTE = (
"- the remote ({remote}) you have specified\n"
" - was misspelled\n"
" - does not exist\n"
" - requires credentials that were either not configured or is incorrect\n"
" - is in accessible due to network issues"
)


def is_revision_sha(revision: str | None) -> bool:
return re.match(r"^\b[0-9a-f]{5,40}\b$", revision or "") is not None
Expand Down Expand Up @@ -236,10 +260,15 @@ def _clone_legacy(url: str, refspec: GitRefSpec, target: Path) -> Repo:

try:
SystemGit.clone(url, target)
except CalledProcessError:
raise PoetryConsoleError(
f"Failed to clone {url}, check your git configuration and permissions"
" for this repository."
except CalledProcessError as e:
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone <info>{url}</>, check your git configuration and permissions for this repository.</>",
exception=e,
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START,
ERROR_MESSAGE_BAD_REMOTE.format(remote=url),
],
)

if revision:
Expand All @@ -248,8 +277,16 @@ def _clone_legacy(url: str, refspec: GitRefSpec, target: Path) -> Repo:

try:
SystemGit.checkout(revision, target)
except CalledProcessError:
raise PoetryConsoleError(f"Failed to checkout {url} at '{revision}'")
except CalledProcessError as e:
raise PoetryRuntimeError.create(
reason=f"<error>Failed to checkout {url} at '{revision}'.</>",
exception=e,
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START,
ERROR_MESSAGE_BAD_REVISION.format(revision=revision),
],
)

repo = Repo(str(target))
return repo
Expand All @@ -276,13 +313,28 @@ def _clone(cls, url: str, refspec: GitRefSpec, target: Path) -> Repo:
try:
refspec.resolve(remote_refs=remote_refs, repo=local)
except KeyError: # branch / ref does not exist
raise PoetryConsoleError(
f"Failed to clone {url} at '{refspec.key}', verify ref exists on"
" remote."
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</>",
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START,
ERROR_MESSAGE_BAD_REVISION.format(revision=refspec.key),
],
)

# ensure local HEAD matches remote
local.refs[b"HEAD"] = remote_refs.refs[b"HEAD"]
try:
# ensure local HEAD matches remote
local.refs[b"HEAD"] = remote_refs.refs[b"HEAD"]
except ValueError:
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</>",
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START,
ERROR_MESSAGE_BAD_REVISION.format(revision=refspec.key),
f"\nThis particular error is prevalent when {refspec.key} could not be resolved to a specific commit sha.",
],
)

if refspec.is_ref:
# set ref to current HEAD
Expand Down Expand Up @@ -318,9 +370,14 @@ def _clone(cls, url: str, refspec: GitRefSpec, target: Path) -> Repo:
if isinstance(e, AssertionError) and "Invalid object name" not in str(e):
raise

raise PoetryConsoleError(
f"Failed to clone {url} at '{refspec.key}', verify ref exists on"
" remote."
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</>",
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START,
ERROR_MESSAGE_BAD_REVISION.format(revision=refspec.key),
],
exception=e,
)

return local
Expand Down
7 changes: 4 additions & 3 deletions src/poetry/vcs/git/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ def run(*args: Any, **kwargs: Any) -> None:
git_command = find_git_command()
env = os.environ.copy()
env["GIT_TERMINAL_PROMPT"] = "0"
subprocess.check_call(

subprocess.run(
git_command + list(args),
stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
capture_output=True,
env=env,
text=True,
encoding="utf-8",
check=True,
)

@staticmethod
Expand Down

0 comments on commit 51e1308

Please sign in to comment.