Update to first update: I realized that I did not specify a gem dependency on
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
gemvizto rubyforge.org -- at least I'm one step closer!
Check it out, yo:
[sudo] gem install gemvizNow 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
tredutility 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
railsgem has dependencies on
actionpack. Which is true, as far as it goes, and is reflected in the output of the
gem depcommand thusly:
gem dep rails
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 depdoesn't tell the whole story.
railsdoes depend on those other gems, but only through its dependencies on
activeresource, as shown in the first graph. That's what the
tredutility (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:
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
gemvizis always a single
.pngfile 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.