From d95dd2777305b2b457e762e14e76faa76e6a2c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saugat=20Pachhai=20=28=E0=A4=B8=E0=A5=8C=E0=A4=97=E0=A4=BE?= =?UTF-8?q?=E0=A4=A4=29?= Date: Tue, 23 Nov 2021 21:37:40 +0545 Subject: [PATCH] scm: map internal SCMError to DVC's exception type --- dvc/external_repo.py | 2 ++ dvc/repo/__init__.py | 5 ++++- dvc/repo/experiments/__init__.py | 4 +++- dvc/scm/__init__.py | 23 +++++++++++++++++------ dvc/scm/git/__init__.py | 7 +++++-- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/dvc/external_repo.py b/dvc/external_repo.py index 37f02cc40..e239cb1d2 100644 --- a/dvc/external_repo.py +++ b/dvc/external_repo.py @@ -16,12 +16,14 @@ from dvc.exceptions import ( PathMissingError, ) from dvc.repo import Repo +from dvc.scm import map_scm_exception from dvc.utils import relpath logger = logging.getLogger(__name__) @contextmanager +@map_scm_exception() def external_repo( url, rev=None, for_write=False, cache_dir=None, cache_types=None, **kwargs ): diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index 3a44bf0c4..d34fd2f9f 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -286,7 +286,10 @@ class Repo: assert self.scm if isinstance(self.fs, LocalFileSystem): - return self.scm.get_rev() + from dvc.scm import map_scm_exception + + with map_scm_exception(): + return self.scm.get_rev() return self.fs.rev @cached_property diff --git a/dvc/repo/experiments/__init__.py b/dvc/repo/experiments/__init__.py index 417c85178..64fa900ea 100644 --- a/dvc/repo/experiments/__init__.py +++ b/dvc/repo/experiments/__init__.py @@ -42,7 +42,9 @@ def scm_locked(f): # different sequences of git operations at once @wraps(f) def wrapper(exp, *args, **kwargs): - with exp.scm_lock: + from dvc.scm import map_scm_exception + + with map_scm_exception(), exp.scm_lock: return f(exp, *args, **kwargs) return wrapper diff --git a/dvc/scm/__init__.py b/dvc/scm/__init__.py index a62b0185f..f1fe39e10 100644 --- a/dvc/scm/__init__.py +++ b/dvc/scm/__init__.py @@ -1,4 +1,6 @@ """Manages source control systems (e.g. Git).""" +from contextlib import contextmanager +from typing import Iterator from dvc.scm.base import Base, NoSCMError from dvc.scm.git import Git @@ -11,6 +13,20 @@ class NoSCM(Base): raise NoSCMError +@contextmanager +def map_scm_exception(with_cause: bool = False) -> Iterator[None]: + from dvc.scm.base import SCMError + from dvc.scm.exceptions import SCMError as InternalSCMError + + try: + yield + except InternalSCMError as exc: + into = SCMError(str(exc)) + if with_cause: + raise into from exc + raise into + + def SCM( root_dir, search_parent_directories=True, no_scm=False ): # pylint: disable=invalid-name @@ -26,17 +42,12 @@ def SCM( Returns: dvc.scm.base.Base: SCM instance. """ - from dvc.scm.base import SCMError - from dvc.scm.exceptions import SCMError as InternalSCMError - - try: + with map_scm_exception(): if no_scm: return NoSCM(root_dir) return Git( root_dir, search_parent_directories=search_parent_directories ) - except InternalSCMError as exc: - raise SCMError(str(exc)) def clone(url: str, to_path: str, **kwargs): diff --git a/dvc/scm/git/__init__.py b/dvc/scm/git/__init__.py index d66a7d71a..53942ace1 100644 --- a/dvc/scm/git/__init__.py +++ b/dvc/scm/git/__init__.py @@ -12,11 +12,14 @@ from funcy import cached_property, first from pathspec.patterns import GitWildMatchPattern from dvc.scm.base import Base -from dvc.scm.exceptions import FileNotInRepoError, RevError +from dvc.scm.exceptions import ( + FileNotInRepoError, + GitHookAlreadyExists, + RevError, +) from dvc.utils import relpath from dvc.utils.fs import path_isin -from ..exceptions import GitHookAlreadyExists from .backend.base import BaseGitBackend, NoGitBackendError from .backend.dulwich import DulwichBackend from .backend.gitpython import GitPythonBackend