Skip to content

Commit

Permalink
Merge rubygems/bundler HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
hsbt committed Jul 26, 2022
1 parent b404a5f commit 9e6d07f
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 98 deletions.
3 changes: 2 additions & 1 deletion lib/bundler.rb
Expand Up @@ -53,6 +53,7 @@ module Bundler
autoload :GemHelpers, File.expand_path("bundler/gem_helpers", __dir__)
autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__)
autoload :Graph, File.expand_path("bundler/graph", __dir__)
autoload :IncompleteSpecification, File.expand_path("bundler/incomplete_specification", __dir__)
autoload :Index, File.expand_path("bundler/index", __dir__)
autoload :Injector, File.expand_path("bundler/injector", __dir__)
autoload :Installer, File.expand_path("bundler/installer", __dir__)
Expand Down Expand Up @@ -455,7 +456,7 @@ def unbundled_exec(*args)
end

def local_platform
return Gem::Platform::RUBY if settings[:force_ruby_platform]
return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY]
Gem::Platform.local
end

Expand Down
33 changes: 23 additions & 10 deletions lib/bundler/definition.rb
Expand Up @@ -138,13 +138,13 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti
@unlock[:gems] ||= @dependencies.map(&:name)
else
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
@unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
@unlock[:gems] = @locked_specs.for(eager_unlock, false, platforms).map(&:name)
end

@dependency_changes = converge_dependencies
@local_changes = converge_locals

@locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
@reresolve = nil

@requires = compute_requires
end
Expand Down Expand Up @@ -279,11 +279,8 @@ def resolve
end
end
else
last_resolve = converge_locked_specs
# Run a resolve against the locally available gems
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
@reresolve = reresolve
end
end

Expand Down Expand Up @@ -468,7 +465,7 @@ def most_specific_locked_platform
private :sources

def nothing_changed?
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes && !@locked_specs_incomplete_for_platform
!@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
end

def unlocking?
Expand All @@ -477,8 +474,14 @@ def unlocking?

private

def reresolve
last_resolve = converge_locked_specs
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
end

def filter_specs(specs, deps)
SpecSet.new(specs).for(expand_dependencies(deps, true), false, false)
SpecSet.new(specs).for(expand_dependencies(deps, true), false, platforms)
end

def materialize(dependencies)
Expand All @@ -502,6 +505,17 @@ def materialize(dependencies)
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
end

if @reresolve.nil?
incomplete_specs = specs.incomplete_specs

if incomplete_specs.any?
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
@unlock[:gems].concat(incomplete_specs.map(&:name))
@resolve = reresolve
specs = resolve.materialize(dependencies)
end
end

unless specs["bundler"].any?
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
specs["bundler"] = bundler
Expand Down Expand Up @@ -549,7 +563,6 @@ def change_reason
[@new_platform, "you added a new platform to your gemfile"],
[@path_changes, "the gemspecs for path gems changed"],
[@local_changes, "the gemspecs for git local gems changed"],
[@locked_specs_incomplete_for_platform, "the lockfile does not have all gems needed for the current platform"],
].select(&:first).map(&:last).join(", ")
end

Expand Down Expand Up @@ -725,7 +738,7 @@ def converge_specs(specs)
# if we won't need the source (according to the lockfile),
# don't error if the path/git source isn't available
next if specs.
for(requested_dependencies, false, true).
for(requested_dependencies, false).
none? {|locked_spec| locked_spec.source == s.source }

raise
Expand Down
5 changes: 1 addition & 4 deletions lib/bundler/dependency.rb
@@ -1,14 +1,11 @@
# frozen_string_literal: true

require "rubygems/dependency"
require_relative "force_platform"
require_relative "shared_helpers"
require_relative "rubygems_ext"

module Bundler
class Dependency < Gem::Dependency
include ForcePlatform

attr_reader :autorequire
attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref, :force_ruby_platform

Expand Down Expand Up @@ -112,7 +109,7 @@ def initialize(name, version, options = {}, &blk)
@env = options["env"]
@should_include = options.fetch("should_include", true)
@gemfile = options["gemfile"]
@force_ruby_platform = options.fetch("force_ruby_platform", default_force_ruby_platform)
@force_ruby_platform = options["force_ruby_platform"]

@autorequire = Array(options["require"] || []) if options.key?("require")
end
Expand Down
18 changes: 0 additions & 18 deletions lib/bundler/force_platform.rb

This file was deleted.

12 changes: 12 additions & 0 deletions lib/bundler/incomplete_specification.rb
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Bundler
class IncompleteSpecification
attr_reader :name, :platform

def initialize(name, platform)
@name = name
@platform = platform
end
end
end
33 changes: 16 additions & 17 deletions lib/bundler/lazy_specification.rb
@@ -1,16 +1,13 @@
# frozen_string_literal: true

require_relative "force_platform"
require_relative "match_platform"

module Bundler
class LazySpecification
include ForcePlatform
include MatchPlatform

attr_reader :name, :version, :dependencies, :platform
attr_writer :force_ruby_platform
attr_accessor :source, :remote
attr_accessor :source, :remote, :force_ruby_platform

def initialize(name, version, platform, source = nil)
@name = name
Expand All @@ -19,23 +16,16 @@ def initialize(name, version, platform, source = nil)
@platform = platform || Gem::Platform::RUBY
@source = source
@specification = nil
@force_ruby_platform = nil
end

def full_name
if platform == Gem::Platform::RUBY || platform.nil?
if platform == Gem::Platform::RUBY
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{platform}"
end
end

def force_ruby_platform
return @force_ruby_platform unless @force_ruby_platform.nil?

default_force_ruby_platform
end

def ==(other)
identifier == other.identifier
end
Expand Down Expand Up @@ -71,7 +61,7 @@ def satisfies?(dependency)
def to_lock
out = String.new

if platform == Gem::Platform::RUBY || platform.nil?
if platform == Gem::Platform::RUBY
out << " #{name} (#{version})\n"
else
out << " #{name} (#{version}-#{platform})\n"
Expand All @@ -85,7 +75,17 @@ def to_lock
out
end

def __materialize__
def materialize_for_installation
__materialize__(ruby_platform_materializes_to_ruby_platform? ? platform : Bundler.local_platform)
end

def materialize_for_resolution
return self unless Gem::Platform.match_spec?(self)

__materialize__(platform)
end

def __materialize__(platform)
@specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
source.gemspec.tap {|s| s.source = source }
else
Expand All @@ -94,10 +94,9 @@ def __materialize__
else
ruby_platform_materializes_to_ruby_platform? ? self : Dependency.new(name, version)
end
platform_object = ruby_platform_materializes_to_ruby_platform? ? Gem::Platform.new(platform) : Gem::Platform.local
candidates = source.specs.search(search_object)
same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object)
MatchPlatform.platforms_match?(spec.platform, platform)
end
installable_candidates = same_platform_candidates.select do |spec|
spec.is_a?(StubSpecification) ||
Expand All @@ -115,7 +114,7 @@ def respond_to?(*args)
end

def to_s
@__to_s ||= if platform == Gem::Platform::RUBY || platform.nil?
@__to_s ||= if platform == Gem::Platform::RUBY
"#{name} (#{version})"
else
"#{name} (#{version}-#{platform})"
Expand Down
9 changes: 5 additions & 4 deletions lib/bundler/remote_specification.rb
Expand Up @@ -16,7 +16,8 @@ class RemoteSpecification
def initialize(name, version, platform, spec_fetcher)
@name = name
@version = Gem::Version.create version
@platform = platform
@original_platform = platform || Gem::Platform::RUBY
@platform = Gem::Platform.new(platform)
@spec_fetcher = spec_fetcher
@dependencies = nil
end
Expand All @@ -35,10 +36,10 @@ def required_rubygems_version
end

def full_name
if platform == Gem::Platform::RUBY || platform.nil?
if @original_platform == Gem::Platform::RUBY
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{platform}"
"#{@name}-#{@version}-#{@original_platform}"
end
end

Expand Down Expand Up @@ -105,7 +106,7 @@ def to_ary
end

def _remote_specification
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @original_platform])
@_remote_specification || raise(GemspecError, "Gemspec data for #{full_name} was" \
" missing from the server! Try installing with `--full-index` as a workaround.")
end
Expand Down
5 changes: 2 additions & 3 deletions lib/bundler/resolver.rb
Expand Up @@ -22,17 +22,16 @@ def self.resolve(requirements, source_requirements = {}, base = [], gem_version_
metadata_requirements, regular_requirements = requirements.partition {|dep| dep.name.end_with?("\0") }
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
result = resolver.start(requirements)
SpecSet.new(SpecSet.new(result).for(regular_requirements))
SpecSet.new(SpecSet.new(result).for(regular_requirements, false, platforms))
end

def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms, metadata_requirements)
@source_requirements = source_requirements
@metadata_requirements = metadata_requirements
@base = base
@resolver = Molinillo::Resolver.new(self, self)
@search_for = {}
@base_dg = Molinillo::DependencyGraph.new
@base.each do |ls|
@base = base.materialized_for_resolution do |ls|
dep = Dependency.new(ls.name, ls.version)
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
end
Expand Down
22 changes: 20 additions & 2 deletions lib/bundler/rubygems_ext.rb
Expand Up @@ -222,9 +222,27 @@ class Platform
MINGW = Gem::Platform.new("x86-mingw32")
X64_MINGW = [Gem::Platform.new("x64-mingw32"),
Gem::Platform.new("x64-mingw-ucrt")].freeze
end

Platform.singleton_class.module_eval do
unless Platform.singleton_methods.include?(:match_spec?)
def match_spec?(spec)
match_gem?(spec.platform, spec.name)
end

def match_gem?(platform, gem_name)
match_platforms?(platform, Gem.platforms)
end

private

if RUBY_ENGINE == "truffleruby" && !defined?(REUSE_AS_BINARY_ON_TRUFFLERUBY)
REUSE_AS_BINARY_ON_TRUFFLERUBY = %w[libv8 sorbet-static].freeze
def match_platforms?(platform, platforms)
platforms.any? do |local_platform|
platform.nil? ||
local_platform == platform ||
(local_platform != Gem::Platform::RUBY && local_platform =~ platform)
end
end
end
end

Expand Down

0 comments on commit 9e6d07f

Please sign in to comment.