aboutsummaryrefslogtreecommitdiffstats
path: root/spec/commands
diff options
context:
space:
mode:
authorchrismo <chrismo@clabs.org>2016-09-15 09:56:54 -0500
committerchrismo <chrismo@clabs.org>2016-09-27 10:05:41 -0500
commit4ab674fa04c08e63fbea147cdce77e7630cdb528 (patch)
treed5510218ca265c7d3061f152fc0536bf2acbaa08 /spec/commands
parent62c53199d2f64e5274532b6831a0a7b790ac9350 (diff)
downloadbundler-4ab674fa04c08e63fbea147cdce77e7630cdb528.tar.gz
Fix disable_shared_gems bug & keep nested exec
tl;dr `--deployment` will copy _all_ gems to the `--path` now and a proper fix is in place for nested bundle execs when `--path` is set and RubyGems >=2.6.2 is being used. Fixes #4974. There's two problems blended in here. Let's trace the events here from the beginning, shall we? First off, from probably the first versions of Bundler, when `disable_shared_gems` is true, the `GEM_PATH` gets internally overridden and initialized to an empty string. This is done to make sure that later in the `Bundler.setup` process it's expanded to ONLY the Bundler `--path` setting, otherwise it expands to include the system gems path. In 1.12, `bundle exec` was changed to use `Kernel.load` in some cases, and that new code path calls `require "bundler/setup"`. Later, issue #4592 was filed, showing that in cases like `--deployment` where `disable_shared_gems` is true, Bundler couldn't find itself, because Bundler never lives in the `--path` but only in system gems. And as it would later be discovered, was not a problem with RubyGems 2.6.1, but was a problem with >=2.6.2 (and older RubyGems it would seem, though those weren't as thoroughly investigated). We fixed #4592 (see PR #4701) in 1.13.0 by changing the oooold code initializing `GEM_PATH` to be initialized to `nil` instead of empty string in all `disable_shared_gems` cases. But it created another bug, filed as #4974, wherein system gems were no longer copied to the `--path` when `disable_shared_gems` was true. In this commit here (#4992) we've reverted the change so that `GEM_PATH` is now back to being initialized to an empty string instead of `nil`. That fixes #4974, but regresses #4592, and we needed a new way to fix it. After a few tortured attempts at this, I ran across issue #4602, a similar report of nested bundle execs being broken, #4602 itself an extension of #4381 reporting the same problem. It brought to light the role the Rubygems version played in the problem. When the `bundler` gem is installed and the wrapper is generated for any gem executables, the contents of this wrapper are determined by the Rubygems version. Up until RubyGems 2.6.1 the last line of this wrapper calls `Gem.bin_path`. Bundler replaces the Rubygems implementation of `Gem.bin_path` with its own, and has for a long time made a special exception for the Bundler gem itself, short-circuiting with the contents of a special ENV variable called `BUNDLE_BIN_PATH`. In Rubygems 2.6.2, `bin_path` was superseded by a new `Gem.activate_bin_path` method which did what `bin_path` did but also activated the gem. Bundler 1.13 added support for this, but it didn't include the same short-circuit for bundler itself. (Alert user @taoza even noticed this here https://github.com/bundler/bundler/pull/4341/commits/fcaab3534bb88c4f4a27bc177221181f7c19c73a#r56665282). This commit also includes that short circuit for Rubygems >=2.6.2 now and nested bundle exec should continue to work. Thx to @miros for filing #4974 and isolating the problem in 1.12, @segiddins for many contributions and better ideas, and everyone else for their bug reports and patience :)
Diffstat (limited to 'spec/commands')
-rw-r--r--spec/commands/exec_spec.rb25
1 files changed, 24 insertions, 1 deletions
diff --git a/spec/commands/exec_spec.rb b/spec/commands/exec_spec.rb
index 42afbd24..4dc47919 100644
--- a/spec/commands/exec_spec.rb
+++ b/spec/commands/exec_spec.rb
@@ -2,8 +2,9 @@
require "spec_helper"
describe "bundle exec" do
+ let(:system_gems_to_install) { %w(rack-1.0.0 rack-0.9.1) }
before :each do
- system_gems "rack-1.0.0", "rack-0.9.1"
+ system_gems(system_gems_to_install)
end
it "activates the correct gem" do
@@ -627,4 +628,26 @@ __FILE__: #{path.to_s.inspect}
end
end
end
+
+ context "nested bundle exec" do
+ let(:system_gems_to_install) { super() << :bundler }
+ before do
+ gemfile <<-G
+ source "file://#{gem_repo1}"
+ gem "rack"
+ G
+ bundle :install, :system_bundler => true, :path => "vendor/bundler"
+ end
+
+ it "overrides disable_shared_gems so bundler can be found" do
+ file = bundled_app("file_that_bundle_execs.rb")
+ create_file(file, <<-RB)
+ #!#{Gem.ruby}
+ puts `bundle exec echo foo`
+ RB
+ file.chmod(0o777)
+ bundle! "exec #{file}", :system_bundler => true
+ expect(out).to eq("foo")
+ end
+ end
end