Skip to content

Commit b2375b4

Browse files
Merge pull request #7915 from rubygems/deivid-rodriguez/fix-incorrect-source-on-gem-unlock
Fix `bundle update <indirect_dep>` failing to upgrade when versions present in two different sources
2 parents e7c4377 + eec6830 commit b2375b4

File tree

8 files changed

+108
-24
lines changed

8 files changed

+108
-24
lines changed

bundler/lib/bundler/definition.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ def missing_specs?
214214
@resolve = nil
215215
@resolver = nil
216216
@resolution_packages = nil
217+
@source_requirements = nil
217218
@specs = nil
218219

219220
Bundler.ui.debug "The definition is missing dependencies, failed to resolve & materialize locally (#{e})"
@@ -476,9 +477,6 @@ def most_specific_locked_platform
476477
end
477478
end
478479

479-
attr_reader :sources
480-
private :sources
481-
482480
def nothing_changed?
483481
return false unless lockfile_exists?
484482

@@ -502,8 +500,12 @@ def unlocking?
502500
@unlocking
503501
end
504502

503+
attr_writer :source_requirements
504+
505505
private
506506

507+
attr_reader :sources
508+
507509
def should_add_extra_platforms?
508510
!lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
509511
end
@@ -972,6 +974,10 @@ def metadata_dependencies
972974
end
973975

974976
def source_requirements
977+
@source_requirements ||= find_source_requirements
978+
end
979+
980+
def find_source_requirements
975981
# Record the specs available in each gem's source, so that those
976982
# specs will be available later when the resolver knows where to
977983
# look for that gemspec (or its dependencies)
@@ -1053,6 +1059,7 @@ def additional_base_requirements_to_force_updates(resolution_packages)
10531059

10541060
def dup_for_full_unlock
10551061
unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
1062+
unlocked_definition.source_requirements = source_requirements
10561063
unlocked_definition.gem_version_promoter.tap do |gvp|
10571064
gvp.level = gem_version_promoter.level
10581065
gvp.strict = gem_version_promoter.strict

bundler/spec/commands/outdated_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@
162162
build_gem "vcr", "6.0.0"
163163
end
164164

165-
build_repo gem_repo3 do
165+
build_repo3 do
166166
build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
167167
s.add_dependency "oj"
168168
end

bundler/spec/commands/remove_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@
409409

410410
context "with sources" do
411411
before do
412-
build_repo gem_repo3 do
412+
build_repo3 do
413413
build_gem "rspec"
414414
end
415415
end

bundler/spec/commands/update_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@
956956
build_gem "vcr", "6.0.0"
957957
end
958958

959-
build_repo gem_repo3 do
959+
build_repo3 do
960960
build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s|
961961
s.add_dependency "oj"
962962
end

bundler/spec/install/gemfile/sources_spec.rb

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
before do
99
# Oh no! Someone evil is trying to hijack myrack :(
1010
# need this to be broken to check for correct source ordering
11-
build_repo gem_repo3 do
11+
build_repo3 do
1212
build_gem "myrack", repo3_myrack_version do |s|
1313
s.write "lib/myrack.rb", "MYRACK = 'FAIL'"
1414
end
@@ -156,7 +156,7 @@
156156
before do
157157
# Oh no! Someone evil is trying to hijack myrack :(
158158
# need this to be broken to check for correct source ordering
159-
build_repo gem_repo3 do
159+
build_repo3 do
160160
build_gem "myrack", "1.0.0" do |s|
161161
s.write "lib/myrack.rb", "MYRACK = 'FAIL'"
162162
end
@@ -200,7 +200,7 @@
200200
before do
201201
# Oh no! Someone evil is trying to hijack myrack :(
202202
# need this to be broken to check for correct source ordering
203-
build_repo gem_repo3 do
203+
build_repo3 do
204204
build_gem "myrack", "1.0.0" do |s|
205205
s.write "lib/myrack.rb", "MYRACK = 'FAIL'"
206206
end
@@ -225,7 +225,7 @@
225225

226226
context "when a pinned gem has an indirect dependency in the pinned source" do
227227
before do
228-
build_repo gem_repo3 do
228+
build_repo3 do
229229
build_gem "depends_on_myrack", "1.0.1" do |s|
230230
s.add_dependency "myrack"
231231
end
@@ -287,7 +287,7 @@
287287
before do
288288
# In these tests, we need a working myrack gem in repo2 and not repo3
289289

290-
build_repo gem_repo3 do
290+
build_repo3 do
291291
build_gem "depends_on_myrack", "1.0.1" do |s|
292292
s.add_dependency "myrack"
293293
end
@@ -502,7 +502,7 @@
502502
before do
503503
build_repo2
504504

505-
build_repo gem_repo3 do
505+
build_repo3 do
506506
build_gem "private_gem_1", "1.0.0"
507507
build_gem "private_gem_2", "1.0.0"
508508
end
@@ -528,7 +528,7 @@
528528
before do
529529
build_repo2
530530

531-
build_repo gem_repo3 do
531+
build_repo3 do
532532
build_gem "depends_on_missing", "1.0.1" do |s|
533533
s.add_dependency "missing"
534534
end
@@ -565,7 +565,7 @@
565565
end
566566
end
567567

568-
build_repo gem_repo3 do
568+
build_repo3 do
569569
build_gem "unrelated_gem", "1.0.0"
570570
end
571571

@@ -645,7 +645,7 @@
645645

