From 80f39d78df618baf5af44692db2ca96d5bd4dbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 12 Nov 2021 00:56:19 +0100 Subject: [PATCH] [rubygems/rubygems] Allow `bundle update` to downgrade gems by changing the Gemfile https://github.com/rubygems/rubygems/commit/6a19cca7e5 --- lib/bundler/definition.rb | 2 +- spec/bundler/commands/update_spec.rb | 61 ++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index c009397b08..750536089b 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -853,7 +853,7 @@ module Bundler def additional_base_requirements_for_resolve return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) dependencies_by_name = dependencies.inject({}) {|memo, dep| memo.update(dep.name => dep) } - @locked_gems.specs.reduce({}) do |requirements, locked_spec| + converge_specs(@locked_gems.specs).reduce({}) do |requirements, locked_spec| name = locked_spec.name dependency = dependencies_by_name[name] next requirements if @locked_gems.dependencies[name] != dependency diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index c8f084ca0e..403a48a508 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -354,6 +354,67 @@ RSpec.describe "bundle update" do expect(the_bundle).to include_gems("a 1.0", "b 1.0") end + + it "should still downgrade if forced by the Gemfile, when transitive dependencies also need downgrade" do + build_repo4 do + build_gem "activesupport", "6.1.4.1" do |s| + s.add_dependency "tzinfo", "~> 2.0" + end + + build_gem "activesupport", "6.0.4.1" do |s| + s.add_dependency "tzinfo", "~> 1.1" + end + + build_gem "tzinfo", "2.0.4" + build_gem "tzinfo", "1.2.9" + end + + install_gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem "activesupport", "~> 6.1.0" + G + + expect(the_bundle).to include_gems("activesupport 6.1.4.1", "tzinfo 2.0.4") + + gemfile <<-G + source "#{file_uri_for(gem_repo4)}" + gem "activesupport", "~> 6.0.0" + G + + original_lockfile = lockfile + + expected_lockfile = <<~L + GEM + remote: #{file_uri_for(gem_repo4)}/ + specs: + activesupport (6.0.4.1) + tzinfo (~> 1.1) + tzinfo (1.2.9) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + activesupport (~> 6.0.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "update activesupport" + expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") + expect(lockfile).to eq(expected_lockfile) + + lockfile original_lockfile + bundle "update" + expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") + expect(lockfile).to eq(expected_lockfile) + + lockfile original_lockfile + bundle "lock --update" + expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") + expect(lockfile).to eq(expected_lockfile) + end end describe "with --local option" do