From b285780b5870c7991d2c6452ba44a053409c1502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sat, 21 Dec 2019 21:31:43 +0000 Subject: [PATCH 01/16] commands/update: add --rev option to update with a specific git revision --- dvc/command/update.py | 8 +++++++- dvc/dependency/repo.py | 7 +++++-- dvc/repo/update.py | 4 ++-- dvc/stage.py | 4 ++-- tests/func/test_update.py | 1 + tests/unit/command/test_update.py | 6 ++++-- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/dvc/command/update.py b/dvc/command/update.py index 2b800c9fe0..37201240db 100644 --- a/dvc/command/update.py +++ b/dvc/command/update.py @@ -16,7 +16,10 @@ def run(self): ret = 0 for target in self.args.targets: try: - self.repo.update(target) + self.repo.update( + target, + rev=self.args.rev, + ) except DvcException: logger.exception("failed to update '{}'.".format(target)) ret = 1 @@ -35,4 +38,7 @@ def add_parser(subparsers, parent_parser): update_parser.add_argument( "targets", nargs="+", help="DVC-files to update." ) + update_parser.add_argument( + "--rev", nargs="?", help="DVC repository git revision." + ) update_parser.set_defaults(func=CmdUpdate) diff --git a/dvc/dependency/repo.py b/dvc/dependency/repo.py index df35e45235..c8826bac4b 100644 --- a/dvc/dependency/repo.py +++ b/dvc/dependency/repo.py @@ -114,6 +114,9 @@ def download(self, to): self.def_path, self.def_repo[self.PARAM_URL] ) - def update(self): - with self._make_repo(rev_lock=None) as repo: + def update(self, rev): + with self._make_repo( + rev=rev, + rev_lock=None, + ) as repo: self.def_repo[self.PARAM_REV_LOCK] = repo.scm.get_rev() diff --git a/dvc/repo/update.py b/dvc/repo/update.py index 9533bb6d36..e6258d5903 100644 --- a/dvc/repo/update.py +++ b/dvc/repo/update.py @@ -2,10 +2,10 @@ @locked -def update(self, target): +def update(self, target, rev=None): from dvc.stage import Stage stage = Stage.load(self, target) - stage.update() + stage.update(rev=rev) stage.dump() diff --git a/dvc/stage.py b/dvc/stage.py index 236a5f2d39..62063d7c3e 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -395,11 +395,11 @@ def reproduce(self, interactive=False, **kwargs): return self - def update(self): + def update(self, rev=None): if not self.is_repo_import and not self.is_import: raise StageUpdateError(self.relpath) - self.deps[0].update() + self.deps[0].update(rev) locked = self.locked self.locked = False try: diff --git a/tests/func/test_update.py b/tests/func/test_update.py index 888bea9290..078e66d7f6 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -72,3 +72,4 @@ def test_update_import_url(repo_dir, dvc_repo): assert os.path.exists(dst) assert os.path.isfile(dst) assert filecmp.cmp(src, dst, shallow=False) + diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index c44def6fa6..febb60e80d 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -4,12 +4,14 @@ def test_update(dvc_repo, mocker): targets = ["target1", "target2", "target3"] - cli_args = parse_args(["update"] + targets) + cli_args = parse_args( + ["update", "--rev", "develop"] + targets + ) assert cli_args.func == CmdUpdate cmd = cli_args.func(cli_args) m = mocker.patch("dvc.repo.Repo.update") assert cmd.run() == 0 - calls = [mocker.call(target) for target in targets] + calls = [mocker.call(target, rev="develop") for target in targets] m.assert_has_calls(calls) From 95db0eac9eb0ffe1a337a5c42bc084572e4ebb35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Thu, 2 Jan 2020 02:13:54 +0000 Subject: [PATCH 02/16] commands/update: complete --rev feature and add tests --- dvc/dependency/base.py | 2 +- dvc/dependency/repo.py | 8 +++--- dvc/exceptions.py | 7 +++++ dvc/repo/update.py | 6 ++++ tests/func/test_update.py | 46 +++++++++++++++++++++++++++++++ tests/unit/command/test_update.py | 24 ++++++++++++++-- 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/dvc/dependency/base.py b/dvc/dependency/base.py index 4f52bf5d05..d7fd3d34b8 100644 --- a/dvc/dependency/base.py +++ b/dvc/dependency/base.py @@ -29,5 +29,5 @@ class DependencyBase(object): IsNotFileOrDirError = DependencyIsNotFileOrDirError IsStageFileError = DependencyIsStageFileError - def update(self): + def update(self, rev): pass diff --git a/dvc/dependency/repo.py b/dvc/dependency/repo.py index c8826bac4b..88dc2691e1 100644 --- a/dvc/dependency/repo.py +++ b/dvc/dependency/repo.py @@ -115,8 +115,8 @@ def download(self, to): ) def update(self, rev): - with self._make_repo( - rev=rev, - rev_lock=None, - ) as repo: + if not rev: + rev = self.def_repo.get("rev") + + with self._make_repo(rev=rev, rev_lock=None) as repo: self.def_repo[self.PARAM_REV_LOCK] = repo.scm.get_rev() diff --git a/dvc/exceptions.py b/dvc/exceptions.py index 7151e2e2fa..2cf33ed1a5 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -353,3 +353,10 @@ def __init__(self, path, repo): " neighther as an output nor a git-handled file." ) super(PathMissingError, self).__init__(msg.format(path, repo)) + + +class UpdateWithRevNotPossibleError(DvcException): + def __init__(self): + super(UpdateWithRevNotPossibleError, self).__init__( + "Revision option (--rev) is not a feature of non-Git sources." + ) diff --git a/dvc/repo/update.py b/dvc/repo/update.py index e6258d5903..910d95ce26 100644 --- a/dvc/repo/update.py +++ b/dvc/repo/update.py @@ -1,3 +1,5 @@ +from dvc.exceptions import UpdateWithRevNotPossibleError + from . import locked @@ -6,6 +8,10 @@ def update(self, target, rev=None): from dvc.stage import Stage stage = Stage.load(self, target) + + if not stage.is_repo_import and rev: + raise UpdateWithRevNotPossibleError() + stage.update(rev=rev) stage.dump() diff --git a/tests/func/test_update.py b/tests/func/test_update.py index 078e66d7f6..d3a9e957fc 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -1,7 +1,9 @@ import filecmp import os import shutil +import pytest +from dvc.exceptions import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos from dvc.repo import Repo @@ -73,3 +75,47 @@ def test_update_import_url(repo_dir, dvc_repo): assert os.path.isfile(dst) assert filecmp.cmp(src, dst, shallow=False) + +def test_update_rev(dvc_repo, erepo): + src = "version" + dst = src + + stage = dvc_repo.imp(erepo.root_dir, src, dst, rev="branch") + + # update data + repo = Repo(erepo.root_dir) + + saved_dir = os.getcwd() + os.chdir(erepo.root_dir) + + repo.scm.checkout("master") + os.unlink("version") + erepo.create("version", "updated") + repo.add("version") + repo.scm.add([".gitignore", "version.dvc"]) + repo.scm.commit("updated") + + repo.scm.close() + + os.chdir(saved_dir) + + # Caching in external repos doesn't see upstream updates within single + # cli call, so we need to clean the caches to see the changes. + clean_repos() + + dvc_repo.update(stage.path, "master") + + with open(dst, "r+") as fobj: + assert fobj.read() == "updated" + + +def test_update_rev_non_git_failure(repo_dir, dvc_repo): + src = "file" + dst = src + "_imported" + + shutil.copyfile(repo_dir.FOO, src) + + stage = dvc_repo.imp_url(src, dst) + + with pytest.raises(UpdateWithRevNotPossibleError): + dvc_repo.update(stage.path, rev="dev") diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index febb60e80d..5da3d20b22 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -1,12 +1,13 @@ +import logging + from dvc.cli import parse_args from dvc.command.update import CmdUpdate +from dvc.exceptions import UpdateWithRevNotPossibleError def test_update(dvc_repo, mocker): targets = ["target1", "target2", "target3"] - cli_args = parse_args( - ["update", "--rev", "develop"] + targets - ) + cli_args = parse_args(["update", "--rev", "develop"] + targets) assert cli_args.func == CmdUpdate cmd = cli_args.func(cli_args) m = mocker.patch("dvc.repo.Repo.update") @@ -15,3 +16,20 @@ def test_update(dvc_repo, mocker): calls = [mocker.call(target, rev="develop") for target in targets] m.assert_has_calls(calls) + + +def test_update_rev_failed(mocker, caplog, dvc_repo): + targets = ["target1", "target2", "target3"] + cli_args = parse_args(["update", "--rev", "develop"] + targets) + assert cli_args.func == CmdUpdate + + cmd = cli_args.func(cli_args) + with mocker.patch.object( + cmd.repo, "update", side_effect=UpdateWithRevNotPossibleError() + ): + with caplog.at_level(logging.ERROR, logger="dvc"): + assert cmd.run() == 1 + expected_error = ( + "Revision option (--rev) is not a feature of non-Git sources." + ) + assert expected_error in caplog.text From beab3d59ee2d182abfe3e810d8f74d2d9681d19e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Thu, 2 Jan 2020 15:41:49 +0300 Subject: [PATCH 03/16] cosmetic updates --- dvc/command/update.py | 5 +---- tests/unit/command/test_update.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dvc/command/update.py b/dvc/command/update.py index 37201240db..7a5bb82316 100644 --- a/dvc/command/update.py +++ b/dvc/command/update.py @@ -16,10 +16,7 @@ def run(self): ret = 0 for target in self.args.targets: try: - self.repo.update( - target, - rev=self.args.rev, - ) + self.repo.update(target, rev=self.args.rev) except DvcException: logger.exception("failed to update '{}'.".format(target)) ret = 1 diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 5da3d20b22..7032e10493 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -18,7 +18,7 @@ def test_update(dvc_repo, mocker): m.assert_has_calls(calls) -def test_update_rev_failed(mocker, caplog, dvc_repo): +def test_update_rev_failed(mocker, caplog): targets = ["target1", "target2", "target3"] cli_args = parse_args(["update", "--rev", "develop"] + targets) assert cli_args.func == CmdUpdate From 9d68c8aa61b818a1eb00fd8133589e94767de659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Thu, 2 Jan 2020 17:04:43 +0000 Subject: [PATCH 04/16] commands/update: do validation for update with --rev inside Stage --- dvc/dependency/repo.py | 2 +- dvc/exceptions.py | 7 ------- dvc/repo/update.py | 5 ----- dvc/stage.py | 10 ++++++++++ tests/func/test_update.py | 2 +- tests/unit/command/test_update.py | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/dvc/dependency/repo.py b/dvc/dependency/repo.py index 88dc2691e1..c5010e2fa6 100644 --- a/dvc/dependency/repo.py +++ b/dvc/dependency/repo.py @@ -114,7 +114,7 @@ def download(self, to): self.def_path, self.def_repo[self.PARAM_URL] ) - def update(self, rev): + def update(self, rev=None): if not rev: rev = self.def_repo.get("rev") diff --git a/dvc/exceptions.py b/dvc/exceptions.py index 2cf33ed1a5..7151e2e2fa 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -353,10 +353,3 @@ def __init__(self, path, repo): " neighther as an output nor a git-handled file." ) super(PathMissingError, self).__init__(msg.format(path, repo)) - - -class UpdateWithRevNotPossibleError(DvcException): - def __init__(self): - super(UpdateWithRevNotPossibleError, self).__init__( - "Revision option (--rev) is not a feature of non-Git sources." - ) diff --git a/dvc/repo/update.py b/dvc/repo/update.py index 910d95ce26..c980e868b7 100644 --- a/dvc/repo/update.py +++ b/dvc/repo/update.py @@ -1,5 +1,3 @@ -from dvc.exceptions import UpdateWithRevNotPossibleError - from . import locked @@ -9,9 +7,6 @@ def update(self, target, rev=None): stage = Stage.load(self, target) - if not stage.is_repo_import and rev: - raise UpdateWithRevNotPossibleError() - stage.update(rev=rev) stage.dump() diff --git a/dvc/stage.py b/dvc/stage.py index 62063d7c3e..d8048385b5 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -132,6 +132,13 @@ def __init__(self, missing_files): super(MissingDataSource, self).__init__(msg) +class UpdateWithRevNotPossibleError(DvcException): + def __init__(self): + super(UpdateWithRevNotPossibleError, self).__init__( + "Revision option (--rev) is not a feature of non-Git sources." + ) + + @decorator def rwlocked(call, read=None, write=None): import sys @@ -399,6 +406,9 @@ def update(self, rev=None): if not self.is_repo_import and not self.is_import: raise StageUpdateError(self.relpath) + if not self.is_repo_import and rev: + raise UpdateWithRevNotPossibleError() + self.deps[0].update(rev) locked = self.locked self.locked = False diff --git a/tests/func/test_update.py b/tests/func/test_update.py index d3a9e957fc..fef7e91199 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -3,7 +3,7 @@ import shutil import pytest -from dvc.exceptions import UpdateWithRevNotPossibleError +from dvc.stage import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos from dvc.repo import Repo diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 7032e10493..51d0eefbba 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -2,7 +2,7 @@ from dvc.cli import parse_args from dvc.command.update import CmdUpdate -from dvc.exceptions import UpdateWithRevNotPossibleError +from dvc.stage import UpdateWithRevNotPossibleError def test_update(dvc_repo, mocker): From 386b25ecf88d5c547b5a4bd4c928176f7689ec8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96zt=C3=BCrk?= Date: Sat, 4 Jan 2020 22:45:53 +0300 Subject: [PATCH 05/16] commands/update: cosmetic updates & update docs Co-Authored-By: Jorge Orpinel Co-Authored-By: Ruslan Kuprieiev --- dvc/command/update.py | 2 +- dvc/dependency/base.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dvc/command/update.py b/dvc/command/update.py index 7a5bb82316..70e9ce8b98 100644 --- a/dvc/command/update.py +++ b/dvc/command/update.py @@ -36,6 +36,6 @@ def add_parser(subparsers, parent_parser): "targets", nargs="+", help="DVC-files to update." ) update_parser.add_argument( - "--rev", nargs="?", help="DVC repository git revision." + "--rev", nargs="?", help="Git revision in repository to update from." ) update_parser.set_defaults(func=CmdUpdate) diff --git a/dvc/dependency/base.py b/dvc/dependency/base.py index d7fd3d34b8..9341137af6 100644 --- a/dvc/dependency/base.py +++ b/dvc/dependency/base.py @@ -29,5 +29,5 @@ class DependencyBase(object): IsNotFileOrDirError = DependencyIsNotFileOrDirError IsStageFileError = DependencyIsStageFileError - def update(self, rev): + def update(self, rev=None): pass From 32494bb7cfda45e7705fbca8ad00cab167757a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sat, 4 Jan 2020 20:54:41 +0000 Subject: [PATCH 06/16] commands/update: cosmetic updates related to --rev option * small refactoring on the related test to use new testing util. --- dvc/command/imp.py | 2 +- tests/func/test_update.py | 41 ++++++++++++--------------------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/dvc/command/imp.py b/dvc/command/imp.py index 452a481d5f..ba39cccdb9 100644 --- a/dvc/command/imp.py +++ b/dvc/command/imp.py @@ -52,6 +52,6 @@ def add_parser(subparsers, parent_parser): "-o", "--out", nargs="?", help="Destination path to put data to." ) import_parser.add_argument( - "--rev", nargs="?", help="DVC repository git revision." + "--rev", nargs="?", help="Git revision in repository to update from." ) import_parser.set_defaults(func=CmdImport) diff --git a/tests/func/test_update.py b/tests/func/test_update.py index fef7e91199..ea428497a3 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -6,6 +6,7 @@ from dvc.stage import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos from dvc.repo import Repo +from dvc.utils.compat import fspath def test_update_import(dvc_repo, erepo): @@ -76,37 +77,19 @@ def test_update_import_url(repo_dir, dvc_repo): assert filecmp.cmp(src, dst, shallow=False) -def test_update_rev(dvc_repo, erepo): - src = "version" - dst = src - - stage = dvc_repo.imp(erepo.root_dir, src, dst, rev="branch") - - # update data - repo = Repo(erepo.root_dir) +def test_update_rev(tmp_dir, scm, dvc, erepo_dir, monkeypatch): + with monkeypatch.context() as m: + m.chdir(fspath(erepo_dir)) + erepo_dir.scm.checkout("feature", create_new=True) + erepo_dir.dvc_gen( + "foo", "foo content", commit="create foo on feature branch" + ) + erepo_dir.scm.checkout("master") - saved_dir = os.getcwd() - os.chdir(erepo.root_dir) + stage = dvc.imp(fspath(erepo_dir), "foo", "foo_imported") + dvc.update(stage.path, rev="feature") - repo.scm.checkout("master") - os.unlink("version") - erepo.create("version", "updated") - repo.add("version") - repo.scm.add([".gitignore", "version.dvc"]) - repo.scm.commit("updated") - - repo.scm.close() - - os.chdir(saved_dir) - - # Caching in external repos doesn't see upstream updates within single - # cli call, so we need to clean the caches to see the changes. - clean_repos() - - dvc_repo.update(stage.path, "master") - - with open(dst, "r+") as fobj: - assert fobj.read() == "updated" + assert (tmp_dir / "foo_imported").read_text() == "foo content" def test_update_rev_non_git_failure(repo_dir, dvc_repo): From a9fa7975128aa46bb8a9ffe91a879c82380eabed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sun, 5 Jan 2020 00:04:04 +0300 Subject: [PATCH 07/16] commands/update: update docs related to --rev option --- dvc/stage.py | 2 +- tests/unit/command/test_update.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dvc/stage.py b/dvc/stage.py index d8048385b5..294d4bf10f 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -135,7 +135,7 @@ def __init__(self, missing_files): class UpdateWithRevNotPossibleError(DvcException): def __init__(self): super(UpdateWithRevNotPossibleError, self).__init__( - "Revision option (--rev) is not a feature of non-Git sources." + "Revision option (`--rev`) is not a feature of non-Git sources." ) diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 51d0eefbba..4ae24ff7c0 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -30,6 +30,6 @@ def test_update_rev_failed(mocker, caplog): with caplog.at_level(logging.ERROR, logger="dvc"): assert cmd.run() == 1 expected_error = ( - "Revision option (--rev) is not a feature of non-Git sources." + "Revision option (`--rev`) is not a feature of non-Git sources." ) assert expected_error in caplog.text From 9a04fbd95ca8aa117c587532b05beb77e2178c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sun, 5 Jan 2020 00:15:26 +0300 Subject: [PATCH 08/16] commands/update: satisfy linter for code related to --rev option --- tests/unit/command/test_update.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 4ae24ff7c0..ce72525f6e 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -29,7 +29,5 @@ def test_update_rev_failed(mocker, caplog): ): with caplog.at_level(logging.ERROR, logger="dvc"): assert cmd.run() == 1 - expected_error = ( - "Revision option (`--rev`) is not a feature of non-Git sources." - ) + expected_error = "Revision option (`--rev`) is not a feature of non-Git sources." assert expected_error in caplog.text From f9e5cc93cb1a6020b4a5c784cceec45915e4f2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sun, 5 Jan 2020 00:19:00 +0300 Subject: [PATCH 09/16] commands/update: cosmetic updates related to --rev option --- tests/func/test_update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/func/test_update.py b/tests/func/test_update.py index ea428497a3..336d6fde07 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -77,7 +77,7 @@ def test_update_import_url(repo_dir, dvc_repo): assert filecmp.cmp(src, dst, shallow=False) -def test_update_rev(tmp_dir, scm, dvc, erepo_dir, monkeypatch): +def test_update_rev(tmp_dir, dvc, erepo_dir, monkeypatch): with monkeypatch.context() as m: m.chdir(fspath(erepo_dir)) erepo_dir.scm.checkout("feature", create_new=True) From 1562ca4df5458fdcdecba099cba35ed371bc012d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sat, 4 Jan 2020 23:41:58 +0000 Subject: [PATCH 10/16] commands/update: move 'is repo check' for --rev to lower level --- dvc/dependency/base.py | 4 +++- dvc/exceptions.py | 7 +++++++ dvc/stage.py | 10 ---------- tests/func/test_update.py | 2 +- tests/unit/command/test_update.py | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dvc/dependency/base.py b/dvc/dependency/base.py index 9341137af6..48a9cba0ea 100644 --- a/dvc/dependency/base.py +++ b/dvc/dependency/base.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from dvc.exceptions import DvcException +from dvc.exceptions import UpdateWithRevNotPossibleError class DependencyDoesNotExistError(DvcException): @@ -30,4 +31,5 @@ class DependencyBase(object): IsStageFileError = DependencyIsStageFileError def update(self, rev=None): - pass + if rev: + raise UpdateWithRevNotPossibleError() diff --git a/dvc/exceptions.py b/dvc/exceptions.py index 7151e2e2fa..c9a0ff36d4 100644 --- a/dvc/exceptions.py +++ b/dvc/exceptions.py @@ -353,3 +353,10 @@ def __init__(self, path, repo): " neighther as an output nor a git-handled file." ) super(PathMissingError, self).__init__(msg.format(path, repo)) + + +class UpdateWithRevNotPossibleError(DvcException): + def __init__(self): + super(UpdateWithRevNotPossibleError, self).__init__( + "Revision option (`--rev`) is not a feature of non-Git sources." + ) diff --git a/dvc/stage.py b/dvc/stage.py index 294d4bf10f..62063d7c3e 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -132,13 +132,6 @@ def __init__(self, missing_files): super(MissingDataSource, self).__init__(msg) -class UpdateWithRevNotPossibleError(DvcException): - def __init__(self): - super(UpdateWithRevNotPossibleError, self).__init__( - "Revision option (`--rev`) is not a feature of non-Git sources." - ) - - @decorator def rwlocked(call, read=None, write=None): import sys @@ -406,9 +399,6 @@ def update(self, rev=None): if not self.is_repo_import and not self.is_import: raise StageUpdateError(self.relpath) - if not self.is_repo_import and rev: - raise UpdateWithRevNotPossibleError() - self.deps[0].update(rev) locked = self.locked self.locked = False diff --git a/tests/func/test_update.py b/tests/func/test_update.py index 336d6fde07..09ac17140c 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -3,7 +3,7 @@ import shutil import pytest -from dvc.stage import UpdateWithRevNotPossibleError +from dvc.exceptions import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos from dvc.repo import Repo from dvc.utils.compat import fspath diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index ce72525f6e..6002511671 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -2,7 +2,7 @@ from dvc.cli import parse_args from dvc.command.update import CmdUpdate -from dvc.stage import UpdateWithRevNotPossibleError +from dvc.exceptions import UpdateWithRevNotPossibleError def test_update(dvc_repo, mocker): From 4fe900f67bb47609bcbae6b087ff569eebd9d1ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sun, 5 Jan 2020 03:03:03 +0300 Subject: [PATCH 11/16] commands/update: satisfy linter --- tests/unit/command/test_update.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 6002511671..01ea1a57ff 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -29,5 +29,8 @@ def test_update_rev_failed(mocker, caplog): ): with caplog.at_level(logging.ERROR, logger="dvc"): assert cmd.run() == 1 - expected_error = "Revision option (`--rev`) is not a feature of non-Git sources." + expected_error = ( + "Revision option (`--rev`) is not a feature" + "of non-Git sources." + ) assert expected_error in caplog.text From 5f61f0ce97835ebd43ab69747c6348409437555f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Sun, 5 Jan 2020 03:21:17 +0300 Subject: [PATCH 12/16] commands/update: fix tests --- tests/unit/command/test_update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 01ea1a57ff..510f2151d9 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -31,6 +31,6 @@ def test_update_rev_failed(mocker, caplog): assert cmd.run() == 1 expected_error = ( "Revision option (`--rev`) is not a feature" - "of non-Git sources." + " of non-Git sources." ) assert expected_error in caplog.text From f3eb2cd6d8c300ffc39b62be7a364985e68633e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96zt=C3=BCrk?= Date: Sun, 5 Jan 2020 03:41:49 +0300 Subject: [PATCH 13/16] commands/update: import path of a test Co-Authored-By: Ruslan Kuprieiev --- tests/func/test_update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/func/test_update.py b/tests/func/test_update.py index 09ac17140c..abc0f201e4 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -6,7 +6,7 @@ from dvc.exceptions import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos from dvc.repo import Repo -from dvc.utils.compat import fspath +from dvc.compat import fspath def test_update_import(dvc_repo, erepo): From 2abf41c708edf5c889aa049f448e929dcb9660d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Wed, 15 Jan 2020 09:09:00 +0000 Subject: [PATCH 14/16] commands: --rev option: fix tests & rm an unneeded one --- tests/func/test_update.py | 13 ++++++++----- tests/unit/command/test_update.py | 21 --------------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/tests/func/test_update.py b/tests/func/test_update.py index abc0f201e4..7aecd43322 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -80,16 +80,19 @@ def test_update_import_url(repo_dir, dvc_repo): def test_update_rev(tmp_dir, dvc, erepo_dir, monkeypatch): with monkeypatch.context() as m: m.chdir(fspath(erepo_dir)) - erepo_dir.scm.checkout("feature", create_new=True) + erepo_dir.scm.checkout("new_branch", create_new=True) + erepo_dir.dvc_gen("foo", "foo content", commit="create foo on branch") + erepo_dir.scm.checkout("master") + erepo_dir.scm.checkout("new_branch_2", create_new=True) erepo_dir.dvc_gen( - "foo", "foo content", commit="create foo on feature branch" + "foo", "foo content 2", commit="create foo on branch" ) erepo_dir.scm.checkout("master") - stage = dvc.imp(fspath(erepo_dir), "foo", "foo_imported") - dvc.update(stage.path, rev="feature") + stage = dvc.imp(fspath(erepo_dir), "foo", "foo_imported", rev="new_branch") + dvc.update(stage.path, rev="new_branch_2") - assert (tmp_dir / "foo_imported").read_text() == "foo content" + assert (tmp_dir / "foo_imported").read_text() == "foo content 2" def test_update_rev_non_git_failure(repo_dir, dvc_repo): diff --git a/tests/unit/command/test_update.py b/tests/unit/command/test_update.py index 510f2151d9..b180623263 100644 --- a/tests/unit/command/test_update.py +++ b/tests/unit/command/test_update.py @@ -1,8 +1,5 @@ -import logging - from dvc.cli import parse_args from dvc.command.update import CmdUpdate -from dvc.exceptions import UpdateWithRevNotPossibleError def test_update(dvc_repo, mocker): @@ -16,21 +13,3 @@ def test_update(dvc_repo, mocker): calls = [mocker.call(target, rev="develop") for target in targets] m.assert_has_calls(calls) - - -def test_update_rev_failed(mocker, caplog): - targets = ["target1", "target2", "target3"] - cli_args = parse_args(["update", "--rev", "develop"] + targets) - assert cli_args.func == CmdUpdate - - cmd = cli_args.func(cli_args) - with mocker.patch.object( - cmd.repo, "update", side_effect=UpdateWithRevNotPossibleError() - ): - with caplog.at_level(logging.ERROR, logger="dvc"): - assert cmd.run() == 1 - expected_error = ( - "Revision option (`--rev`) is not a feature" - " of non-Git sources." - ) - assert expected_error in caplog.text From f56efc6b8aae8d9b426f4bfda35333e9bfabbaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Wed, 15 Jan 2020 20:11:03 +0300 Subject: [PATCH 15/16] fix merge master --- dvc/command/imp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvc/command/imp.py b/dvc/command/imp.py index 9d825420ad..a8ca6d27eb 100644 --- a/dvc/command/imp.py +++ b/dvc/command/imp.py @@ -52,7 +52,7 @@ def add_parser(subparsers, parent_parser): import_parser.add_argument( "-o", "--out", nargs="?", help="Destination path to download files to" ) - import_parser.add_argument + import_parser.add_argument( "--rev", nargs="?", help="Git revision in repository to update from." ) import_parser.set_defaults(func=CmdImport) \ No newline at end of file From e6a56f36b6fbc87154bd7ae62f26130dfaf0037e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20G=C3=B6ktu=C4=9F=20=C3=96ZT=C3=9CRK?= Date: Wed, 15 Jan 2020 20:14:10 +0300 Subject: [PATCH 16/16] satisfy linter --- dvc/command/imp.py | 2 +- tests/func/test_update.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dvc/command/imp.py b/dvc/command/imp.py index a8ca6d27eb..4b24985dcd 100644 --- a/dvc/command/imp.py +++ b/dvc/command/imp.py @@ -55,4 +55,4 @@ def add_parser(subparsers, parent_parser): import_parser.add_argument( "--rev", nargs="?", help="Git revision in repository to update from." ) - import_parser.set_defaults(func=CmdImport) \ No newline at end of file + import_parser.set_defaults(func=CmdImport) diff --git a/tests/func/test_update.py b/tests/func/test_update.py index 33411131f3..ed96b983c3 100644 --- a/tests/func/test_update.py +++ b/tests/func/test_update.py @@ -1,11 +1,8 @@ -import filecmp -import os import shutil import pytest from dvc.exceptions import UpdateWithRevNotPossibleError from dvc.external_repo import clean_repos -from dvc.repo import Repo from dvc.compat import fspath from dvc.stage import Stage @@ -105,4 +102,4 @@ def test_update_rev_non_git_failure(repo_dir, dvc_repo): stage = dvc_repo.imp_url(src, dst) with pytest.raises(UpdateWithRevNotPossibleError): - dvc_repo.update(stage.path, rev="dev") \ No newline at end of file + dvc_repo.update(stage.path, rev="dev")