diff --git a/dvc/exceptions.py b/dvc/exceptions.py index 2916066146..92f46a8829 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -59,10 +59,12 @@ class OutputNotFoundError(DvcException): output (unicode): path to the file/directory. """ - def __init__(self, output): + def __init__(self, output, repo=None): + self.output = output + self.repo = repo super(OutputNotFoundError, self).__init__( "unable to find DVC-file with output '{path}'".format( - path=relpath(output) + path=relpath(self.output) ) ) @@ -338,3 +340,12 @@ def __init__(self, url, cause=None): ), cause=cause, ) + + +class NoOutputInExternalRepoError(DvcException): + def __init__(self, path, external_repo_path, external_repo_url): + super(NoOutputInExternalRepoError, self).__init__( + "Output '{}' not found in target repository '{}'".format( + relpath(path, external_repo_path), external_repo_url + ) + ) diff --git a/dvc/external_repo.py b/dvc/external_repo.py index 46657fc4d7..0555f2d756 100644 --- a/dvc/external_repo.py +++ b/dvc/external_repo.py @@ -9,6 +9,8 @@ from dvc.config import NoRemoteError from dvc.exceptions import RemoteNotSpecifiedInExternalRepoError +from dvc.exceptions import NoOutputInExternalRepoError +from dvc.exceptions import OutputNotFoundError from dvc.utils.fs import remove @@ -25,6 +27,10 @@ def external_repo(url=None, rev=None, rev_lock=None, cache_dir=None): yield repo except NoRemoteError as exc: raise RemoteNotSpecifiedInExternalRepoError(url, cause=exc) + except OutputNotFoundError as exc: + if exc.repo is repo: + raise NoOutputInExternalRepoError(exc.output, repo.root_dir, url) + raise repo.close() diff --git a/dvc/repo/__init__.py b/dvc/repo/__init__.py index e0003b8087..9f6284ef48 100644 --- a/dvc/repo/__init__.py +++ b/dvc/repo/__init__.py @@ -435,7 +435,7 @@ def func(out): matched = list(filter(func, outs)) if not matched: - raise OutputNotFoundError(path) + raise OutputNotFoundError(path, self) return matched diff --git a/tests/func/test_import.py b/tests/func/test_import.py index 06e8f8c830..067d5be8eb 100644 --- a/tests/func/test_import.py +++ b/tests/func/test_import.py @@ -8,7 +8,7 @@ from mock import patch from dvc.config import Config -from dvc.exceptions import DownloadError +from dvc.exceptions import DownloadError, NoOutputInExternalRepoError from dvc.stage import Stage from dvc.system import System from dvc.utils import makedirs @@ -154,3 +154,8 @@ def test_pull_non_workspace(git, dvc_repo, erepo): os.remove(stage.outs[0].cache_path) dvc_repo.fetch(all_tags=True) assert os.path.exists(stage.outs[0].cache_path) + + +def test_import_non_existing(dvc_repo, erepo): + with pytest.raises(NoOutputInExternalRepoError): + dvc_repo.imp(erepo.root_dir, "invalid_output")