Toxic Elephant

A tiny replacement for RVM

Posted by matijs 31/07/2011 at 17h31

Recently, there was a change in where Debian’s rubygems packages store each gem’s files. Instead of having a separate bin directory for each version of ruby, now both the 1.8 and the 1.9 version store scripts in /usr/local/bin. In fact, they will happily overwrite each other’s scripts. This can be very confusing when you think you’re running a script with Ruby 1.8, but in fact it’s running with 1.9, and hence, 1.9’s set of installed gems.

All this made me seriously consider using RVM. Which was quite shocking, as I consider it to be an ugly hack, both in concept and in execution. So, rather than admitting defeat, I decided to create my own hack.

The first thing I did was make rubygems install into my home directory, by putting the option --user-install in my .gemrc. That way, I regained separate bin directories, solving that part of the problem.

Next, of course, I had to be able to quickly switch between those separate bin directories. For this, I made the following zsh function (I use zsh as my shell):

<typo:code lang=”zsh”> use_ruby() { case $1 in

ruby1.8)
  gemdirsuffix="ruby/1.8"
  ruby="ruby1.8"
  gem="gem1.8"
  ;;
ruby1.9.1)
  gemdirsuffix="ruby/1.9.1"
  ruby="ruby1.9.1"
  gem="gem1.9.1"
  ;;
jruby)
  gemdirsuffix="jruby/1.8"
  ruby="jruby"
  gem="jgem"
  ;;
system)
  ;;
*)
  print "Unknown ruby: $1"; return ;;

esac

newpath=() for p in $path do

case $p in
  *.gem*)
    ;;
  *)
    newpath=($newpath $p)
    ;;
esac

done

case $1 in

system)
  PROMPT="[%n@%m] "
  unalias gem
  unalias ruby
  ;;
*)
  gembin="$HOME/.gem/$gemdirsuffix/bin"
  newpath=($gembin $newpath)
  PROMPT="[%n@%m($1)] "
  alias gem=$gem
  alias ruby=$ruby
  ;;

esac

path=($newpath) unset newpath

rehash

print “Environment set for $1” } </typo:code>

This gives me the entirety of what I need from RVM: The ability to switch between ruby versions and then have all scripts available (if installed) running with that version. I don’t need an extra installation system: I can use apt-get for the default rubies provided, and I can install other rubies using their respective installation methods. For isolation of gems, I have bundler.

What’s missing.

Bundler will try to install in the system’s gem location, ignoring the --user-install in .gemrc. This can probably be solved with a little juggling of environment variables like GEM_HOME. I’ll get round to it once I get annoyed enough with running bundle install --local and installing each missing gem one by one.

Tags no comments Trackbacks

No comments

No trackbacks

Comments are disabled

Toxic Elephant is Matijs van Zuijlen's weblog.

Powered