Skip to content
By Leo (Jialiang) Liang

No more bundle exec: using the new RUBYGEMS_GEMDEPS environment variable

TL;DR

RUBYGEMS_GEMDEPS is a 'new' environment variable for RubyGems(>=2.2.0). With this line of code in your .zshrc or .bashrc:

export RUBYGEMS_GEMDEPS=-

You don't need to type bundle exec anymore.

However, RubyGems does not fully support Gemfile syntax yet and still has some fairly serious bugs waiting to be fixed with RUBYGEMS_GEMDEPS, so don't use this feature in your daily development environment at the moment.

Now, if you are still interested, read on for more info :)

The issue with binstub

Back in the day when Rails 3 had just been released, many Rails developers were thrilled by the introduction of bundler, a gem that helped our beloved Rails applications resolve gem dependencies in the project, letting it install and use the correct version of each gem. With bundler, Rails applications always use the expected gems (and versions thereof), which makes us a bunch of happy developers.

But those happy days didn't last very long. Soon, we found that when we run commands like rails or rake, they use binstubs generated by RubyGems, and don't use the information from the Gemfile or Gemfile.lock files.

For example, let's say there are three versions of rack in my development environment, like this:

gem list rack
#=> rack (1.6.4, 1.5.5, 1.5.4)

And I have a Gemfile like this in my project:

ruby "2.2.2"
source "https://rubygems.org"

gem 'rack', '~>1.5.4'

and the Gemfile.lock looks like this:

GEM
  remote: https://rubygems.org/
  specs:
    rack (1.5.4)

PLATFORMS
  ruby

DEPENDENCIES
  rack (~> 1.5.4)

BUNDLED WITH
   1.10.6

Ideally, when I run rackup --version, the result would be:

#=> Rack 1.2 (Release: 1.5.4)

But instead it returns:

#=> Rack 1.3 (Release: 1.6.4)

That is not what I want; I would expect it use rack 1.5.4, not the other version. Luckily, the smart developers who built bundler had already foreseen this issue and provided the command bundle exec for us to use; meaning that we can run binstubs generated by bundler with this command: bundle exec rackup --version, and bundler would pick correct version of rack for us:

#=> Rack 1.2 (Release: 1.5.4)

Some of us live with it, but some don't, because we still need to type bundle exec every time we want to run a command. The latter group found some ways to get around this issue, like using rubygems-bundler, and adding a project-specific binstub folder to the top of $PATH. But we all wish that one day, RubyGems can support the Gemfile and Gemfile.lock files, so that we can just type rackup without any setup required.

Obviously, the RubyGems team is aware of this issue, and they have finally introduced the RUBYGEMS_GEMDEPS environment variable in rubygems 2.2.0.

RUBYGEMS_GEMDEPS

According to RubyGems:

RubyGems can install a consistent set of gems across multiple environments using gem install -g when a gem dependencies file (gem.deps.rb, Gemfile or Isolate) is present. If no explicit file is given RubyGems attempts to find one in the current directory.

When the RUBYGEMS_GEMDEPS environment variable is set to a gem dependencies file the gems from that file will be activated at startup time. Set it to a specific filename or to “-“ to have RubyGems automatically discover the gem dependencies file by walking up from the current directory.

In short, once you put this line in your ~/.bashrc or ~/.zshrc file:

export RUBYGEMS_GEMDEPS=-

Then RubyGems will look for a Gemfile in the current directory, and use the correct version of gems for you.

To prove this, I ran the same command that I ran before, and got following output:

rackup --version
#=> Rack 1.2 (Release: 1.5.4)

RubyGems is smart enough to pick the version in Gemfile.lock, not only the Gemfile. So now we can get rid of rubygems-bundler, and we no longer need project binstub folders in the $PATH. Great! ;) Moreover, note that the latest version of rubygems (2.4.8) still works with Ruby 1.8.7, so you can even use RUBYGEMS_GEMDEPS in ruby 1.8.7!

But...

Wait, if this function is so great, how come it still isn't being widely used by the Ruby community? After all, rubygems 2.2.0 came out at the end of 2013. Unfortunately, that is because RUBYGEMS_GEMDEPS still has some fairly serious bugs waiting to be fixed. One issue I found is that if there are git repos in your Gemfile, many gem related commands will become really slow. For example, with the following Gemfile:

ruby "2.2.2"
source "https://rubygems.org"

gem 'multi_json', git: "https://github.com/intridea/multi_json.git"
gem 'tilt', git: "https://github.com/rtomayko/tilt.git"
gem 'rack', git: "https://github.com/rack/rack.git"
gem 'vcr', git: "https://github.com/vcr/vcr.git"
gem 'shoulda-matchers', git: "https://github.com/thoughtbot/shoulda-matchers.git"

You can see that most of the commands take more than 15s to run:

time bundle #after all gems installed
#=>  bundle  1.02s user 0.46s system 9% cpu 15.658 total
time gem --version
#=> gem --version  0.68s user 0.40s system 7% cpu 14.536 total
time gem list tile
#=> gem list tilt  0.85s user 0.44s system 4% cpu 29.202 total

You can find more information about this here.

Conclusion

I don't suggest that you use this feature in your daily development environment at the moment. However, I do believe that sometime in the near future, RUBYGEMS_GEMDEPS will be ready, and will be the best approach for handling the binstub issue. So I encourage you to give it a try, and submit any issues you find here!

Latest Articles by Our Team

Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.

We Hire Only the Best

reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.

We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.

Free Community Workshops

We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.

  • Webinars

    Webinars

    Webinars are our online portal for tips, tricks and lessons learned in everything we do. Make the most of this free resource to help you become a better developer.

    Learn more about webinars

  • Installfest

    Installfest

    The Ruby on Rails Installfest includes a full setup of your development environment and step-by-step instructions on how to build your first app hosted on Heroku. Over 1,800 attendees to date and counting.

    Learn more about Installfest

  • Development Hub

    Development Hub

    The Ruby on Rails Development Hub is a monthly event where you will get the chance to spend time with our team and others in the community to improve and hone your Ruby on Rails skills.

    Learn more about Development Hub

Get the “reinteractive Review” Monthly Email