From 9a8ab67da6567c767307e8861893761542483ba0 Mon Sep 17 00:00:00 2001 From: chrismo Date: Wed, 22 Jun 2016 16:36:21 -0500 Subject: [PATCH] Unset `GEM_PATH` with `nil` not empty string. This should fix #4592, the tests all pass, but the line of code in question goes back to 2010, so this sorta seems slightly dangerous, but it's probable the circumstances of hitting this line in conjunction with `bundle exec` is a combination that didn't exist prior to 1.12.x. Issue #4592 has a full diagnosis, but the gist of it is this: if an empty string is passed as the `GEM_PATH` to the subsequent process launched by `bundle exec`, then if the `cmd` portion of `bundle exec` is a ruby shebanged file, then if the current bundle install uses a local path (`disable_shared_gems` is true) then it won't be able to find the bundler gem at all because Bundler doesn't install itself into its own Bundle, it's only installed in the system gems for the Ruby. `nil` must be passed because the RubyGems code that sets up the `GEM_PATH` does a conditional on the current `GEM_PATH` and empty string evaluates to true, whereas `nil` evaluates to false. In the false case the `GEM_PATH` is internally populated with the system gems path such that the bundler gem can be found. --- lib/bundler.rb | 15 +++++++++------ spec/bundler/bundler_spec.rb | 12 ++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index dcb151b0581..139ccf8a349 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -408,17 +408,20 @@ def eval_gemspec(path, contents) end def configure_gem_home_and_path - blank_home = ENV["GEM_HOME"].nil? || ENV["GEM_HOME"].empty? + configure_gem_path + configure_gem_home + bundle_path + end + + def configure_gem_path(env = ENV, settings = self.settings) + blank_home = env["GEM_HOME"].nil? || env["GEM_HOME"].empty? if settings[:disable_shared_gems] - ENV["GEM_PATH"] = "" + env["GEM_PATH"] = nil elsif blank_home || Bundler.rubygems.gem_dir != bundle_path.to_s possibles = [Bundler.rubygems.gem_dir, Bundler.rubygems.gem_path] paths = possibles.flatten.compact.uniq.reject(&:empty?) - ENV["GEM_PATH"] = paths.join(File::PATH_SEPARATOR) + env["GEM_PATH"] = paths.join(File::PATH_SEPARATOR) end - - configure_gem_home - bundle_path end def configure_gem_home diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb index 2ad3704db08..f338b5268d6 100644 --- a/spec/bundler/bundler_spec.rb +++ b/spec/bundler/bundler_spec.rb @@ -140,4 +140,16 @@ it_behaves_like "it returns the correct executable" end end + + describe "configuration" do + context "disable_shared_gems" do + it "should unset GEM_PATH with nil" do + env = {} + settings = { :disable_shared_gems => true } + Bundler.send(:configure_gem_path, env, settings) + expect(env.keys).to include("GEM_PATH") + expect(env["GEM_PATH"]).to be_nil + end + end + end end