Skip to content

Commit

Permalink
[rubygems/rubygems] Don't remove platform specific variants from the …
Browse files Browse the repository at this point in the history
…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.

rubygems/rubygems@9a3e583b0c
  • Loading branch information
deivid-rodriguez authored and hsbt committed Jan 14, 2025
1 parent 3c900b9 commit e4d0531
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ def start_resolution

@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?
Expand Down
3 changes: 2 additions & 1 deletion lib/bundler/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def setup_solver
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

Expand Down
3 changes: 2 additions & 1 deletion lib/bundler/resolver/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
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

Expand Down
10 changes: 10 additions & 0 deletions lib/bundler/spec_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ def find_by_name_and_platform(name, platform)
@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 }

Expand Down Expand Up @@ -277,6 +281,12 @@ def all_platforms
@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
Expand Down
46 changes: 45 additions & 1 deletion spec/bundler/install/gemfile/specific_platform_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@
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
Expand Down Expand Up @@ -1167,13 +1167,15 @@

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)
GEM
remote: https://gem.repo4/
specs:
nokogiri (1.14.0)
nokogiri (1.14.0-x86_64-linux)
PLATFORMS
x86_64-linux
Expand Down Expand Up @@ -1699,6 +1701,48 @@
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
Expand Down

0 comments on commit e4d0531

Please sign in to comment.