# Automating gem installs?

**URL:** <https://rubytalk.org/t/automating-gem-installs/42054>\
**Category:** ruby-talk\
**Created:** [9 November 2007 17:48 UTC](https://rubytalk.org/t/automating-gem-installs/42054 "2007-11-09T17:48:36Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Justin\_Hahn](https://avatars.discourse-cdn.com/v4/letter/j/898d66/32.png) [@Justin\_Hahn](https://rubytalk.org/u/Justin_Hahn)\
**Post date:** [9 November 2007 17:48 UTC](https://rubytalk.org/t/automating-gem-installs/42054/1 "2007-11-09T17:48:36Z")

</div>

I'm trying to setup an automated build system for all of our upstream  
binary dependencies (that we don't get from our OS). Since we track a  
newer ruby than most of our machines ship with, this means building ruby  
and installing gems. For the most part this works fine, except when I  
need to install a gem like mongrel that has several versions.

For example, if I run 'gem install -y mongrel' from my Makefile, I get  
an error like this (since stdin isn't attached):

Select which gem to install for your platform (x86\_64-linux)  
1. mongrel 1.1 (ruby)  
2. mongrel 1.1 (mswin32)  
3. mongrel 1.0.4 (mswin32)  
4. mongrel 1.0.4 (ruby)  
5. Skip this gem  
6. Cancel installation

> ERROR: While executing gem ... (NoMethodError)

&nbsp;&nbsp;&nbsp;&nbsp;undefined method `strip' for nil:NilClass

Unfortunately, the list entries aren't even stable -- sometimes option  
#1 is the mswin32 and sometimes it's the ruby choice. So I can't even do  
something nasty like "echo 1 | gem install -y mongrel" and be assured of  
getting the right thing.

Is there any way to tell gem, from the commandline, precisely which gem  
I want? The documentation seems sparse, and I haven't had the time to go  
digging through gem's source code yet. (My hope is that this is any easy  
answer...)

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [9 November 2007 18:09 UTC](https://rubytalk.org/t/automating-gem-installs/42054/2 "2007-11-09T18:09:17Z")

</div>

not yet... but we're getting there. I've got this requirement as well and I sit next to eric all the time. don't worry. 🙂

> **···**
>
> On Nov 9, 2007, at 09:48 , Justin Hahn wrote:
> 
> > Is there any way to tell gem, from the commandline, precisely which gem  
> > I want? The documentation seems sparse, and I haven't had the time to go  
> > digging through gem's source code yet. (My hope is that this is any easy  
> > answer...)

---

<div class="post-metadata">

**Author:** ![nate2](https://avatars.discourse-cdn.com/v4/letter/n/c89c15/32.png) [@nate2](https://rubytalk.org/u/nate2)\
**Post date:** [11 November 2007 14:28 UTC](https://rubytalk.org/t/automating-gem-installs/42054/3 "2007-11-11T14:28:30Z")

</div>

Justin Hahn wrote:

> I'm trying to setup an automated build system for all of our upstream  
> binary dependencies (that we don't get from our OS). Since we track a  
> newer ruby than most of our machines ship with, this means building ruby  
> and installing gems. For the most part this works fine, except when I  
> need to install a gem like mongrel that has several versions.

I do this the hard way probably, but I convert gems into RPMs and then  
push the RPMs to the systems. It takes quite a while but I can be sure  
of:

(assuming your using Linux and an RPM-based distribution)  
- no external dependencies(e.g. servers calling to the internet to  
&nbsp;&nbsp;download something)  
- one package manager to query for all files on the system  
- more compatible with our automated management system(www.cfengine.org)  
- installs exactly the versions we use, never have to worry about the  
&nbsp;&nbsp;wrong version getting installed by accident.  
- don't need development stuff installed to install the gems  
&nbsp;&nbsp;(though we still have development stuff installed, at some point  
&nbsp;&nbsp;&nbsp;I expect we'll remove non essentials from most systems)

Currently I maintain 29 gems using this method. If your interested I  
can send you a short little HOWTO doc I wrote so when I go through  
this painful process I remember all of the commands I need.

Basically what I do is:  
- build a list of files in /usr  
- install the gem(one gem at a time!), for me I resolve dependencies  
manually, and download the gems direct from  
[http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)  
- build a list of files again in /usr  
- run a diff between the two lists to find new files(this is a fairly  
&nbsp;&nbsp;complicated command, the one I often forget:  
&nbsp;&nbsp;for i in `diff -u /tmp/usr-before-gd.log /tmp/usr-after-gd.log | grep ^+ |  
grep /usr/ | sed s'/+//'g`; do [-d $i] || echo $i ;done \>/tmp/new.txt

- tar those new files up into a tarball  
- copy tarball to debian/ubuntu system (or some system that has alien  
installed)  
- run alien in prepare mode, edit the SPEC file, change values as needed(I  
add descriptions and stuff so we can query what the rpm is)  
- run rpmbuild to build the binary

it takes about 10 minutes per gem, if your updating gems often this is  
painful, but we don't update too often, I've gone through this process about  
4 times in the past year. Been deploying gems this way for over a year now  
and haven't had any problems(as in the files I built missing stuff or bad  
versions etc). If there's a better/faster way to build RPMs that'd be great,  
I'd love to build source rpms from gems, though the only way I know how to  
build rpms myself is with alien which is cheating, but it works.. I think  
building source rpms would take a lot more time.

The resulting RPMs are pushed out to about 60 systems.

nate

---

<div class="post-metadata">

**Author:** ![Jan\_Svitok](https://avatars.discourse-cdn.com/v4/letter/j/cab0a1/32.png) [@Jan\_Svitok](https://rubytalk.org/u/Jan_Svitok)\
**Post date:** [13 November 2007 16:51 UTC](https://rubytalk.org/t/automating-gem-installs/42054/4 "2007-11-13T16:51:06Z")

</div>

One way is to install the gems on one machine and run a gem server on it.  
Then install the other machines from that server (--source=[http://yourserver](http://yourserver))

If you install only one version of a gem, only one will be offered and  
you'll exactly  
know which one.

This will make the install a bit faster, as you'll be downloading from  
the local network.  
Setting up a gem server is pretty easy -- e.g.  
[http://rambleon.org/2007/04/19/creating-your-own-gem-server/](http://rambleon.org/2007/04/19/creating-your-own-gem-server/)

J.

> **···**
>
> On Nov 9, 2007 6:48 PM, Justin Hahn \<jhahn@rbmtechnologies.com\> wrote:
> 
> > I'm trying to setup an automated build system for all of our upstream  
> > binary dependencies (that we don't get from our OS). Since we track a  
> > newer ruby than most of our machines ship with, this means building ruby  
> > and installing gems. For the most part this works fine, except when I  
> > need to install a gem like mongrel that has several versions.
> > 
> > For example, if I run 'gem install -y mongrel' from my Makefile, I get  
> > an error like this (since stdin isn't attached):
> > 
> > Select which gem to install for your platform (x86\_64-linux)  
> > 1. mongrel 1.1 (ruby)  
> > 2. mongrel 1.1 (mswin32)  
> > 3. mongrel 1.0.4 (mswin32)  
> > 4. mongrel 1.0.4 (ruby)  
> > 5. Skip this gem  
> > 6. Cancel installation  
> > \> ERROR: While executing gem ... (NoMethodError)  
> > &nbsp;&nbsp;&nbsp;&nbsp;undefined method `strip' for nil:NilClass
> > 
> > Unfortunately, the list entries aren't even stable -- sometimes option  
> > #1 is the mswin32 and sometimes it's the ruby choice. So I can't even do  
> > something nasty like "echo 1 | gem install -y mongrel" and be assured of  
> > getting the right thing.
> > 
> > Is there any way to tell gem, from the commandline, precisely which gem  
> > I want? The documentation seems sparse, and I haven't had the time to go  
> > digging through gem's source code yet. (My hope is that this is any easy  
> > answer...)

---

<div class="post-metadata">

**Author:** ![Justin\_Hahn](https://avatars.discourse-cdn.com/v4/letter/j/898d66/32.png) [@Justin\_Hahn](https://rubytalk.org/u/Justin_Hahn)\
**Post date:** [11 November 2007 23:01 UTC](https://rubytalk.org/t/automating-gem-installs/42054/5 "2007-11-11T23:01:48Z")

</div>

nate wrote:

> - install the gem(one gem at a time!), for me I resolve dependencies  
> manually, and download the gems direct from  
> [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)

That tells me what I needed to know. The only way to accomplish this  
right now is by downloading the gems manually and installing them that  
way. I was beginning to lean that way anyhow, but I guess there are  
worse things than making my dependencies more explicit.

Thanks.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Eric\_Hodel1](https://avatars.discourse-cdn.com/v4/letter/e/a9adbd/32.png) [@Eric\_Hodel1](https://rubytalk.org/u/Eric_Hodel1)\
**Post date:** [12 November 2007 23:21 UTC](https://rubytalk.org/t/automating-gem-installs/42054/6 "2007-11-12T23:21:35Z")

</div>

No!!!

Download gems direct from [RubyGems.org | your community gem host](http://gems.rubyforge.org/gems%5C). It will round-robin across all the mirrors.

Don't punish one mirror.

> **···**
>
> On Nov 11, 2007, at 06:28 , nate wrote:
> 
> > - install the gem(one gem at a time!), for me I resolve dependencies  
> > manually, and download the gems direct from  
> > [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)
> 
> --  
> Poor workers blame their tools. Good workers build better tools. The  
> best workers get their tools to do the work for them. -- Syndicate Wars

---

<div class="post-metadata">

**Author:** ![Ezra\_Zygmuntowicz](https://avatars.discourse-cdn.com/v4/letter/e/958977/32.png) [@Ezra\_Zygmuntowicz](https://rubytalk.org/u/Ezra_Zygmuntowicz)\
**Post date:** [12 November 2007 21:23 UTC](https://rubytalk.org/t/automating-gem-installs/42054/7 "2007-11-12T21:23:28Z")

</div>

Here is a script called gemcmd. This script is to be used in place of the gem command. It will choose the proper platform and will install the latest version of the requested gem available with no interaction so it is suitable to be called from scripts.

Cheers-  
-Ezra

#!/usr/bin/env ruby

> **···**
>
> On Nov 11, 2007, at 3:01 PM, Justin Hahn wrote:
> 
> > nate wrote:
> > 
> > > - install the gem(one gem at a time!), for me I resolve dependencies  
> > > manually, and download the gems direct from  
> > > [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)
> > 
> > That tells me what I needed to know. The only way to accomplish this  
> > right now is by downloading the gems manually and installing them that  
> > way. I was beginning to lean that way anyhow, but I guess there are  
> > worse things than making my dependencies more explicit.
> > 
> > Thanks.  
> > -- Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
> 
> #--  
> # 'gemcmd' - A non-interactive version of 'gem'.  
> #  
> # Original code  
> # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.  
> #  
> # Monkey Patch by Todd Fisher:  
> # [http://revolutiononrails.blogspot.com/2007/06/code-digest-2.html](http://revolutiononrails.blogspot.com/2007/06/code-digest-2.html)  
> #  
> # Integrated into command line by Neil Wilson \<aldursys@gmail.com\>  
> # (c) 2007  
> #  
> # This program is free software; you can redistribute it and/or modify  
> # it under the terms of the GNU General Public License as published by  
> # the Free Software Foundation; either version 2 of the License, or  
> # (at your option) any later version.  
> #  
> # This program is distributed in the hope that it will be useful,  
> # but WITHOUT ANY WARRANTY; without even the implied warranty of  
> # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
> # GNU General Public License for more details.  
> #  
> # You should have received a copy of the GNU General Public License along  
> # with this program; if not, write to the Free Software Foundation, Inc.,  
> # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  
> #  
> #++
> 
> require 'rubygems'  
> Gem.manage\_gems
> 
> required\_version = Gem::Version::Requirement.new("\>= 1.8.0")  
> unless required\_version.satisfied\_by?(Gem::Version.new(RUBY\_VERSION))  
> &nbsp;&nbsp;&nbsp;puts "Expected Ruby Version #{required\_version}, was #{RUBY\_VERSION}"  
> &nbsp;&nbsp;&nbsp;exit(1)  
> end
> 
> Gem::RemoteInstaller.class\_eval do
> 
> &nbsp;&nbsp;&nbsp;alias\_method :find\_gem\_to\_install\_without\_ruby\_only\_platform, :find\_gem\_to\_install
> 
> &nbsp;&nbsp;&nbsp;def find\_gem\_to\_install( gem\_name, version\_requirement, caches = nil )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if caches # old version of rubygems used to pass a caches object  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caches.each {|k,v| caches[k].each { |name,spect| caches[k].remove\_spec(name) unless spec.platform == (ENV['GEMCMD\_PLATFORM']||Gem::Platform::RUBY) } }  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find\_gem\_to\_install\_without\_ruby\_only\_platform( gem\_name, version\_requirement, caches )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gem::StreamUI.class\_eval do
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias\_method :choose\_from\_list\_without\_choosing\_ruby\_only, :choose\_from\_list  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def choose\_from\_list( question, list )  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result\_index = -1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result= nil  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.each\_with\_index do |item,index|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if item.match(/\(#{ENV['GEMCMD\_PLATFORM']||Gem::Platform::RUBY}\)/)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result\_index = index  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = item  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return [result, result\_index]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find\_gem\_to\_install\_without\_ruby\_only\_platform( gem\_name, version\_requirement )
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;end  
> end
> 
> # We need to preserve the original ARGV to use for passing gem options  
> # to source gems. If there is a -- in the line, strip all options after  
> # it...its for the source building process.  
> args = !ARGV.include?("--") ? ARGV.clone : ARGV[0...ARGV.index("--")]
> 
> Gem::GemRunner.new.run(args)

---

<div class="post-metadata">

**Author:** ![Eric\_Hodel1](https://avatars.discourse-cdn.com/v4/letter/e/a9adbd/32.png) [@Eric\_Hodel1](https://rubytalk.org/u/Eric_Hodel1)\
**Post date:** [12 November 2007 23:20 UTC](https://rubytalk.org/t/automating-gem-installs/42054/8 "2007-11-12T23:20:11Z")

</div>

No, try the beta.

There's a new one coming out probably Tuesday night, I'm waiting on one more patch.

> **···**
>
> On Nov 11, 2007, at 15:01 , Justin Hahn wrote:
> 
> > nate wrote:
> > 
> > > - install the gem(one gem at a time!), for me I resolve dependencies  
> > > manually, and download the gems direct from  
> > > [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)
> > 
> > That tells me what I needed to know. The only way to accomplish this  
> > right now is by downloading the gems manually and installing them that  
> > way. I was beginning to lean that way anyhow, but I guess there are  
> > worse things than making my dependencies more explicit.
> 
> --  
> Poor workers blame their tools. Good workers build better tools. The  
> best workers get their tools to do the work for them. -- Syndicate Wars

---

<div class="post-metadata">

**Author:** ![Justin\_Hahn](https://avatars.discourse-cdn.com/v4/letter/j/898d66/32.png) [@Justin\_Hahn](https://rubytalk.org/u/Justin_Hahn)\
**Post date:** [13 November 2007 15:04 UTC](https://rubytalk.org/t/automating-gem-installs/42054/9 "2007-11-13T15:04:02Z")

</div>

Eric Hodel wrote:

> **···**
>
> > On Nov 11, 2007, at 06:28 , nate wrote:
> > 
> > > - install the gem(one gem at a time!), for me I resolve dependencies  
> > > manually, and download the gems direct from  
> > > [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)
> > 
> > No!!!
> > 
> > Download gems direct from [RubyGems.org | your community gem host](http://gems.rubyforge.org/gems%5C). It will  
> > round-robin across all the mirrors.
> > 
> > Don't punish one mirror.
> 
> You may want to update this page then:
> 
> [http://gems.rubyforge.org/](http://gems.rubyforge.org/)
> 
> The gems link is a direct reference to that one mirror.  
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Tom\_Copeland](https://avatars.discourse-cdn.com/v4/letter/t/94ad74/32.png) [@Tom\_Copeland](https://rubytalk.org/u/Tom_Copeland)\
**Post date:** [13 November 2007 15:19 UTC](https://rubytalk.org/t/automating-gem-installs/42054/10 "2007-11-13T15:19:00Z")

</div>

Yup, what Eric said. And thanks again to our mirror providers!

[http://rubyforge.org/credits/](http://rubyforge.org/credits/)

Yours,

Tom

> **···**
>
> On Tue, 2007-11-13 at 08:21 +0900, Eric Hodel wrote:
> 
> > On Nov 11, 2007, at 06:28 , nate wrote:  
> > \> - install the gem(one gem at a time!), for me I resolve dependencies  
> > \> manually, and download the gems direct from  
> > \> [http://rubyforge.vm.bytemark.co.uk/gems/](http://rubyforge.vm.bytemark.co.uk/gems/)
> > 
> > No!!!
> > 
> > Download gems direct from [RubyGems.org | your community gem host](http://gems.rubyforge.org/gems%5C). It will  
> > round-robin across all the mirrors.
> > 
> > Don't punish one mirror.

---

<div class="post-metadata">

**Author:** ![nate2](https://avatars.discourse-cdn.com/v4/letter/n/c89c15/32.png) [@nate2](https://rubytalk.org/u/nate2)\
**Post date:** [12 November 2007 23:19 UTC](https://rubytalk.org/t/automating-gem-installs/42054/11 "2007-11-12T23:19:30Z")

</div>

Ezra Zygmuntowicz wrote:

> Here is a script called gemcmd. This script is to be used in place of  
> the gem command. It will choose the proper platform and will install  
> the latest version of the requested gem available with no interaction  
> so it is suitable to be called from scripts.

Looks like that script has it's uses, but it wouldn't be suitable for  
me, I want to be sure that the same version of a gem is installed on  
every system, whether I install the system in 10 minutes or 6 weeks  
from now, or 6 months from now(been running most of the same gem versions  
for probably at least 10 months so far).

nate
