From e177f041c8384e4e4e5d600a6dd633540bc8be92 Mon Sep 17 00:00:00 2001 From: Karthikeyan Singaravelan Date: Tue, 3 May 2022 13:59:15 +0530 Subject: [PATCH] Fail on sync when there is no match for glob. --- dvc/exceptions.py | 6 ++++++ dvc/repo/pull.py | 4 ++++ dvc/repo/push.py | 9 ++++++++- tests/func/test_import.py | 21 ++++++++++++++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dvc/exceptions.py b/dvc/exceptions.py index 127d46362..26afde585 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -349,3 +349,9 @@ class CircularImportError(DvcException): class PrettyDvcException(DvcException): def __pretty_exc__(self, **kwargs): """Print prettier exception message.""" + + +class GlobDoesNotMatchError(DvcException): + def __init__(self, glob): + msg = f"Glob {glob} has no matches." + super().__init__(msg) diff --git a/dvc/repo/pull.py b/dvc/repo/pull.py index b4f472933..3639a89b6 100644 --- a/dvc/repo/pull.py +++ b/dvc/repo/pull.py @@ -1,6 +1,7 @@ import logging from typing import TYPE_CHECKING, Optional +from dvc.exceptions import GlobDoesNotMatchError from dvc.repo import locked from dvc.utils import glob_targets @@ -31,6 +32,9 @@ def pull( expanded_targets = glob_targets(targets, glob=glob) + if targets and not expanded_targets: + raise GlobDoesNotMatchError(targets) + processed_files_count = self.fetch( expanded_targets, jobs, diff --git a/dvc/repo/push.py b/dvc/repo/push.py index 25a9b3692..2d9a7fbd1 100644 --- a/dvc/repo/push.py +++ b/dvc/repo/push.py @@ -1,6 +1,10 @@ from typing import TYPE_CHECKING, Optional -from dvc.exceptions import FileTransferError, UploadError +from dvc.exceptions import ( + FileTransferError, + GlobDoesNotMatchError, + UploadError, +) from ..utils import glob_targets from . import locked @@ -35,6 +39,9 @@ def push( expanded_targets = glob_targets(targets, glob=glob) + if targets and not expanded_targets: + raise GlobDoesNotMatchError(targets) + used = self.used_objs( expanded_targets, all_branches=all_branches, diff --git a/tests/func/test_import.py b/tests/func/test_import.py index 1c9dd986e..afa46592e 100644 --- a/tests/func/test_import.py +++ b/tests/func/test_import.py @@ -9,7 +9,11 @@ from scmrepo.git import Git from dvc.config import NoRemoteError from dvc.data.db import ODBManager from dvc.dvcfile import Dvcfile -from dvc.exceptions import DownloadError, PathMissingError +from dvc.exceptions import ( + DownloadError, + GlobDoesNotMatchError, + PathMissingError, +) from dvc.stage.exceptions import StagePathNotFoundError from dvc.system import System from dvc.utils.fs import makedirs, remove @@ -266,6 +270,21 @@ def test_pull_wildcard_imported_directory_stage(tmp_dir, dvc, erepo_dir): assert (tmp_dir / "dir_imported123").read_text() == {"foo": "foo content"} +def test_push_pull_glob_no_match( + tmp_dir, dvc, erepo_dir, run_copy, local_remote +): + tmp_dir.gen("foo", "foo") + erepo_dir.add_remote(config=local_remote.config) + + with erepo_dir.chdir(): + with pytest.raises(GlobDoesNotMatchError): + dvc.push(targets="b*", glob=True) + + with pytest.raises(GlobDoesNotMatchError): + dvc.pull(targets="b*", glob=True) + assert not os.path.exists(erepo_dir.dvc.stage_cache.cache_dir) + + def test_push_wildcard_from_bare_git_repo( tmp_dir, make_tmp_dir, erepo_dir, local_cloud ):