Skip to content

Commit

Permalink
Updated brew graph
Browse files Browse the repository at this point in the history
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#18282.

Signed-off-by: Adam Vandenberg <flangy@gmail.com>
  • Loading branch information
int3h authored and mistydemeo committed Jun 12, 2013
1 parent 0fab0e9 commit e7742df
Showing 1 changed file with 46 additions and 14 deletions.
60 changes: 46 additions & 14 deletions Library/Contributions/cmd/brew-graph
@@ -1,8 +1,8 @@
#!/usr/bin/env python
"""
$ brew install graphviz
$ brew graph | dot -Tsvg -ohomebrew.svg
$ open homebrew.svg
$ brew graph | dot -Tsvg -ohomebrew.html
$ open homebrew.html
"""
from __future__ import with_statement

Expand Down Expand Up @@ -274,13 +274,26 @@ class Graph(NodeContainer, EdgeContainer, ClusterContainer):

def main():
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)
output = output.strip()
depgraph = list()

for f in output.split("\n"):
stuff = f.split(":",2)
if len(stuff) < 2:
continue
name = stuff[0]
deps = stuff[1].strip()
if not deps:
Expand All @@ -289,20 +302,39 @@ def main():
deps = deps.split(" ")
depgraph.append((name, deps))

hb = Graph("Homebrew Dependencies", attrib={'labelloc':'b', 'rankdir':'LR', 'ranksep':'5'})

used = set()
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

seen = set()
def addNode(graph, name):
if name not in seen:
graph.node(name, name, attrib={'shape': 'box'})
seen.add(name)
return True
return False

independent = set()
for f in depgraph:
for d in f[1]:
used.add(f[0])
used.add(d)

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
n = hb.node(f[0], f[0])

independent.add(f[0])
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()

Expand Down

0 comments on commit e7742df

Please sign in to comment.