Skip to content

Commit 28cc13a

Browse files
Merge pull request #7310 from rubygems/fix-bundle-update-bundler
Fix `bundle update --bundler` when latest version does not support current ruby
2 parents 10d74a3 + c5f4c91 commit 28cc13a

File tree

7 files changed

+115
-45
lines changed

7 files changed

+115
-45
lines changed

bundler/lib/bundler/self_manager.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def remote_specs
121121
source = Bundler::Source::Rubygems.new("remotes" => "https://rubygems.org")
122122
source.remote!
123123
source.add_dependency_names("bundler")
124-
source.specs
124+
source.specs.select(&:matches_current_metadata?)
125125
end
126126
end
127127

bundler/spec/commands/update_spec.rb

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,26 +1371,28 @@
13711371
expect(the_bundle).to include_gem "rack 1.0"
13721372
end
13731373

1374-
it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo, :realworld do
1374+
it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo do
13751375
pristine_system_gems "bundler-2.3.9"
13761376

13771377
build_repo4 do
13781378
build_gem "rack", "1.0"
1379+
1380+
build_bundler "999.0.0"
13791381
end
13801382

1381-
install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
1383+
install_gemfile <<-G
13821384
source "#{file_uri_for(gem_repo4)}"
13831385
gem "rack"
13841386
G
13851387
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
13861388

1387-
bundle :update, bundler: true, artifice: "vcr", verbose: true, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
1389+
bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
13881390

13891391
# Only updates properly on modern RubyGems.
13901392

13911393
if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev")
1392-
expect(out).to include("Updating bundler to 2.3.10")
1393-
expect(out).to include("Using bundler 2.3.10")
1394+
expect(out).to include("Updating bundler to 999.0.0")
1395+
expect(out).to include("Using bundler 999.0.0")
13941396
expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.")
13951397

13961398
expect(lockfile).to eq <<~L
@@ -1406,16 +1408,63 @@
14061408
rack
14071409
14081410
BUNDLED WITH
1409-
2.3.10
1411+
999.0.0
14101412
L
14111413

1412-
expect(the_bundle).to include_gems "bundler 2.3.10"
1414+
expect(the_bundle).to include_gems "bundler 999.0.0"
1415+
expect(the_bundle).to include_gems "rack 1.0"
1416+
else
1417+
# Old RubyGems versions do not trampoline but they still change BUNDLED
1418+
# WITH to the latest bundler version. This means the below check fails
1419+
# because it tries to use bundler 999.0.0 which did not get installed.
1420+
# Workaround the bug by forcing the version we know is installed.
1421+
expect(the_bundle).to include_gems "rack 1.0", env: { "BUNDLER_VERSION" => "2.3.9" }
1422+
end
1423+
end
1424+
1425+
it "does not update the bundler version in the lockfile if the latest version is not compatible with current ruby", :ruby_repo do
1426+
pristine_system_gems "bundler-2.3.9"
1427+
1428+
build_repo4 do
1429+
build_gem "rack", "1.0"
1430+
1431+
build_bundler "2.3.9"
1432+
build_bundler "999.0.0" do |s|
1433+
s.required_ruby_version = "> #{Gem.ruby_version}"
1434+
end
14131435
end
14141436

1437+
install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
1438+
source "#{file_uri_for(gem_repo4)}"
1439+
gem "rack"
1440+
G
1441+
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
1442+
1443+
bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLER_IGNORE_DEFAULT_GEM" => "true" }
1444+
1445+
expect(out).to include("Using bundler 2.3.9")
1446+
1447+
expect(lockfile).to eq <<~L
1448+
GEM
1449+
remote: #{file_uri_for(gem_repo4)}/
1450+
specs:
1451+
rack (1.0)
1452+
1453+
PLATFORMS
1454+
#{lockfile_platforms}
1455+
1456+
DEPENDENCIES
1457+
rack
1458+
1459+
BUNDLED WITH
1460+
2.3.9
1461+
L
1462+
1463+
expect(the_bundle).to include_gems "bundler 2.3.9"
14151464
expect(the_bundle).to include_gems "rack 1.0"
14161465
end
14171466

1418-
it "errors if the explicit target version does not exist", :realworld do
1467+
it "errors if the explicit target version does not exist" do
14191468
pristine_system_gems "bundler-2.3.9"
14201469

14211470
build_repo4 do
@@ -1428,7 +1477,7 @@
14281477
G
14291478
lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9")
14301479

1431-
bundle :update, bundler: "999.999.999", artifice: "vcr", raise_on_error: false
1480+
bundle :update, bundler: "999.999.999", artifice: "compact_index", raise_on_error: false
14321481

14331482
# Only gives a meaningful error message on modern RubyGems.
14341483

bundler/spec/support/artifice/vcr_cassettes/realworld/rubygems.org/gems/bundler-2.3.10.gem/GET/request

Lines changed: 0 additions & 7 deletions
This file was deleted.

bundler/spec/support/builders.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ def build_lib(name, *args, &blk)
297297
build_with(LibBuilder, name, args, &blk)
298298
end
299299

300+
def build_bundler(*args, &blk)
301+
build_with(BundlerBuilder, "bundler", args, &blk)
302+
end
303+
300304
def build_gem(name, *args, &blk)
301305
build_with(GemBuilder, name, args, &blk)
302306
end
@@ -402,6 +406,49 @@ def required_ruby_version=(*reqs)
402406
alias_method :dep, :runtime
403407
end
404408

409+
class BundlerBuilder
410+
attr_writer :required_ruby_version
411+
412+
def initialize(context, name, version)
413+
raise "can only build bundler" unless name == "bundler"
414+
415+
@context = context
416+
@version = version || Bundler::VERSION
417+
end
418+
419+
def _build(options = {})
420+
full_name = "bundler-#{@version}"
421+
build_path = @context.tmp + full_name
422+
bundler_path = build_path + "#{full_name}.gem"
423+
424+
Dir.mkdir build_path
425+
426+
@context.shipped_files.each do |shipped_file|
427+
target_shipped_file = shipped_file
428+
target_shipped_file = shipped_file.sub(/\Alibexec/, "exe") if @context.ruby_core?
429+
target_shipped_file = build_path + target_shipped_file
430+
target_shipped_dir = File.dirname(target_shipped_file)
431+
FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir)
432+
FileUtils.cp shipped_file, target_shipped_file, preserve: true
433+
end
434+
435+
@context.replace_version_file(@version, dir: build_path)
436+
@context.replace_required_ruby_version(@required_ruby_version, dir: build_path) if @required_ruby_version
437+
438+
Spec::BuildMetadata.write_build_metadata(dir: build_path)
439+
440+
@context.gem_command "build #{@context.relative_gemspec}", dir: build_path
441+
442+
if block_given?
443+
yield(bundler_path)
444+
else
445+
FileUtils.mv bundler_path, options[:path]
446+
end
447+
ensure
448+
build_path.rmtree
449+
end
450+
end
451+
405452
class LibBuilder
406453
def initialize(context, name, version)
407454
@context = context

bundler/spec/support/helpers.rb

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -326,34 +326,8 @@ def install_gem(path, install_dir, default = false)
326326
gem_command "install #{args} '#{path}'"
327327
end
328328

329-
def with_built_bundler(version = nil)
330-
version ||= Bundler::VERSION
331-
full_name = "bundler-#{version}"
332-
build_path = tmp + full_name
333-
bundler_path = build_path + "#{full_name}.gem"
334-
335-
Dir.mkdir build_path
336-
337-
begin
338-
shipped_files.each do |shipped_file|
339-
target_shipped_file = shipped_file
340-
target_shipped_file = shipped_file.sub(/\Alibexec/, "exe") if ruby_core?
341-
target_shipped_file = build_path + target_shipped_file
342-
target_shipped_dir = File.dirname(target_shipped_file)
343-
FileUtils.mkdir_p target_shipped_dir unless File.directory?(target_shipped_dir)
344-
FileUtils.cp shipped_file, target_shipped_file, preserve: true
345-
end
346-
347-
replace_version_file(version, dir: build_path)
348-
349-
Spec::BuildMetadata.write_build_metadata(dir: build_path)
350-
351-
gem_command "build #{relative_gemspec}", dir: build_path
352-
353-
yield(bundler_path)
354-
ensure
355-
build_path.rmtree
356-
end
329+
def with_built_bundler(version = nil, &block)
330+
Builders::BundlerBuilder.new(self, "bundler", version)._build(&block)
357331
end
358332

359333
def with_gem_path_as(path)

bundler/spec/support/path.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ def replace_version_file(version, dir: source_root)
250250
File.open(version_file, "w") {|f| f << contents }
251251
end
252252

253+
def replace_required_ruby_version(version, dir:)
254+
gemspec_file = File.expand_path("bundler.gemspec", dir)
255+
contents = File.read(gemspec_file)
256+
contents.sub!(/(^\s+s\.required_ruby_version\s*=\s*)"[^"]+"/, %(\\1"#{version}"))
257+
File.open(gemspec_file, "w") {|f| f << contents }
258+
end
259+
253260
def ruby_core?
254261
# avoid to warnings
255262
@ruby_core ||= nil

0 commit comments

Comments
 (0)