ruby/lib/bundler/materialization.rb
David Rodríguez a65c7c8428 [rubygems/rubygems] Fix parallel installation issue
If using a gem with precompiled versions having different dependencies
than the generic version from a path source, and with a lockfile
including a precompiled version, we would materialize the
generic version, but end up using dependencies for the precompiled
version. That will result in the parallel installer missing the
specifications for the extra dependencies of the generic version,
causing a crash.

If we are materializing for installation, make sure we use the
materialized specification when traversing dependencies.

https://github.com/rubygems/rubygems/commit/5f75d75de7
2025-09-19 19:30:10 +09:00

60 lines
1.4 KiB
Ruby

# frozen_string_literal: true
module Bundler
#
# This class materializes a set of resolved specifications (`LazySpecification`)
# for a given gem into the most appropriate real specifications
# (`StubSepecification`, `EndpointSpecification`, etc), given a dependency and a
# target platform.
#
class Materialization
def initialize(dep, platform, candidates:)
@dep = dep
@platform = platform
@candidates = candidates
end
def complete?
specs.any?
end
def specs
@specs ||= if @candidates.nil?
[]
elsif platform
MatchPlatform.select_best_platform_match(@candidates, platform, force_ruby: dep.force_ruby_platform)
else
MatchPlatform.select_best_local_platform_match(@candidates, force_ruby: dep.force_ruby_platform || dep.default_force_ruby_platform)
end
end
def dependencies
(materialized_spec || specs.first).runtime_dependencies.map {|d| [d, platform] }
end
def materialized_spec
specs.reject(&:missing?).first&.materialization
end
def completely_missing_specs
return [] unless specs.all?(&:missing?)
specs
end
def partially_missing_specs
specs.select(&:missing?)
end
def incomplete_specs
return [] if complete?
@candidates || LazySpecification.new(dep.name, nil, nil)
end
private
attr_reader :dep, :platform
end
end