From 825da210cfb9a44a47d3734f1072ffe53091b8a3 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Tue, 28 Aug 2018 09:31:01 +0300 Subject: [PATCH 1/2] dvc: use __str__ method for deps/outs Signed-off-by: Ruslan Kuprieiev --- dvc/command/pipeline.py | 10 +++++----- dvc/dependency/base.py | 3 +++ dvc/dependency/local.py | 3 +++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/dvc/command/pipeline.py b/dvc/command/pipeline.py index 36a8a8958..4fd75ba6d 100644 --- a/dvc/command/pipeline.py +++ b/dvc/command/pipeline.py @@ -20,7 +20,7 @@ class CmdPipelineShow(CmdBase): self.project.logger.info(stages[n].cmd) elif outs: for out in stages[n].outs: - self.project.logger.info(out.rel_path) + self.project.logger.info(str(out)) else: self.project.logger.info(n) @@ -52,10 +52,10 @@ class CmdPipelineShow(CmdBase): elif outs: for from_out in from_stage.outs: for to_out in to_stage.outs: - nodes.add(from_out.rel_path) - nodes.add(to_out.rel_path) - edges.append((from_out.rel_path, - to_out.rel_path)) + nodes.add(str(from_out)) + nodes.add(str(to_out)) + edges.append((str(from_out), + str(to_out))) else: nodes.add(from_stage.relpath) nodes.add(to_stage.relpath) diff --git a/dvc/dependency/base.py b/dvc/dependency/base.py index 970fc540a..512c44621 100644 --- a/dvc/dependency/base.py +++ b/dvc/dependency/base.py @@ -31,6 +31,9 @@ class DependencyBase(object): self.project = stage.project self.path = path + def __str__(self): + return self.path + @classmethod def match(cls, url): return re.match(cls.REGEX, url) diff --git a/dvc/dependency/local.py b/dvc/dependency/local.py index c4ea5e9ba..3ff164121 100644 --- a/dvc/dependency/local.py +++ b/dvc/dependency/local.py @@ -38,6 +38,9 @@ class DependencyLOCAL(DependencyBase): self.path_info = {'scheme': 'local', 'path': self.path} + def __str__(self): + return self.rel_path + @property def sep(self): return os.sep From 55b3c47bbfd33b0b059fe9207ffc196cff840981 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Tue, 28 Aug 2018 11:25:28 +0300 Subject: [PATCH 2/2] pipeline: process edges and nodes separately Signed-off-by: Ruslan Kuprieiev --- dvc/command/pipeline.py | 26 ++++++++++++++++---------- tests/test_pipeline.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/dvc/command/pipeline.py b/dvc/command/pipeline.py index 4fd75ba6d..280b8be94 100644 --- a/dvc/command/pipeline.py +++ b/dvc/command/pipeline.py @@ -38,32 +38,38 @@ class CmdPipelineShow(CmdBase): G = pipelines[0] stages = networkx.get_node_attributes(G, 'stage') - nodes = set() + nodes = [] + for n in G.nodes(): + stage = stages[n] + if commands: + if stage.cmd is None: + continue + nodes.append(stage.cmd) + elif outs: + for out in stage.outs: + nodes.append(str(out)) + else: + nodes.append(stage.relpath) + + if len(nodes) == 0: + return + edges = [] for e in G.edges(): from_stage = stages[e[0]] to_stage = stages[e[1]] if commands: - nodes.add(from_stage.cmd) if to_stage.cmd is None: continue - nodes.add(to_stage.cmd) edges.append((from_stage.cmd, to_stage.cmd)) elif outs: for from_out in from_stage.outs: for to_out in to_stage.outs: - nodes.add(str(from_out)) - nodes.add(str(to_out)) edges.append((str(from_out), str(to_out))) else: - nodes.add(from_stage.relpath) - nodes.add(to_stage.relpath) edges.append((from_stage.relpath, to_stage.relpath)) - nodes = list(nodes) - assert len(nodes) > 0 - d = Dagascii(nodes, edges) d.draw() diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index af5d9ea22..8a6646b03 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -1,8 +1,49 @@ from dvc.main import main +from tests.basic_env import TestDvc from tests.test_repro import TestRepro, TestReproChangedDeepData +class TestPipelineShowSingle(TestDvc): + def setUp(self): + super(TestPipelineShowSingle, self).setUp() + self.stage = 'foo.dvc' + ret = main(['add', self.FOO]) + self.assertEqual(ret, 0) + + def test(self): + ret = main(['pipeline', 'show', self.stage]) + self.assertEqual(ret, 0) + + def test_commands(self): + ret = main(['pipeline', 'show', self.stage, '--commands']) + self.assertEqual(ret, 0) + + def test_outs(self): + ret = main(['pipeline', 'show', self.stage, '--outs']) + self.assertEqual(ret, 0) + + def test_ascii(self): + ret = main(['pipeline', 'show', '--ascii', self.stage]) + self.assertEqual(ret, 0) + + def test_ascii_commands(self): + ret = main(['pipeline', 'show', '--ascii', self.stage, '--commands']) + self.assertEqual(ret, 0) + + def test_ascii_outs(self): + ret = main(['pipeline', 'show', '--ascii', self.stage, '--outs']) + self.assertEqual(ret, 0) + + def test_not_dvc_file(self): + ret = main(['pipeline', 'show', self.FOO]) + self.assertNotEqual(ret, 0) + + def test_non_existing(self): + ret = main(['pipeline', 'show', 'non-existing']) + self.assertNotEqual(ret, 0) + + class TestPipelineShow(TestRepro): def test(self): ret = main(['pipeline', 'show', self.file1_stage])