Skip to content

Commit c6a28b0

Browse files
deivid-rodriguezhsbt
authored andcommitted
[rubygems/rubygems] Always resolve against the local platform
If RUBY is the only platform in the lockfile, we were skipping adding the local platform to the list of resolution platforms. This generally works anyways, because we had some code to still add it if the RUBY platform is not valid for the set of locked gems. However, sometimes it can happen that "RUBY" is valid for the current set of locked gems, but when adding a new dependency, it becomes invalid. For example, when adding sorbet to a Gemfile, that will introduce `sorbet-static` as an indirect dependency which does not have a generic "RUBY" variant. This will cause resolution to take a long time continuously backtracking trying to find solutions that don't introduce `sorbet-static` as a dependency and will eventually fail. Instead, we can always add the local platform to the set of resolution platforms before resolving, and remove it as necessary after resolution so that we lock the correct set of platforms. rubygems/rubygems@6ed1fe6050
1 parent 9e713f0 commit c6a28b0

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

lib/bundler/definition.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,11 @@ def start_resolution
624624
result = SpecSet.new(resolver.start)
625625

626626
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
627+
628+
if @current_ruby_locked_platform && @current_ruby_locked_platform != local_platform
629+
@platforms.delete(result.incomplete_for_platform?(dependencies, @current_ruby_locked_platform) ? @current_ruby_locked_platform : local_platform)
630+
end
631+
627632
@platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
628633

629634
result.complete_platforms!(platforms)
@@ -661,7 +666,7 @@ def current_platform_locked?
661666
end
662667

663668
def add_current_platform
664-
return if current_ruby_platform_locked?
669+
@current_ruby_locked_platform = most_specific_locked_platform if current_ruby_platform_locked?
665670

666671
add_platform(local_platform)
667672
end
@@ -1049,7 +1054,6 @@ def remove_invalid_platforms!(dependencies)
10491054
!@originally_locked_specs.incomplete_for_platform?(dependencies, platform)
10501055

10511056
remove_platform(platform)
1052-
add_current_platform if platform == Gem::Platform::RUBY
10531057
end
10541058
end
10551059

spec/bundler/install/gemfile/specific_platform_spec.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,60 @@
10661066
end
10671067
end
10681068

1069+
it "automatically fixes the lockfile when only RUBY platform locked, and adding a dependency with subdependencies not valid for RUBY" do
1070+
simulate_platform "x86_64-linux" do
1071+
build_repo4 do
1072+
build_gem("sorbet", "0.5.10160") do |s|
1073+
s.add_runtime_dependency "sorbet-static", "= 0.5.10160"
1074+
end
1075+
1076+
build_gem("sorbet-static", "0.5.10160") do |s|
1077+
s.platform = "x86_64-linux"
1078+
end
1079+
end
1080+
1081+
gemfile <<~G
1082+
source "#{file_uri_for(gem_repo4)}"
1083+
1084+
gem "sorbet"
1085+
G
1086+
1087+
lockfile <<~L
1088+
GEM
1089+
remote: #{file_uri_for(gem_repo4)}/
1090+
specs:
1091+
1092+
PLATFORMS
1093+
ruby
1094+
1095+
DEPENDENCIES
1096+
1097+
BUNDLED WITH
1098+
#{Bundler::VERSION}
1099+
L
1100+
1101+
bundle "lock"
1102+
1103+
expect(lockfile).to eq <<~L
1104+
GEM
1105+
remote: #{file_uri_for(gem_repo4)}/
1106+
specs:
1107+
sorbet (0.5.10160)
1108+
sorbet-static (= 0.5.10160)
1109+
sorbet-static (0.5.10160-x86_64-linux)
1110+
1111+
PLATFORMS
1112+
x86_64-linux
1113+
1114+
DEPENDENCIES
1115+
sorbet
1116+
1117+
BUNDLED WITH
1118+
#{Bundler::VERSION}
1119+
L
1120+
end
1121+
end
1122+
10691123
it "locks specific platforms automatically" do
10701124
simulate_platform "x86_64-linux" do
10711125
build_repo4 do

0 commit comments

Comments
 (0)