Repository: iterative/dvc

Issue:
Remove show pipeline command to avoid graphviz dependency



Discussion:

Resolving patch:
diff --git a/dvc/cli.py b/dvc/cli.py
--- a/dvc/cli.py
+++ b/dvc/cli.py
@@ -14,7 +14,6 @@
 from dvc.command.gc import CmdGC
 from dvc.command.add import CmdAdd
 from dvc.command.config import CmdConfig
-from dvc.command.show_pipeline import CmdShowPipeline
 from dvc.command.checkout import CmdCheckout
 from dvc.stage import Stage
 from dvc import VERSION
@@ -223,25 +222,6 @@ def parse_args(argv=None):
                         help='Option value')
     config_parser.set_defaults(func=CmdConfig)
 
-    # Show
-    show_parser = subparsers.add_parser(
-                        'show',
-                        parents=[parent_parser],
-                        help='Show graphs')
-    show_subparsers = show_parser.add_subparsers(
-                        dest='cmd',
-                        help='Use `dvc show CMD` --help for command-specific help')
-
-    pipeline_parser = show_subparsers.add_parser(
-                        'pipeline',
-                        parents=[parent_parser],
-                        help='Show pipeline image')
-    pipeline_parser.add_argument(
-                        'target',
-                        nargs='*',
-                        help='Target data directory')
-    pipeline_parser.set_defaults(func=CmdShowPipeline)
-
     # Fsck
     fsck_parser = subparsers.add_parser(
                         'fsck',
diff --git a/dvc/command/show_pipeline.py b/dvc/command/show_pipeline.py
deleted file mode 100644
--- a/dvc/command/show_pipeline.py
+++ /dev/null
@@ -1,72 +0,0 @@
-import os
-import networkx as nx
-
-from dvc.command.common.base import CmdBase
-
-
-class CmdShowPipeline(CmdBase):
-    def draw(self, g, target, fname_suffix):
-        fname = 'pipeline_' + fname_suffix
-        try:
-            A = nx.nx_agraph.to_agraph(g)
-            A.write(fname + '.dot')
-            A.draw(fname + '.jpeg', format='jpeg', prog='dot')
-        except Exception as exc:
-            self.project.logger.error('Failed to draw dependency graph for {}: {}'.format(target, exc))
-            return 1
-
-        return 0
-
-    def find_sub(self, fname):
-        for s in self.subs:
-            if fname in s.nodes():
-                return s
-
-        return None
-
-    def draw_targets(self, target):
-        if not target:
-            return self.draw(self.g, '.', 'all')
-
-        for t in self.args.target:
-            fname_suffix = os.path.basename(os.path.normpath(t))
-            s = self.find_sub(t)
-
-            ret = self.draw(s, t, fname_suffix)
-            if ret != 0:
-                return ret
-
-        return 0
-
-    def run(self):
-        self.g = nx.DiGraph()
-        self.subs = []
-
-        saved_targets = self.args.target
-        self.args.target = ['.']
- 
-        for stage in self.project.stages():
-            self.collect_stage(stage)
-
-        self.args.target = saved_targets
-
-        # Try to find independent clusters which might occure
-        # when a bunch of data items were used independently.
-        self.subs = nx.weakly_connected_component_subgraphs(self.g)
-
-        return self.draw_targets(saved_targets)
-
-    def collect_stage(self, stage):
-        name = os.path.relpath(stage.path, self.project.root_dir)
-
-        self.g.add_node(name)
-
-        for dep in stage.deps:
-            i = os.path.relpath(dep.path, self.project.root_dir)
-            self.g.add_node(i)
-            self.g.add_edge(i, name)
-
-        for out in stage.outs:
-            o = os.path.relpath(out.path, self.project.root_dir)
-            self.g.add_node(o)
-            self.g.add_edge(name, o)


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -9,7 +9,6 @@
 from dvc.command.remove import CmdRemove
 from dvc.command.gc import CmdGC
 from dvc.command.config import CmdConfig
-from dvc.command.show_pipeline import CmdShowPipeline
 from dvc.command.checkout import CmdCheckout
 from dvc.command.fsck import CmdFsck
 
@@ -143,20 +142,6 @@ def test(self):
         self.assertEqual(args.value, value)
 
 
-class TestShowPipeline(TestDvc):
-    def test(self):
-        target1 = '1'
-        target2 = '2'
-
-        args = parse_args(['show',
-                           'pipeline',
-                           target1,
-                           target2])
-
-        self.assertIsInstance(args.func(args), CmdShowPipeline)
-        self.assertEqual(args.target, [target1, target2])
-
-
 class TestCheckout(TestDvc):
     def test(self):
         args = parse_args(['checkout'])
diff --git a/tests/test_show_pipeline.py b/tests/test_show_pipeline.py
deleted file mode 100644
--- a/tests/test_show_pipeline.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import os
-import pygraphviz
-
-from dvc.main import main
-
-from tests.test_repro import TestRepro
-
-
-class TestShowPipeline(TestRepro):
-    def test_show(self):
-        ret = main(['show',
-                    'pipeline'])
-
-        self.assertEqual(ret, 0)
-        self.assertTrue(os.path.isfile('pipeline_all.dot'))
-        self.assertTrue(os.path.isfile('pipeline_all.jpeg'))
-
-    def test_target(self):
-        base = 'pipeline_' + os.path.basename(self.file1_stage)
-        ret = main(['show',
-                    'pipeline',
-                    self.file1_stage])
-
-        self.assertEqual(ret, 0)
-        self.assertTrue(os.path.isfile(base + '.dot'))
-        self.assertTrue(os.path.isfile(base + '.jpeg'))
-
-    def test_non_existing_target(self):
-        ret = main(['show',
-                    'pipeline',
-                    'non-existing-target'])
-
-        self.assertNotEqual(ret, 0)