From 540bcf524850854fdf199096da1e0e829e1dfbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 2 Aug 2024 20:59:31 +0200 Subject: [PATCH] [rubygems/rubygems] Fix locked source not getting respected when `bundle update ` is run https://github.com/rubygems/rubygems/commit/eec6830c04 --- lib/bundler/definition.rb | 8 +++ spec/bundler/install/gemfile/sources_spec.rb | 66 ++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 31b9517693..d2cab437a0 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -214,6 +214,7 @@ module Bundler @resolve = nil @resolver = nil @resolution_packages = nil + @source_requirements = nil @specs = nil Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})" @@ -499,6 +500,8 @@ module Bundler @unlocking end + attr_writer :source_requirements + private attr_reader :sources @@ -971,6 +974,10 @@ module Bundler end def source_requirements + @source_requirements ||= find_source_requirements + end + + def find_source_requirements # Record the specs available in each gem's source, so that those # specs will be available later when the resolver knows where to # look for that gemspec (or its dependencies) @@ -1052,6 +1059,7 @@ module Bundler def dup_for_full_unlock unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles) + unlocked_definition.source_requirements = source_requirements unlocked_definition.gem_version_promoter.tap do |gvp| gvp.level = gem_version_promoter.level gvp.strict = gem_version_promoter.strict diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index 279aef79d5..84af5c0d06 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -1921,4 +1921,70 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to include("Could not find gem 'example' in rubygems repository https://gem.repo4/") end end + + context "when a gem has versions in two sources, but only the locked one has updates" do + let(:original_lockfile) do + <<~L + GEM + remote: https://main.source/ + specs: + activesupport (1.0) + bigdecimal + bigdecimal (1.0.0) + + GEM + remote: https://main.source/extra/ + specs: + foo (1.0) + bigdecimal + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + activesupport + foo! + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + before do + build_repo3 do + build_gem "activesupport" do |s| + s.add_dependency "bigdecimal" + end + + build_gem "bigdecimal", "1.0.0" + build_gem "bigdecimal", "3.3.1" + end + + build_repo4 do + build_gem "foo" do |s| + s.add_dependency "bigdecimal" + end + + build_gem "bigdecimal", "1.0.0" + end + + gemfile <<~G + source "https://main.source" + + gem "activesupport" + + source "https://main.source/extra" do + gem "foo" + end + G + + lockfile original_lockfile + end + + it "properly upgrades the lockfile when updating that specific gem" do + bundle "update bigdecimal --conservative", artifice: "compact_index_extra_api", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo3.to_s } + + expect(lockfile).to eq original_lockfile.gsub("bigdecimal (1.0.0)", "bigdecimal (3.3.1)") + end + end end