diff --git a/dvc/cache.py b/dvc/cache.py index feec198f7..a211c5916 100644 --- a/dvc/cache.py +++ b/dvc/cache.py @@ -8,6 +8,8 @@ class Cache(object): def __init__(self, dvc_dir): self.cache_dir = os.path.abspath(os.path.realpath(os.path.join(dvc_dir, self.CACHE_DIR))) + if not os.path.exists(self.cache_dir): + os.mkdir(self.cache_dir) @staticmethod def init(dvc_dir): diff --git a/dvc/command/repro.py b/dvc/command/repro.py index c8bb524a9..08e5e7cfd 100644 --- a/dvc/command/repro.py +++ b/dvc/command/repro.py @@ -1,5 +1,6 @@ -from dvc.exceptions import DvcException from dvc.command.common.base import CmdBase +from dvc.project import ReproductionError + class CmdRepro(CmdBase): def run(self): @@ -9,8 +10,10 @@ class CmdRepro(CmdBase): self.project.reproduce(target, recursive=recursive, force=self.args.force) - except DvcException as ex: - msg = 'Failed to reproduce {}: {}'.format(target, str(ex)) + except ReproductionError as ex: + self.project.logger.error(ex) + except Exception as ex: + msg = 'Failed to reproduce \'{}\' - unexpected error: {}'.format(target, ex) self.project.logger.error(msg) return 1 return 0 diff --git a/dvc/project.py b/dvc/project.py index 5c5f9cad6..5e167d7e5 100644 --- a/dvc/project.py +++ b/dvc/project.py @@ -26,6 +26,13 @@ class StageNotFoundError(DvcException): super(StageNotFoundError, self).__init__(msg) +class ReproductionError(DvcException): + def __init__(self, dvc_file_name, msg): + self.dvc_file_name = dvc_file_name + self.msg = msg + super(ReproductionError, self).__init__(u'Failed to reproduce \'{}\': {}'.format(dvc_file_name, msg)) + + class Pipeline(object): def __init__(self, project, G): @@ -168,17 +175,12 @@ class Project(object): return stage def reproduce(self, target, recursive=True, force=False): - reproduced = [] stages = nx.get_node_attributes(self.graph(), 'stage') node = os.path.relpath(os.path.abspath(target), self.root_dir) if node not in stages: raise StageNotFoundError(target) - if recursive: - for n in nx.dfs_postorder_nodes(self.graph(), node): - stages[n].reproduce(force=force) - stages[n].dump() - reproduced.append(stages[n]) + reproduced = self._reproduce_stages(force, node, stages) if recursive else [] stages[node].reproduce(force=force) stages[node].dump() @@ -186,6 +188,17 @@ class Project(object): return reproduced + def _reproduce_stages(self, force, node, stages): + result = [] + for n in nx.dfs_postorder_nodes(self.graph(), node): + try: + stages[n].reproduce(force=force) + stages[n].dump() + result.append(stages[n]) + except Exception as ex: + raise ReproductionError(n, ex.message) + return result + def checkout(self): for stage in self.stages(): stage.checkout()