How to maintain ruby project that works with Ruby and JRuby
If your Ruby/Rails project has to work with Ruby and JRuby at the same time, sooner or later you’ll end up with Gemfile that has a lot of if logic:
# Gemfile
if RUBY_PLATFORM == "java" # jruby
gem "jdbc-postgres"
gem "activerecord-jdbcpostgresql-adapter"
else
gem "pg", '0.13.2'
end
If you have a lot of dependencies this if logic complicates and pollutes your code.
How can we simplify this code? Easy - keep two separate Gemfile - one for Ruby (Gemfile) and another for JRuby (Gemfile-jruby).
You need to tell your bundler though which Gemfile needs to be used.
If you want to run bundler with different Gemfile, run it this way:
BUNDLE_GEMFILE=Gemfile-jruby bundle
This is fine, but you have to remember to provide additional environment variable every time you run the command.
If you want to select Gemfile automatically when you change ruby or gemset, you can use rvm hook. All hooks for rvm are located in ~/.rvm/hooks folder.
Create or edit this file:
vi ~/.rvm/hooks/after_use_jruby
Locate line with if [[ “${rvmrubystring}” =~ “jruby” ]] and add your code:
#!/usr/bin/env bash
\. "${rvm_path}/scripts/functions/hooks/jruby"
if [[ "${rvm_ruby_string}" =~ "jruby" ]]
then
export BUNDLE_GEMFILE="Gemfile-jruby"
else
export BUNDLE_GEMFILE="Gemfile"
fi
Change rights for this file to make it executable:
chmod +x ~/.rvm/hooks/after_use_jruby
Now, every time you change directory to your project, rvm will setup all environment variables as before plus your BUNDLE_GEMFILE variable.
If your current ruby (.ruby-version) is jruby, it will use Gemfile-jruby, otherwise - Gemfile.