[Rubygems-developers] Automating gems

Chad Woolley thewoolleyman at gmail.com
Sat Mar 17 12:07:53 EDT 2007


On 3/17/07, Eric Hodel <drbrain at segment7.net> wrote:
> On Mar 14, 2007, at 14:47, Patrick Hurley wrote:
>
> > Sorry, if I should have been able to find some docs to point me in the
> > right direction, but so far here is what I figured out from trial and
> > error and some source code reading.
> >
> > I want to unpack a gem already on my machine:
> > gem unpack a_gem
> >
> > Then I want to retrieve the gem spec
> > gem specification a_gem
> >
> > (then more stuff but this will get me started)
> >
> > So far I have the simple code:
> >
> > require "rubygems"
> > Gem.manage_gems
> >
> > if gem = ARGV.first
> >   puts "Processing #{gem}"
> >   runner = Gem::GemRunner.new
> >   puts "Unpack #{gem}"
> >   runner.run ['unpack', gem]
> >   runner.run(['specification', gem])
> > end
> >
> > This works; however, the run command displays to the screen. Is there
> > an easy way to capture its output? I see there is a default interface
> > object, with a method called say I could grab, but that seems pretty
> > messy. I could also grab the stdout handle and play games there, but
> > again, I feel I am missing something.
>
> Don't use the runner interface at all, it doesn't do anything you
> need, and adds a bunch of crap you don't (redirecting output).
>
> Just call the Gem::Installer#unpack method directly.
>
> $ ri Gem::Installer#unpack
> -------------------------------------------------- Gem::Installer#unpack
>       unpack(directory)
> ------------------------------------------------------------------------
>       Unpacks the gem into the given directory.
>
> Just use to_yaml or to_ruby on Gem::Specification.

This will work because the unpack command doesn't use stdin or stdout,
it only throws exceptions (that I see).  I think the original poster
indicated that he wanted to do more eventually, though.  If he wants
to automate stuff like installing/uninstalling gems, *especially*
multiplatform gems, then he will have to override the default ui in
user_interaction to capture the output.  In the case of multiplatform
gems, there is currently no way to specify a platform via the
installer API, so you must deal with the input and output stream in
order to parse and respond to the lists of non-ruby-platform gems that
are presented.

You don't have to use gem_runner, you can use installer directly.  In
my case, it was just easier to use gem_runner directly in my case,
because I wanted to preserve the original rubygems config and arg
behavior as much as possible, and try to stay close to the "edge" of
the internal API (to avoid breaking if the deeper API implementation
changes over time).  You still have to use a custom ui implementation
to interact with install/uninstall, though.

-- Chad


More information about the Rubygems-developers mailing list