646646
context "when a scoped gem has a deeply nested indirect dependency" do
647647
before do
648-
build_repo gem_repo3 do
648+
build_repo3 do
649649
build_gem "depends_on_depends_on_myrack", "1.0.1" do |s|
650650
s.add_dependency "depends_on_myrack"
651651
end
@@ -764,7 +764,7 @@
764764
build_gem "zeitwerk", "2.4.2"
765765
end
766766

767-
build_repo gem_repo3 do
767+
build_repo3 do
768768
build_gem "sidekiq-pro", "5.2.1" do |s|
769769
s.add_dependency "connection_pool", ">= 2.2.3"
770770
s.add_dependency "sidekiq", ">= 6.1.0"
@@ -1080,7 +1080,7 @@
10801080

10811081
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do
10821082
before do
1083-
build_repo gem_repo3 do
1083+
build_repo3 do
10841084
build_gem "handsoap", "0.2.5.5" do |s|
10851085
s.add_dependency "nokogiri", ">= 1.2.3"
10861086
end
@@ -1157,7 +1157,7 @@
11571157

11581158
context "with a gem that is only found in the wrong source" do
11591159
before do
1160-
build_repo gem_repo3 do
1160+
build_repo3 do
11611161
build_gem "not_in_repo1", "1.0.0"
11621162
end
11631163

@@ -1250,7 +1250,7 @@
12501250
end
12511251

12521252
before do
1253-
build_repo gem_repo3 do
1253+
build_repo3 do
12541254
build_gem "myrack", "0.9.1"
12551255
end
12561256

@@ -1393,7 +1393,7 @@
13931393
context "re-resolving" do
13941394
context "when there is a mix of sources in the gemfile" do
13951395
before do
1396-
build_repo gem_repo3 do
1396+
build_repo3 do
13971397
build_gem "myrack"
13981398
end
13991399

@@ -1921,4 +1921,70 @@
19211921
expect(err).to include("Could not find gem 'example' in rubygems repository https://gem.repo4/")
19221922
end
19231923
end
1924+
1925+
context "when a gem has versions in two sources, but only the locked one has updates" do
1926+
let(:original_lockfile) do
1927+
<<~L
1928+
GEM
1929+
remote: https://main.source/
1930+
specs:
1931+
activesupport (1.0)
1932+
bigdecimal
1933+
bigdecimal (1.0.0)
1934+
1935+
GEM
1936+
remote: https://main.source/extra/
1937+
specs:
1938+
foo (1.0)
1939+
bigdecimal
1940+
1941+
PLATFORMS
1942+
#{lockfile_platforms}
1943+
1944+
DEPENDENCIES
1945+
activesupport
1946+
foo!
1947+
1948+
BUNDLED WITH
1949+
#{Bundler::VERSION}
1950+
L
1951+
end
1952+
1953+
before do
1954+
build_repo3 do
1955+
build_gem "activesupport" do |s|
1956+
s.add_dependency "bigdecimal"
1957+
end
1958+
1959+
build_gem "bigdecimal", "1.0.0"
1960+
build_gem "bigdecimal", "3.3.1"
1961+
end
1962+
1963+
build_repo4 do
1964+
build_gem "foo" do |s|
1965+
s.add_dependency "bigdecimal"
1966+
end
1967+
1968+
build_gem "bigdecimal", "1.0.0"
1969+
end
1970+
1971+
gemfile <<~G
1972+
source "https://main.source"
1973+
1974+
gem "activesupport"
1975+
1976+
source "https://main.source/extra" do
1977+
gem "foo"
1978+
end
1979+
G
1980+
1981+
lockfile original_lockfile
1982+
end
1983+
1984+
it "properly upgrades the lockfile when updating that specific gem" do
1985+
bundle "update bigdecimal --conservative", artifice: "compact_index_extra_api", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo3.to_s }
1986+
1987+
expect(lockfile).to eq original_lockfile.gsub("bigdecimal (1.0.0)", "bigdecimal (3.3.1)")
1988+
end
1989+
end
19241990
end

bundler/spec/install/prereleases_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
describe "when prerelease gems are not available" do
4040
it "still works" do
41-
build_repo gem_repo3 do
41+
build_repo3 do
4242
build_gem "myrack"
4343
end
4444
FileUtils.rm_rf Dir[gem_repo3("prerelease*")]

bundler/spec/other/major_deprecation_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@
454454

455455
context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do
456456
before do
457-
build_repo gem_repo3 do
457+
build_repo3 do
458458
build_gem "myrack", "0.9.1"
459459
end
460460

bundler/spec/support/builders.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,15 @@ def build_repo2(**kwargs, &blk)
188188

189189
# A repo that has no pre-installed gems included. (The caller completely
190190
# determines the contents with the block.)
191+
def build_repo3(**kwargs, &blk)
192+
build_empty_repo gem_repo3, **kwargs, &blk
193+
end
194+
195+
# Like build_repo3, this is a repo that has no pre-installed gems included.
196+
# We have two different methods for situations where two different empty
197+
# sources are needed.
191198
def build_repo4(**kwargs, &blk)
192-
FileUtils.rm_rf gem_repo4
193-
build_repo(gem_repo4, **kwargs, &blk)
199+
build_empty_repo gem_repo4, **kwargs, &blk
194200
end
195201

196202
def update_repo4(&blk)
@@ -307,6 +313,11 @@ def build_plugin(name, *args, &blk)
307313

308314
private
309315

316+
def build_empty_repo(gem_repo, **kwargs, &blk)
317+
FileUtils.rm_rf gem_repo
318+
build_repo(gem_repo, **kwargs, &blk)
319+
end
320+
310321
def build_with(builder, name, args, &blk)
311322
@_build_path ||= nil
312323
@_build_repo ||= nil

0 commit comments

Comments
 (0)