Updated brew graph
Changed 'graph' command to show only installed by default. Prettified resulting graph. By default, the `brew graph` command would output a dependency graph for every formula it knew about. Now it only outputs a dependency graph the for formulas installed. If you want to see the graph for all formulas, use `brew graph --all`. Additionally, the old version of the graph command would filter out any formulas without depdency connections. The updated version now only does this if calculating dependencies for all formulas via the `--all` flag. Finally, the resulting graph has been redesigned to be simpler to read. All formulas which have no other formulas depending on them (i.e., root nodes) are aligned to the left. They are also outlined in a light grey box, which is labelled "Safe to Remove". As implied, all of the formulas in this box can be safely removed without breaking other installed formulas; all formulas outside this box have at least one installed formula depending on them. This new graph style is surpressed if the `--all` flag is used. Closes Homebrew/homebrew#18282. Signed-off-by: Adam Vandenberg <flangy@gmail.com>
This commit is contained in:
parent
a60eed48bc
commit
14e3c77f60
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""
|
"""
|
||||||
$ brew install graphviz
|
$ brew install graphviz
|
||||||
$ brew graph | dot -Tsvg -ohomebrew.svg
|
$ brew graph | dot -Tsvg -ohomebrew.html
|
||||||
$ open homebrew.svg
|
$ open homebrew.html
|
||||||
"""
|
"""
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
|
||||||
@ -274,13 +274,26 @@ class Graph(NodeContainer, EdgeContainer, ClusterContainer):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
cmd = ["brew", "deps"]
|
cmd = ["brew", "deps"]
|
||||||
cmd.extend(sys.argv[1:] or ["--all"])
|
if sys.argv[1:]:
|
||||||
|
if '--all' in sys.argv[1:]:
|
||||||
|
show = 'all'
|
||||||
|
cmd.extend(['--all'])
|
||||||
|
else:
|
||||||
|
show = 'one'
|
||||||
|
hideOrphaned = False
|
||||||
|
cmd.extend(sys.argv[1:])
|
||||||
|
else:
|
||||||
|
show = 'installed'
|
||||||
|
cmd.extend(['--installed'])
|
||||||
|
|
||||||
code, output = run(cmd)
|
code, output = run(cmd)
|
||||||
output = output.strip()
|
output = output.strip()
|
||||||
depgraph = list()
|
depgraph = list()
|
||||||
|
|
||||||
for f in output.split("\n"):
|
for f in output.split("\n"):
|
||||||
stuff = f.split(":",2)
|
stuff = f.split(":",2)
|
||||||
|
if len(stuff) < 2:
|
||||||
|
continue
|
||||||
name = stuff[0]
|
name = stuff[0]
|
||||||
deps = stuff[1].strip()
|
deps = stuff[1].strip()
|
||||||
if not deps:
|
if not deps:
|
||||||
@ -289,20 +302,39 @@ def main():
|
|||||||
deps = deps.split(" ")
|
deps = deps.split(" ")
|
||||||
depgraph.append((name, deps))
|
depgraph.append((name, deps))
|
||||||
|
|
||||||
hb = Graph("Homebrew Dependencies", attrib={'labelloc':'b', 'rankdir':'LR', 'ranksep':'5'})
|
hb = Graph("Homebrew Dependencies", attrib={'labelloc':'t', 'rankdir':'LR', 'ranksep':'5'})
|
||||||
|
# Independent formulas (those that are not dependended on by any other formula) get placed in
|
||||||
|
# their own subgraph so we can align them together on the left.
|
||||||
|
if show == 'installed':
|
||||||
|
sub = hb.cluster("independent", "Safe to Remove", attrib={'rank': 'min', 'style': 'filled', 'fillcolor': '#F0F0F0', 'color': 'invis'})
|
||||||
|
else:
|
||||||
|
sub = hb
|
||||||
|
|
||||||
used = set()
|
seen = set()
|
||||||
for f in depgraph:
|
def addNode(graph, name):
|
||||||
for d in f[1]:
|
if name not in seen:
|
||||||
used.add(f[0])
|
graph.node(name, name, attrib={'shape': 'box'})
|
||||||
used.add(d)
|
seen.add(name)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
independent = set()
|
||||||
for f in depgraph:
|
for f in depgraph:
|
||||||
if f[0] not in used:
|
# Filter out orphan formulas when showing all, to cut down on noise
|
||||||
|
if show == 'all' and len(f[1]) == 0:
|
||||||
continue
|
continue
|
||||||
n = hb.node(f[0], f[0])
|
|
||||||
|
independent.add(f[0])
|
||||||
for d in f[1]:
|
for d in f[1]:
|
||||||
hb.link(d, f[0])
|
independent.discard(d)
|
||||||
|
hb.link(f[0], d)
|
||||||
|
# Children we can add right away because we don't care where they go
|
||||||
|
addNode(hb, d)
|
||||||
|
|
||||||
|
# For all installed formulas, place them in the 'indep' subgraph iff they
|
||||||
|
# are not depended on by other formulas, i.e. are root nodes.
|
||||||
|
for d in independent:
|
||||||
|
addNode(sub, d)
|
||||||
|
|
||||||
hb.dot()
|
hb.dot()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user