Final (potentially) update: Now appearing on github:
git://github.com/davidrupp/gemviz.git
Update to first update: I realized that I did not specify a gem dependency on
ruby-graphviz
in my
hoe
-generated Rakefile. This is in place as of version 0.1.2.
To quote Groundskeeper Willie in The Simpsons - Treehouse of Horror V: "Och, I'm bad at this!"
We now return you to the first update.
Update: Peter Cooper correctly points out in his comment that Gemviz has a hard dependency on Graphviz, which isn't installed by default on Macs. I tend to take it for granted because it's one of the first things on my checklist to install when breaking in a new Mac. I use
The Mac OS X Edition of Graphviz, as referenced on
the Graphviz home page.
We now return you to the regularly scheduled original post.
Original Post: I can't really call myself a hotshot Ruby programmer until I release a RubyGem, now can I? Well, I still won't call myself a hotshot Ruby programmer yet...but, as of today -- and the release of versions 0.1.0 and 0.1.1 (for documentation purposes) of my new gem
gemviz
to rubyforge.org -- at least I'm one step closer!
Check it out, yo:
[sudo] gem install gemviz
Now you can do e.g.,
gemviz rails
(assuming you have Rails installed as a gem which, if you don't by now: huh?), which produces this graph on my system:
In fairness, I should disclose that Gemviz is only about 30 lines of code, and makes heavy use of other people's work to do its magic. Here's how it works:
* it scrapes the output of the system command
gem dep gem_name --pipe
.
* for each dependency thus listed, it adds that dependency to the list of dependent gems.
* it does the same recursively for each dependent gem until it finds that the current gem has no dependencies, or that some (recursively) dependent gem is not installed on the system.
* it builds a Graphviz graph from the graph so built.
* it runs the awesome
tred
utility on the resulting Graphviz graph, which translates the original messy graph into one that properly represents all of the transitive dependencies.
If you're not sure what that last bit is about, don't feel bad: I didn't either at first. So here's the picture that's worth a thousand words (give or take):
The difference is subtle, but telling. The second graph shows that the
rails
gem has dependencies on
activesupport
and
actionpack
. Which is true, as far as it goes, and is reflected in the output of the
gem dep
command thusly:
gem dep rails
Gem rails-2.2.2
rake (>= 0.8.3, runtime)
activesupport (= 2.2.2, runtime)
activerecord (= 2.2.2, runtime)
actionpack (= 2.2.2, runtime)
actionmailer (= 2.2.2, runtime)
activeresource (= 2.2.2, runtime)
But it turns out that
gem dep
doesn't tell the whole story.
rails
does depend on those other gems, but only
through its dependencies on
activerecord
,
actionmailer
, and
activeresource
, as shown in the first graph. That's what the
tred
utility (part of the Graphviz package) does: reduce the second graph to its minimal equivalent representation in the first graph.
Here's another more fun example, for
merb
, prior to transitive reduction:
And post
tred
:
This implementation owes much to the existing
DepGraph
, especially its use of Graphviz and
tred
. I basically just extracted the simple use case of graphing a gem at a time, and neglected to implement a bunch of DepGraph's options. For instance, the output of
gemviz
is always a single
.png
file per requested gem, named after the gem and placed in the current directory.
Keep in mind that this is a very simple initial release. Please let me know if you find it useful, and especially what improvements you can think of.