Making it easier to install gems on Windows
When you install gems, you’re usually asked what version you want to install. Windows users have to choose the one that says ‘mswin32′. This can be really, really awkward for people who are new to this. You have to admit that this is comfusing for a first-time Rails on Windows user:
Select which gem to install for your platform (i386-mswin32) 1. mongrel 1.0.1 (mswin32) 2. mongrel 1.0.1 (ruby) 3. mongrel 1.0 (mswin32) 4. mongrel 1.0 (ruby) 5. Skip this gem 6. Cancel installation >
I’ve had lots of students say that they thought they should choose the Ruby one because that’s what they’re programming in.
I found a great example at http://revolutiononrails.blogspot.com/2007/06/code-digest-2.html by Todd Fisher that explained how to skip the os and version selection on Linux, so I modified it slightly to work with Windows and I’ve added my own method to make installation of gems easier for Windows users.
Here’s how it works: You install gems via a new command on Windows to skip selection of OS and version number.
This will install the gem with dependencies, without documentation. I made the choice to skip doc generation because it’s much faster, but you can modify the script below to take that out, or even make it optional, based on parameters you pass in.
Examples of use:
gem_install rails gem_install rails mongrel mongrel_service capistrano redcloth tzinfo zentest rcov
Here’s the source code for the file. Save this to c:\ruby\bin\gem_install.bat or anywhere on your PATH.
gem_install.bar source code:
@echo off
goto endofruby
#!/bin/ruby
# Cobbled together by Brian Hogan from scripts found at
# http://svn.bountysource.com/fishplate/scripts/debian_install.pl
# and http://revolutiononrails.blogspot.com/2007/06/code-digest-2.html by Todd Fisher.
# Many thanks to their hard work for their solutions that finally made this possible.
require 'rubygems'
Gem.manage_gems
# Patch gems to only install the latest Windows version of the gems.
Gem::RemoteInstaller.class_eval do
alias_method :find_gem_to_install_without_ruby_only_platform, :find_gem_to_install
def find_gem_to_install( gem_name, version_requirement, caches = nil )
if caches # old version of rubygems used to pass a caches object
caches.each {|k,v| caches[k].each { |name,spect| caches[k].remove_spec(name) unless spec.platform == 'ruby' } }
find_gem_to_install_without_ruby_only_platform( gem_name, version_requirement, caches )
else
Gem::StreamUI.class_eval do
alias_method :choose_from_list_without_choosing_ruby_only, :choose_from_list
def choose_from_list( question, list )
result = nil
result_index = -1
list.each_with_index do |item,index|
if item.match(/(mswin32)/)
result_index = index
result = item
break
end
end
return [result, result_index]
end
end
find_gem_to_install_without_ruby_only_platform( gem_name, version_requirement )
end
end
end
# end patching of Gems.
# Install multiple gems with dependencies and without documentation.
# pass in an array of gem names to install.
#
# install_gems "mongrel", "redcloth", "mongrel_service", "tzinfo", "capistrano"
#
#
def install_gems(*attrs)
attrs.flatten!
puts attrs.inspect
attrs.each do |gem_name|
puts "installing gem #{gem_name}"
Gem:: GemRunner.new.run(['install', gem_name, '--include-dependencies', '--no-rdoc', '--no-ri'])
end
end
if ARGV[0] == "help"
puts "Install gems via this tool on Windows to skip selection of OS and version number. This will install the gem with dependencies, without documentation."
puts "Examples:"
puts " gem_install rails"
puts " gem_install rails mongrel mongrel_service"
puts "Report bugs to info@napcs.com ."
else
install_gems ARGV
end
__END__
:endofruby
"ruby" -x "%~f0" %*
That’s it. It works great so far and I’m going to be embedding this into the Eclipse for Rails installation. You Mac users should have no trouble taking this concept to your platform. It just involves changing the regex from mswin32 to ruby in the Ruby portion of the script and then copying the Ruby code into its own .rb file that you mark executable.
I should say something about how the whole thing works. When you run the batch file, it skips over the Ruby code because of the goto command and then actually passes itself to the Ruby interpreter.
ruby -x gem_install.bat rails mongrel
The additional parameters you send to the batch file are also passed along to the Ruby script as well. The Ruby interpreter ignores everything in the file until it gets to the shebang line (#!/bin/ruby). It starts executing code from this point on, but then it stops when it gets to __END__. Everything else in the file is ignored.
This method is how we Windows users get to do things like rake or gem or even rails Linux users can just set a Ruby script to be executable. Windows users have a little more trouble doing that so we cheat.
Before I go, I should say that I could not have done this without Curt Hibbs, who uses this batch-file-to-ruby approach in the One-Click Ruby Installer. He’s a swell guy.
If you’ve got comments, I’d love to hear them. Let me know what you think, or if there are ways I can improve this.
