====================================== Printing a plain text dependency graph ====================================== We populate a custom working set and compute its dependency graph, arranging for one subtree to appear more than once in the graph: >>> anton_1 = make_dist("anton-1.egg", depends="""berta ... charlie[extra]""") >>> berta_2 = make_dist("berta-2.egg", depends="charlie[artxe, extra]") >>> charlie_1_4 = make_dist("charlie-1.4.egg", depends="""[extra] ... dora ... [artxe] ... dora ... emil""") >>> dora_0_5 = make_dist("dora-0.5.egg") >>> emil_1 = make_dist("emil-1.egg") >>> ws = make_working_set(anton_1, berta_2, charlie_1_4, dora_0_5, emil_1) >>> from tl.eggdeps.graph import Graph >>> graph = Graph(working_set=ws) >>> graph.from_working_set() >>> sprint(graph) {'anton': {'berta': {None: set([])}, 'charlie': {'extra': set([])}}, 'berta': {'charlie': {'artxe': set([]), 'extra': set([])}}, 'charlie': {'dora': {None: set(['artxe', 'extra'])}, 'emil': {None: set(['artxe'])}}, 'dora': {}, 'emil': {}} Full trees ========== Full trees are still somewhat abbreviated representations of the complete dependency structure but include enough information to reconstruct the latter: they spell out recurring subtrees only once but print the subtree root distributions in all other places and add ellipses to hint at omissions. >>> from tl.eggdeps.plaintext import print_graph >>> print_graph(graph, Options()) anton berta charlie [artxe, extra] ... charlie [extra] [artxe] dora emil [extra] dora Version numbers may be printed next to the distribution names: >>> print_graph(graph, Options(version_numbers=True)) anton 1 berta 2 charlie 1.4 [artxe, extra] ... charlie 1.4 [extra] [artxe] dora 0.5 emil 1 [extra] dora 0.5 Reduced output ============== The representation can be shortened in several ways. The ``terse`` option omits ellipses for left-out subtrees: >>> print_graph(graph, Options(terse=True)) anton berta charlie [artxe, extra] charlie [extra] [artxe] dora emil [extra] dora Alternatively, the ``once`` option hides omitted subtrees completely so that even the names of root distributions of subtrees are printed in only one place. Which extras of each distribution are required is then not shown anymore. This means that the full information cannot be reconstructed from the output anymore. Still, an ellipsis indicates where one or more subtrees have been left out: >>> print_graph(graph, Options(once=True)) anton berta ... charlie [artxe] dora emil [extra] ... These two options may be combined to remove even those ellipses: >>> print_graph(graph, Options(once=True, terse=True)) anton berta charlie [artxe] dora emil [extra] Determining which occurrence of a subtree to render =================================================== If a subgraph of the dependency structure occurs multiple times, a deterministic algorithm is employed to decide at which point in the printed tree the subgraph is to be rendered. A subgraph will be rendered as close to the root as possible in order to avoid printing a deep tree: >>> anton = make_dist("anton-1.egg", depends="""berta ... charlie""") >>> berta = make_dist("berta-2.egg", depends="charlie") >>> charlie = make_dist("charlie-1.4.egg", depends="dora") >>> dora = make_dist("dora-0.5.egg") >>> ws = make_working_set(anton, berta, charlie, dora) >>> graph = Graph(working_set=ws) >>> graph.from_specifications("anton") >>> print_graph(graph, Options()) anton berta charlie ... charlie dora In particular, this prevents infinite recursion with cyclic dependency graphs: >>> anton = make_dist("anton-1.egg", depends="anton") >>> ws = make_working_set(anton) >>> graph = Graph(working_set=ws) >>> graph.from_specifications("anton") >>> print_graph(graph, Options()) anton anton ... If a subgraph can be reached from a root node both by a route consisting only of mandatory dependency edges and by a route including extra dependencies, the subgraph will be rendered at the point reached without considering extras: >>> anton = make_dist("anton-1.egg", depends="""berta ... [extra] ... charlie""") >>> ws = make_working_set(anton, berta, charlie, dora) >>> graph = Graph(working_set=ws) >>> graph.from_specifications("anton[extra]") >>> print_graph(graph, Options()) anton berta charlie dora [extra] charlie ... However, if a distribution is required more than once with different sets of extras, the dependencies of all extras involved will be rendered at the same occurrence of that distribution: >>> anton = make_dist("anton-1.egg", depends="""berta ... charlie""") >>> berta = make_dist("berta-2.egg", depends="charlie[foo]") >>> charlie = make_dist("charlie-1.4.egg", depends="""dora ... [foo] ... emil""") >>> dora = make_dist("dora-0.5.egg") >>> emil = make_dist("emil-1.egg") >>> ws = make_working_set(anton, berta, charlie, dora, emil) >>> graph = Graph(working_set=ws) >>> graph.from_specifications("anton") >>> print_graph(graph, Options()) anton berta charlie [foo] ... charlie dora [foo] emil .. Local Variables: .. mode: rst .. End: