From 71d156ac49c5fdbe88694c7148a23a10ff6e0b60 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Thu, 30 Apr 2020 17:16:16 +0300 Subject: [PATCH] run: try to save deps before running the command (#3709) Unlike old `_check_missing_deps`, this also verifies that we are able to save more complex dependencies such as parameters, where we not only care about the config file, but also about the parameters in it. Fixes #3707 --- dvc/stage/__init__.py | 18 ++++++------------ dvc/stage/exceptions.py | 9 --------- tests/func/test_run_single_stage.py | 5 +++-- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/dvc/stage/__init__.py b/dvc/stage/__init__.py index 6c78c65de..e1c629abd 100644 --- a/dvc/stage/__init__.py +++ b/dvc/stage/__init__.py @@ -21,7 +21,6 @@ from .exceptions import ( StagePathNotDirectoryError, StageCommitError, StageUpdateError, - MissingDep, MissingDataSource, ) from . import params @@ -374,8 +373,7 @@ class Stage(params.StageParams): # NOTE: need to save checksums for deps in order to compare them # with what is written in the old stage. - for dep in self.deps: - dep.save() + self._save_deps() old_d = old.dumpd() new_d = self.dumpd() @@ -482,10 +480,13 @@ class Stage(params.StageParams): logger.debug("Computed {} md5: '{}'".format(self, m)) return m - def save(self): + def _save_deps(self): for dep in self.deps: dep.save() + def save(self): + self._save_deps() + for out in self.outs: out.save() @@ -526,12 +527,6 @@ class Stage(params.StageParams): for out in self.outs: out.commit() - def _check_missing_deps(self): - missing = [dep for dep in self.deps if not dep.exists] - - if any(missing): - raise MissingDep(missing) - @staticmethod def _warn_if_fish(executable): # pragma: no cover if ( @@ -570,8 +565,6 @@ class Stage(params.StageParams): @unlocked_repo def _run(self): - self._check_missing_deps() - kwargs = {"cwd": self.wdir, "env": fix_env(None), "close_fds": True} if os.name == "nt": @@ -667,6 +660,7 @@ class Stage(params.StageParams): logger.info("Stage is cached, skipping.") self.checkout() else: + self._save_deps() logger.info("Running command:\n\t{}".format(self.cmd)) self._run() diff --git a/dvc/stage/exceptions.py b/dvc/stage/exceptions.py index 3049826c4..4d10bc40f 100644 --- a/dvc/stage/exceptions.py +++ b/dvc/stage/exceptions.py @@ -73,15 +73,6 @@ class StageUpdateError(DvcException): ) -class MissingDep(DvcException): - def __init__(self, deps): - assert len(deps) > 0 - - dep = "dependencies" if len(deps) > 1 else "dependency" - msg = "missing '{}': {}".format(dep, ", ".join(map(str, deps))) - super().__init__(msg) - - class MissingDataSource(DvcException): def __init__(self, missing_files): assert len(missing_files) > 0 diff --git a/tests/func/test_run_single_stage.py b/tests/func/test_run_single_stage.py index a5e9a34d7..049aa5ed0 100644 --- a/tests/func/test_run_single_stage.py +++ b/tests/func/test_run_single_stage.py @@ -26,7 +26,6 @@ from dvc.stage.exceptions import ( StagePathOutsideError, StagePathNotFoundError, StagePathNotDirectoryError, - MissingDep, ) from dvc.system import System from dvc.utils import file_md5 @@ -79,7 +78,9 @@ class TestRunEmpty(TestDvc): class TestRunMissingDep(TestDvc): def test(self): - with self.assertRaises(MissingDep): + from dvc.dependency.base import DependencyDoesNotExistError + + with self.assertRaises(DependencyDoesNotExistError): self.dvc.run( cmd="", deps=["non-existing-dep"],