Skip to content

Commit 9ea6249

Browse files
authored
Merge pull request #9249 from Shopify/ec-no-reexec
Fix Bundler that re-exec $0 when a `version` is present in the config:
2 parents fd9b28a + d6e0f43 commit 9ea6249

3 files changed

Lines changed: 84 additions & 32 deletions

File tree

bundler/spec/runtime/self_management_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@
171171
expect(out).to eq(previous_minor)
172172
end
173173

174+
it "requires the right bundler version from the config and run bundle CLI without re-exec" do
175+
unless Bundler.rubygems.provides?(">= 4.1.0.dev")
176+
skip "This spec can only run when Gem::BundlerVersionFinder.bundler_versions reads bundler configs"
177+
end
178+
179+
lockfile_bundled_with(current_version)
180+
181+
bundle "config set --local version #{previous_minor}"
182+
bundle "config set --local path.system true"
183+
bundle "install"
184+
185+
script = bundled_app("script.rb")
186+
create_file(script, "p 'executed once'")
187+
188+
bundle "-v", env: { "RUBYOPT" => "-r#{script}" }
189+
expect(out).to eq(%("executed once"\n9.3.0))
190+
end
191+
174192
it "does not try to install when using bundle config version global" do
175193
lockfile_bundled_with(previous_minor)
176194

lib/rubygems/bundler_version_finder.rb

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ def self.bundler_version
1010
v ||= bundle_update_bundler_version
1111
return if v == true
1212

13+
v ||= bundle_config_version
14+
1315
v ||= lockfile_version
1416
return unless v
1517

@@ -49,21 +51,7 @@ def self.lockfile_version
4951
private_class_method :lockfile_version
5052

5153
def self.lockfile_contents
52-
gemfile = ENV["BUNDLE_GEMFILE"]
53-
gemfile = nil if gemfile&.empty?
54-
55-
unless gemfile
56-
begin
57-
Gem::Util.traverse_parents(Dir.pwd) do |directory|
58-
next unless gemfile = Gem::GEM_DEP_FILES.find {|f| File.file?(f) }
59-
60-
gemfile = File.join directory, gemfile
61-
break
62-
end
63-
rescue Errno::ENOENT
64-
return
65-
end
66-
end
54+
gemfile = gemfile_path
6755

6856
return unless gemfile
6957

@@ -82,19 +70,24 @@ def self.lockfile_contents
8270
private_class_method :lockfile_contents
8371

8472
def self.bundle_config_version
85-
config_file = bundler_config_file
86-
return unless config_file && File.file?(config_file)
73+
version = nil
8774

88-
contents = File.read(config_file)
89-
contents =~ /^BUNDLE_VERSION:\s*["']?([^"'\s]+)["']?\s*$/
75+
[bundler_local_config_file, bundler_global_config_file].each do |config_file|
76+
next unless config_file && File.file?(config_file)
9077

91-
$1
78+
contents = File.read(config_file)
79+
contents =~ /^BUNDLE_VERSION:\s*["']?([^"'\s]+)["']?\s*$/
80+
81+
version = $1
82+
break if version
83+
end
84+
85+
version
9286
end
9387
private_class_method :bundle_config_version
9488

95-
def self.bundler_config_file
96-
# see Bundler::Settings#global_config_file and local_config_file
97-
# global
89+
def self.bundler_global_config_file
90+
# see Bundler::Settings#global_config_file
9891
if ENV["BUNDLE_CONFIG"] && !ENV["BUNDLE_CONFIG"].empty?
9992
ENV["BUNDLE_CONFIG"]
10093
elsif ENV["BUNDLE_USER_CONFIG"] && !ENV["BUNDLE_USER_CONFIG"].empty?
@@ -103,10 +96,36 @@ def self.bundler_config_file
10396
ENV["BUNDLE_USER_HOME"] + "config"
10497
elsif Gem.user_home && !Gem.user_home.empty?
10598
Gem.user_home + ".bundle/config"
106-
else
107-
# local
108-
"config"
10999
end
110100
end
111-
private_class_method :bundler_config_file
101+
private_class_method :bundler_global_config_file
102+
103+
def self.bundler_local_config_file
104+
gemfile = gemfile_path
105+
return unless gemfile
106+
107+
File.join(File.dirname(gemfile), ".bundle", "config")
108+
end
109+
private_class_method :bundler_local_config_file
110+
111+
def self.gemfile_path
112+
gemfile = ENV["BUNDLE_GEMFILE"]
113+
gemfile = nil if gemfile&.empty?
114+
115+
unless gemfile
116+
begin
117+
Gem::Util.traverse_parents(Dir.pwd) do |directory|
118+
next unless gemfile = Gem::GEM_DEP_FILES.find {|f| File.file?(f) }
119+
120+
gemfile = File.join directory, gemfile
121+
break
122+
end
123+
rescue Errno::ENOENT
124+
return
125+
end
126+
end
127+
128+
gemfile
129+
end
130+
private_class_method :gemfile_path
112131
end

test/rubygems/test_gem_bundler_version_finder.rb

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def test_bundler_version_with_bundle_config
6666
f.write(config_content)
6767
f.flush
6868

69-
bvf.stub(:bundler_config_file, f.path) do
69+
bvf.stub(:bundler_global_config_file, f.path) do
7070
assert_nil bvf.bundler_version
7171
end
7272
end
@@ -81,7 +81,7 @@ def test_bundler_version_with_bundle_config_single_quoted
8181
f.write(config_with_single_quoted_version)
8282
f.flush
8383

84-
bvf.stub(:bundler_config_file, f.path) do
84+
bvf.stub(:bundler_global_config_file, f.path) do
8585
assert_nil bvf.bundler_version
8686
end
8787
end
@@ -98,18 +98,33 @@ def test_bundler_version_with_bundle_config_version
9898
f.write(config_content)
9999
f.flush
100100

101-
bvf.stub(:bundler_config_file, f.path) do
101+
bvf.stub(:bundler_global_config_file, f.path) do
102102
assert_equal v("1.1.1.1"), bvf.bundler_version
103103
end
104104
end
105105
end
106106

107107
def test_bundler_version_with_bundle_config_non_existent_file
108-
bvf.stub(:bundler_config_file, "/non/existent/path") do
108+
bvf.stub(:bundler_global_config_file, "/non/existent/path") do
109109
assert_nil bvf.bundler_version
110110
end
111111
end
112112

113+
def test_bundler_version_set_on_local_config
114+
config_content = <<~CONFIG
115+
BUNDLE_VERSION: "1.2.3"
116+
CONFIG
117+
118+
Tempfile.create("bundle_config") do |f|
119+
f.write(config_content)
120+
f.flush
121+
122+
bvf.stub(:bundler_local_config_file, f.path) do
123+
assert_equal v("1.2.3"), bvf.bundler_version
124+
end
125+
end
126+
end
127+
113128
def test_bundler_version_with_bundle_config_without_version
114129
config_without_version = <<~CONFIG
115130
BUNDLE_JOBS: "8"
@@ -120,7 +135,7 @@ def test_bundler_version_with_bundle_config_without_version
120135
f.write(config_without_version)
121136
f.flush
122137

123-
bvf.stub(:bundler_config_file, f.path) do
138+
bvf.stub(:bundler_global_config_file, f.path) do
124139
assert_nil bvf.bundler_version
125140
end
126141
end

0 commit comments

Comments
 (0)