Skip to content

Commit

Permalink
checkout: raise on non existing dir cache (#2514)
Browse files Browse the repository at this point in the history
* checkout: raise on non existing dir cache

* checkout: don't throw on failed load_dir_cache

* checkout: raise on failed checkouts, only after all checkouts are perfromed

* remote: base: raise on failed dir cache loading

* rename exception for failed checkout
  • Loading branch information
pared authored and efiop committed Sep 24, 2019
1 parent 7409fad commit be012e7
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 18 deletions.
10 changes: 10 additions & 0 deletions dvc/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,13 @@ def __init__(self, amount):
super(UploadError, self).__init__(
"{amount} files failed to upload".format(amount=amount)
)


class CheckoutError(DvcException):
def __init__(self, target_infos):
targets = [str(t) for t in target_infos]
m = (
"Checkout failed for following targets:\n {}\nDid you "
"forget to fetch?".format("\n".join(targets))
)
super(CheckoutError, self).__init__(m)
2 changes: 1 addition & 1 deletion dvc/output/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def checkout(self, force=False, progress_callback=None, tag=None):
else:
info = self.info

self.cache.checkout(
return self.cache.checkout(
self.path_info,
info,
force=force,
Expand Down
30 changes: 21 additions & 9 deletions dvc/remote/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ class RemoteMissingDepsError(DvcException):
pass


class DirCacheError(DvcException):
def __init__(self, checksum, cause=None):
super(DirCacheError, self).__init__(
"Failed to load dir cache for checksum: '{}'.".format(checksum),
cause=cause,
)


class RemoteBASE(object):
scheme = "base"
path_cls = URLInfo
Expand Down Expand Up @@ -256,7 +264,11 @@ def get_dir_cache(self, checksum):
if dir_info:
return dir_info

dir_info = self.load_dir_cache(checksum)
try:
dir_info = self.load_dir_cache(checksum)
except DirCacheError:
dir_info = []

self._dir_info[checksum] = dir_info
return dir_info

Expand All @@ -266,9 +278,8 @@ def load_dir_cache(self, checksum):
try:
with self.cache.open(path_info, "r") as fobj:
d = json.load(fobj)
except (ValueError, FileNotFoundError):
logger.exception("Failed to load dir cache '{}'".format(path_info))
return []
except (ValueError, FileNotFoundError) as exc:
raise DirCacheError(checksum, cause=exc)

if not isinstance(d, list):
msg = "dir cache file format error '{}' [skipping the file]"
Expand Down Expand Up @@ -848,32 +859,33 @@ def checkout(
raise NotImplementedError

checksum = checksum_info.get(self.PARAM_CHECKSUM)
skip = False
failed = None
if not checksum:
logger.warning(
"No checksum info found for '{}'. "
"It won't be created.".format(str(path_info))
)
self.safe_remove(path_info, force=force)
skip = True
failed = path_info

elif self.changed_cache(checksum):
msg = "Cache '{}' not found. File '{}' won't be created."
logger.warning(msg.format(checksum, str(path_info)))
self.safe_remove(path_info, force=force)
skip = True
failed = path_info

if skip:
if failed:
if progress_callback:
progress_callback(
str(path_info), self.get_files_number(checksum)
)
return
return failed

msg = "Checking out '{}' with cache '{}'."
logger.debug(msg.format(str(path_info), checksum))

self._checkout(path_info, checksum, force, progress_callback)
return None

def _checkout(
self, path_info, checksum, force=False, progress_callback=None
Expand Down
11 changes: 9 additions & 2 deletions dvc/repo/checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import logging

from dvc.exceptions import CheckoutErrorSuggestGit
from dvc.exceptions import CheckoutErrorSuggestGit, CheckoutError
from dvc.progress import Tqdm


Expand Down Expand Up @@ -42,6 +42,7 @@ def _checkout(
total = get_all_files_numbers(stages)
if total == 0:
logger.info("Nothing to do")
failed = []
with Tqdm(
total=total, unit="file", desc="Checkout", disable=total == 0
) as pbar:
Expand All @@ -54,4 +55,10 @@ def _checkout(
)
)

stage.checkout(force=force, progress_callback=pbar.update_desc)
failed.extend(
stage.checkout(
force=force, progress_callback=pbar.update_desc
)
)
if failed:
raise CheckoutError(failed)
6 changes: 5 additions & 1 deletion dvc/stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,10 +872,14 @@ def check_missing_outputs(self):
raise MissingDataSource(paths)

def checkout(self, force=False, progress_callback=None):
failed_checkouts = []
for out in self.outs:
out.checkout(
failed = out.checkout(
force=force, tag=self.tag, progress_callback=progress_callback
)
if failed:
failed_checkouts.append(failed)
return failed_checkouts

@staticmethod
def _status(entries):
Expand Down
4 changes: 3 additions & 1 deletion tests/func/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from dvc.cache import Cache
from dvc.main import main
from dvc.remote.base import DirCacheError
from dvc.utils import relpath

from tests.basic_env import TestDvc, TestDir
Expand Down Expand Up @@ -49,7 +50,8 @@ def test(self):
checksum = "123.dir"
fname = self.dvc.cache.local.get(checksum)
self.create(fname, "<clearly>not,json")
self._do_test(self.dvc.cache.local.load_dir_cache(checksum))
with pytest.raises(DirCacheError):
self.dvc.cache.local.load_dir_cache(checksum)

checksum = "234.dir"
fname = self.dvc.cache.local.get(checksum)
Expand Down
13 changes: 9 additions & 4 deletions tests/func/test_checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
ConfirmRemoveError,
TargetNotDirectoryError,
CheckoutErrorSuggestGit,
CheckoutError,
)

from mock import patch
Expand Down Expand Up @@ -74,7 +75,8 @@ def test(self):
with open(cache, "a") as fd:
fd.write("1")

self.dvc.checkout(force=True)
with pytest.raises(CheckoutError):
self.dvc.checkout(force=True)

self.assertFalse(os.path.isfile(self.FOO))
self.assertFalse(os.path.isfile(cache))
Expand All @@ -101,7 +103,8 @@ def test(self):
with open(cache, "w+") as fobj:
fobj.write("1")

self.dvc.checkout(force=True)
with pytest.raises(CheckoutError):
self.dvc.checkout(force=True)

self.assertFalse(os.path.exists(cache))

Expand Down Expand Up @@ -302,7 +305,8 @@ def test(self):
del d[Stage.PARAM_DEPS][0][RemoteLOCAL.PARAM_CHECKSUM]
dump_stage_file(self.file1_stage, d)

self.dvc.checkout(force=True)
with pytest.raises(CheckoutError):
self.dvc.checkout(force=True)


class TestCheckoutEmptyDir(TestDvc):
Expand Down Expand Up @@ -476,7 +480,8 @@ def test(self):

def test_checkout_no_checksum(repo_dir, dvc_repo):
stage = dvc_repo.run(outs=[repo_dir.FOO], no_exec=True, cmd="somecmd")
dvc_repo.checkout(stage.path, force=True)
with pytest.raises(CheckoutError):
dvc_repo.checkout(stage.path, force=True)
assert not os.path.exists(repo_dir.FOO)


Expand Down

0 comments on commit be012e7

Please sign in to comment.