On Nov 27, 2006, at 1:56 PM, Steven Hansen wrote:

>
>
> Greetings,
>
> I'm wondering if anyone has used Capistrano to automate the  
> installation of gems on remote machines.
>
> The problem I'm having is that when you install a gem from the  
> command line, at various stages it will prompt you for a 'Y' or 'N'  
> answer.
>
> Let's say I have the following task and I want it to run on a  
> remote machine:
>
> desc "Install rails"
> task :install_rails do
>  run "gem install rails"
> end
>
> The task starts up and begins the installation, but then hangs  
> after I get the 'Y' or 'N' prompt.
>
> Is there a way to just skip the prompt and specify 'Y' for everything?
>
> Regards,
> Steven
>

Hey Steven-

	Here is a capistrano plugin for installing gems remotely. This  
supports slecting gem versions or letting it pick from the list  
itself when it gets presented with a list of choices it will choose  
the correct latest version based on architecture.

	This is code adapted and extracted from the vmgen gem for generating  
Xen instances.


require 'capistrano'
# Installs within Capistrano as the plugin _gem_.
# Prefix all calls to the library with <tt>gem.</tt>
# Manages installing gems and versioned gems.
module Gem

   # Default install command
   #
   # * doesn't install documentation
   # * installs all required dependencies automatically.
   #
   GEM_INSTALL="gem install -y --no-rdoc"

   # Upgrade the *gem* system to the latest version. Runs via *sudo*
   def update_system
     sudo "gem update --system"
   end

   # Updates all the installed gems to the latest version. Runs via  
*sudo*.
   # Don't use this command if any of the gems require a version  
selection.
   def upgrade
     sudo "gem update --no-rdoc"
   end

   # Removes old versions of gems from installation area.
   def cleanup
     sudo "gem cleanup"
   end

   # Installs the gems detailed in +packages+, selecting version  
+version+ if
   # specified.
   #
   # +packages+ can be a single string or an array of strings.
   #
   def install(packages, version=nil)
     sudo "#{GEM_INSTALL} #{if version then '-v '+version.to_s end} # 
{packages.to_a.join(' ')}"
   end

   # Auto selects a gem from a list and installs it.
   #
   # *gem* has no mechanism on the command line of disambiguating  
builds for
   # different platforms, and instead asks the user. This method has  
the necessary
   # conversation to select the +version+ relevant to +platform+ (or  
the one nearest
   # the top of the list if you don't specify +version+).
   def select(package, version=nil, platform='ruby')
     selections={}
     cmd="#{GEM_INSTALL} #{if version then '-v '+version.to_s end} # 
{package}"
     sudo cmd do |channel, stream, data|
       data.each_line do | line |
	case line
	when /\s(\d+).*\(#{platform}\)/
	  if selections[channel[:host]].nil?
	    selections[channel[:host]]=$1.dup+"\n"
	    logger.info "Selecting #$&", "#{stream} :: #{channel[:host]}"
	  end
	when /\s\d+\./
	  # Discard other selections from data stream
	when /^>/
	  channel.send_data selections[channel[:host]]
	  logger.debug line, "#{stream} :: #{channel[:host]}"
	else
	  logger.info line, "#{stream} :: #{channel[:host]}"
	end
       end
     end
   end

end

Capistrano.plugin :gem, Gem


Cheers-
-- Ezra Zygmuntowicz 
-- Lead Rails Evangelist
-- ez / engineyard.com
-- Engine Yard, Serious Rails Hosting
-- (866) 518-YARD (9273)