From 11e522b913af36acfe10e8ba9cfc0a14b0335aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Thu, 21 Nov 2024 11:59:57 +0100 Subject: [PATCH] [rubygems/rubygems] Fix installs of subdependencies of unlocked dependencies to be conservative When converging specification to pass the set of versions that should be preserved from the lockfile during resolution, we should make sure all top level gems are considered, and only exclude those gems themselves (and not their dependencies) if their locked versions happen to not be satisfied by an edited Gemfile. https://github.com/rubygems/rubygems/commit/ed2f1b7b88 --- lib/bundler/definition.rb | 7 ++-- spec/bundler/commands/install_spec.rb | 56 +++++++++++++++++++++++++++ spec/bundler/commands/update_spec.rb | 2 +- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 1eb578f7bd..cde87134de 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -1010,11 +1010,12 @@ module Bundler end end - if dep.nil? && requested_dependencies.find {|d| name == d.name } + if dep.nil? && requested_dep = requested_dependencies.find {|d| name == d.name } @gems_to_unlock << name - else - converged << s + deps << requested_dep end + + converged << s end filter_specs(converged, deps).reject {|s| @gems_to_unlock.include?(s.name) } diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 9a4006faaa..1c99a1877a 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -1741,4 +1741,60 @@ RSpec.describe "bundle install with gem sources" do expected_executables << vendored_gems("bin/myrackup.bat").to_s if Gem.win_platform? expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables) end + + it "preserves lockfile versions conservatively" do + build_repo4 do + build_gem "mypsych", "4.0.6" do |s| + s.add_dependency "mystringio" + end + + build_gem "mypsych", "5.1.2" do |s| + s.add_dependency "mystringio" + end + + build_gem "mystringio", "3.1.0" + build_gem "mystringio", "3.1.1" + end + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + mypsych (4.0.6) + mystringio + mystringio (3.1.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + mypsych (~> 4.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + + install_gemfile <<~G + source "https://gem.repo4" + gem "mypsych", "~> 5.0" + G + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + mypsych (5.1.2) + mystringio + mystringio (3.1.0) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + mypsych (~> 5.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + end end diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 2d66c0e550..d28c74ed62 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -1931,7 +1931,7 @@ RSpec.describe "bundle update conservative" do bundle "install" - expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.2", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1" + expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.1", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1" end end