diff options
| author | David RodrÃguez <deivid.rodriguez@riseup.net> | 2025-01-09 21:34:29 +0100 |
|---|---|---|
| committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2025-01-14 12:24:37 +0900 |
| commit | 0b1b8bc3ec08de6944e6784de1ea5e03e90d8dba (patch) | |
| tree | e80f982ef9fda23e3f5b2de553d6a65a4cb289f7 | |
| parent | 5c83d09ec874db44f6a69d8f81952f31a811013d (diff) | |
[rubygems/rubygems] Don't remove platform specific variants from the lockfile unless necessary
Even if they don't match the current Ruby version, they could still work
in other rubies. So it's better to keep them.
https://github.com/rubygems/rubygems/commit/9a3e583b0c
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12568
| -rw-r--r-- | lib/bundler/definition.rb | 2 | ||||
| -rw-r--r-- | lib/bundler/resolver.rb | 3 | ||||
| -rw-r--r-- | lib/bundler/resolver/base.rb | 3 | ||||
| -rw-r--r-- | lib/bundler/spec_set.rb | 10 | ||||
| -rw-r--r-- | spec/bundler/install/gemfile/specific_platform_spec.rb | 46 |
5 files changed, 60 insertions, 4 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index fd81fe2aa3..c31682ce4e 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -742,7 +742,7 @@ module Bundler @platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms? - SpecSet.new(result.for(dependencies, @platforms)) + SpecSet.new(result.for(dependencies, @platforms | [Gem::Platform::RUBY])) end def precompute_source_requirements_for_indirect_dependencies? diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 54e25a2adc..56a6c7ac67 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -80,7 +80,8 @@ module Bundler def solve_versions(root:, logger:) solver = PubGrub::VersionSolver.new(source: self, root: root, logger: logger) result = solver.solve - result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) } + resolved_specs = result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) } + SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs) rescue PubGrub::SolveFailure => e incompatibility = e.incompatibility diff --git a/lib/bundler/resolver/base.rb b/lib/bundler/resolver/base.rb index f7d15a3024..932a92ff41 100644 --- a/lib/bundler/resolver/base.rb +++ b/lib/bundler/resolver/base.rb @@ -5,10 +5,11 @@ require_relative "package" module Bundler class Resolver class Base - attr_reader :packages, :requirements, :source_requirements + attr_reader :packages, :requirements, :source_requirements, :locked_specs def initialize(source_requirements, dependencies, base, platforms, options) @source_requirements = source_requirements + @locked_specs = options[:locked_specs] @base = base diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 994c3d29d2..f0082d46d5 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -163,6 +163,10 @@ module Bundler @specs.detect {|spec| spec.name == name && spec.match_platform(platform) } end + def specs_with_additional_variants_from(other) + sorted | additional_variants_from(other) + end + def delete_by_name(name) @specs.reject! {|spec| spec.name == name } @@ -277,6 +281,12 @@ module Bundler @specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq end + def additional_variants_from(other) + other.select do |spec| + version_for(spec.name) == spec.version && valid_dependencies?(spec) + end + end + def valid_dependencies?(s) validate_deps(s) == :valid end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index dc9bbd1144..04495e2b72 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -1121,7 +1121,7 @@ RSpec.describe "bundle install with specific platforms" do bundle :install end - it "automatically fixes the lockfile if the specific platform is locked and we move to a newer ruby version for which a native package is not available" do + it "automatically adds the ruby variant to the lockfile if the specific platform is locked and we move to a newer ruby version for which a native package is not available" do # # Given an existing application using native gems (e.g., nokogiri) # And a lockfile generated with a stable ruby version @@ -1167,6 +1167,7 @@ RSpec.describe "bundle install with specific platforms" do checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.14.0" + c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux" end expect(lockfile).to eq(<<~L) @@ -1174,6 +1175,7 @@ RSpec.describe "bundle install with specific platforms" do remote: https://gem.repo4/ specs: nokogiri (1.14.0) + nokogiri (1.14.0-x86_64-linux) PLATFORMS x86_64-linux @@ -1699,6 +1701,48 @@ RSpec.describe "bundle install with specific platforms" do end end + it "does not remove platform specific gems from lockfile when using a ruby version that does not match their ruby requirements, since they may be useful in other rubies" do + build_repo4 do + build_gem("google-protobuf", "3.25.5") + build_gem("google-protobuf", "3.25.5") do |s| + s.required_ruby_version = "< #{current_ruby_minor}.dev" + s.platform = "x86_64-linux" + end + end + + gemfile <<~G + source "https://gem.repo4" + + gem "google-protobuf", "~> 3.0" + G + + original_lockfile = <<~L + GEM + remote: https://gem.repo4/ + specs: + google-protobuf (3.25.5) + google-protobuf (3.25.5-x86_64-linux) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + google-protobuf (~> 3.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile original_lockfile + + simulate_platform "x86_64-linux" do + bundle "lock --update" + end + + expect(lockfile).to eq(original_lockfile) + end + private def setup_multiplatform_gem |
