I’ve been using chruby
to manage my ruby versions for a few
months — I like it’s lightweight approach.
A combination of bundler’s binstubs, the introduction
of rails 4 introducing the bin
directory and trying to use the
environment to configure my apps has meant I wanted a way to
to manage my environment on a per project basis.
I’ve tried using dotenv, which works well for ruby projects, and for
setting environment variables to be used by your app — but, as far as
I can tell, it doesn’t actually modify your environment. So setting your PATH
to select the correct binary, e.g. bin/rails
in a rails app, won’t work.
Enter direnv
. direnv
looks for a .envrc
file in a directory and
loads any thing there into your environment. You have to specifically allow
direnv to load a file, and it tracks modifications to the file. It’s very nice.
Unfortunately, I had a problem using it alongside chruby
— everytime
I entered a directory direnv
would do it’s thing and then chruby
would
follow suit, and I could never quite get the result I wanted! For example, I’d
have the right version of ruby, but the wrong PATH
&mdash or the right PATH
with the wrong ruby.
To fix this I removed chruby
’s auto switching feature from my default
environment, and based on a suggestion here added a use_ruby
function to my ~/.direnvrc
:
source /usr/local/share/chruby/chruby.sh
# use ruby [version]
use_ruby() {
local ver=$1
if [[ -z $ver ]] && [[ -f .ruby-version ]]; then
ver=$(cat .ruby-version)
fi
if [[ -z $ver ]]; then
echo Unknown ruby version
exit 1
fi
chruby $ver
}
This checks for a .ruby-version
file, and, if it finds one, defers to chruby
to load the correct ruby environment.
I can now use this function in a project .envrc
to load ruby before I modify
the path:
use ruby
PATH_add bin
You can also pass a ruby version to the use_ruby
function:
use ruby 2.1
PATH_add bin
If you don’t want to use a .ruby-version
file.
This seems to work really well. The only downside is that I don’t have autoswitching of ruby versions anymore — unless I decide that’s what I want. I don’t think its too bad to have to be explicit about that.