RUBYGEMS_GEMDEPS is a 'new' environment variable for RubyGems(>=2.2.0). With this line of code in your
You don't need to type
bundle exec anymore.
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
rake, they use binstubs generated by RubyGems, and don't use the information from the
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'
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.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
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
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!
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
gem related commands will become really slow. For example, with the following
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.
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!
No app left behind: Upgrade your application to Ruby 3.0 and s...
A look forward from 2020
Testing Rails applications on real mobile devices (both design...
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.
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.
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.
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.