cli: add pipeline show --tree

Add option to unfold dependencies into a tree.

Fixes #1038
This commit is contained in:
Dmitrii Pukhov
2019-03-26 01:29:49 +09:00
parent 49ae03fdc5
commit fba43277e6
3 changed files with 41 additions and 3 deletions
+36 -3
View File
@@ -71,23 +71,46 @@ class CmdPipelineShow(CmdBase):
else:
edges.append((from_stage.relpath, to_stage.relpath))
return nodes, edges
return nodes, edges, networkx.is_tree(G)
def _show_ascii(self, target, commands, outs):
from dvc.dagascii import draw
nodes, edges = self.__build_graph(target, commands, outs)
nodes, edges, _ = self.__build_graph(target, commands, outs)
if not nodes:
return
draw(nodes, edges)
def _show_dependencies_tree(self, target, commands, outs):
from treelib import Tree
nodes, edges, is_tree = self.__build_graph(target, commands, outs)
if not nodes:
return
if not is_tree:
raise ValueError(
"DAG is not a tree, can not print it in tree-structure way, "
"please use --ascii instead"
)
tree = Tree()
tree.create_node(target, target) # Root node
observe_list = [target]
while len(observe_list) > 0:
current_root = observe_list[0]
for edge in edges:
if edge[0] == current_root:
tree.create_node(edge[1], edge[1], parent=current_root)
observe_list.append(edge[1])
observe_list.pop(0)
tree.show()
def __write_dot(self, target, commands, outs, filename):
import networkx
from networkx.drawing.nx_pydot import write_dot
_, edges = self.__build_graph(target, commands, outs)
_, edges, _ = self.__build_graph(target, commands, outs)
edges = [edge[::-1] for edge in edges]
simple_g = networkx.DiGraph()
@@ -111,6 +134,10 @@ class CmdPipelineShow(CmdBase):
self.args.outs,
self.args.dot,
)
elif self.args.tree:
self._show_dependencies_tree(
target, self.args.commands, self.args.outs
)
else:
self._show(target, self.args.commands, self.args.outs)
except DvcException:
@@ -185,6 +212,12 @@ def add_parser(subparsers, parent_parser):
pipeline_show_parser.add_argument(
"--dot", help="Write DAG in .dot format."
)
pipeline_show_parser.add_argument(
"--tree",
action="store_true",
default=False,
help="Output DAG as Dependencies Tree.",
)
pipeline_show_parser.add_argument(
"targets", nargs="*", help="DVC files. 'Dvcfile' by default."
)
+1
View File
@@ -25,3 +25,4 @@ pydot>=1.2.4
asciimatics>=1.10.0
distro>=1.3.0
appdirs>=1.4.3
treelib>=1.5.5
+4
View File
@@ -34,6 +34,10 @@ class TestPipelineShowSingle(TestDvc):
self.assertEqual(ret, 0)
self.assertTrue(os.path.isfile(self.dotFile))
def test_tree(self):
ret = main(["pipeline", "show", "--tree", self.stage])
self.assertEqual(ret, 0)
def test_ascii_commands(self):
ret = main(["pipeline", "show", "--ascii", self.stage, "--commands"])
self.assertEqual(ret, 0)