diff --git a/dvc/command/metrics.py b/dvc/command/metrics.py index fae601c4f..8d3e746f7 100644 --- a/dvc/command/metrics.py +++ b/dvc/command/metrics.py @@ -1,25 +1,43 @@ from dvc.command.common.base import CmdBase +from dvc.exceptions import DvcException class CmdMetricsShow(CmdBase): def run(self): - self.project.metrics_show(self.args.path, - json_path=self.args.json_path, - tsv_path=self.args.tsv_path, - htsv_path=self.args.htsv_path, - csv_path=self.args.csv_path, - hcsv_path=self.args.hcsv_path, - all_branches=self.args.all_branches) + try: + self.project.metrics_show(self.args.path, + json_path=self.args.json_path, + tsv_path=self.args.tsv_path, + htsv_path=self.args.htsv_path, + csv_path=self.args.csv_path, + hcsv_path=self.args.hcsv_path, + all_branches=self.args.all_branches) + except DvcException as exc: + self.project.logger.error('Failed to show metrics', exc) + return 1 + return 0 class CmdMetricsAdd(CmdBase): def run(self): - self.project.metrics_add(self.args.path) + try: + self.project.metrics_add(self.args.path) + except DvcException as exc: + msg = 'Failed to add metric file \'{}\''.format(self.args.path) + self.project.logger.error(msg, exc) + return 1 + return 0 class CmdMetricsRemove(CmdBase): def run(self): - self.project.metrics_remove(self.args.path) + try: + self.project.metrics_remove(self.args.path) + except DvcException as exc: + msg = 'Failed to remove metric file \'{}\''.format(self.args.path) + self.project.logger.error(msg, exc) + return 1 + return 0 diff --git a/dvc/project.py b/dvc/project.py index 38ad4473f..03e082364 100644 --- a/dvc/project.py +++ b/dvc/project.py @@ -488,15 +488,27 @@ class Project(object): for fname, metric in val.items(): self.logger.info('\t{}: {}'.format(fname, metric)) - return res + if res: + return res + + + if path: + msg = 'File \'{}\' does not exist'.format(path) + else: + msg = 'No metric files in this repository. ' \ + 'Use \'dvc metrics add\' to add a metric file to track.' + raise DvcException(msg) def _metrics_modify(self, path, val): apath = os.path.abspath(path) + found = False for stage in self.stages(): for out in stage.outs: if apath != out.path: continue + found = True + if out.path_info['scheme'] != 'local': msg = 'Output \'{}\' scheme \'{}\' is not supported for metrics' raise DvcException(msg.format(out.path, out.path_info['scheme'])) @@ -510,6 +522,10 @@ class Project(object): stage.dump() + if not found: + msg = 'Unable to find file \'{}\' in the pipeline'.format(path) + raise DvcException(msg) + def metrics_add(self, path): self._metrics_modify(path, True) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 921152044..e918002e7 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -89,7 +89,7 @@ class TestMetricsReproCLI(TestDvc): self.assertEqual(ret, 0) ret = main(['repro', '-f', '-m', stage.path]) - self.assertEqual(ret, 0) + self.assertNotEqual(ret, 0) def test_dir(self): os.mkdir('metrics_dir') @@ -140,3 +140,16 @@ class TestMetricsCLI(TestMetrics): with self.assertRaises(DvcException): self.dvc.run(outs_no_cache=['metrics_bin']) self.dvc.metrics_add('metrics_bin') + + def test_non_existing(self): + ret = main(['metrics', 'add', 'non-existing']) + self.assertNotEqual(ret, 0) + + ret = main(['metrics', 'remove', 'non-existing']) + self.assertNotEqual(ret, 0) + + +class TestNoMetrics(TestDvc): + def test(self): + ret = main(['metrics', 'show']) + self.assertNotEqual(ret, 0)