diff options
Diffstat (limited to 'lib/bundler/resolver/base.rb')
-rw-r--r-- | lib/bundler/resolver/base.rb | 89 |
1 files changed, 80 insertions, 9 deletions
diff --git a/lib/bundler/resolver/base.rb b/lib/bundler/resolver/base.rb index 78b798f4ec..3f2436672a 100644 --- a/lib/bundler/resolver/base.rb +++ b/lib/bundler/resolver/base.rb @@ -1,19 +1,49 @@ # frozen_string_literal: true +require_relative "package" + module Bundler class Resolver class Base - def initialize(base, additional_base_requirements) + attr_reader :packages, :requirements, :source_requirements + + def initialize(source_requirements, dependencies, base, platforms, options) + @source_requirements = source_requirements + @base = base - @additional_base_requirements = additional_base_requirements + + @packages = Hash.new do |hash, name| + hash[name] = Package.new(name, platforms, **options) + end + + @requirements = dependencies.map do |dep| + dep_platforms = dep.gem_platforms(platforms) + + # Dependencies scoped to external platforms are ignored + next if dep_platforms.empty? + + name = dep.name + + @packages[name] = Package.new(name, dep_platforms, **options.merge(dependency: dep)) + + dep + end.compact + end + + def specs_compatible_with(result) + @base.specs_compatible_with(result) end def [](name) @base[name] end - def delete(spec) - @base.delete(spec) + def delete(specs) + @base.delete(specs) + end + + def get_package(name) + @packages[name] end def base_requirements @@ -21,24 +51,65 @@ module Bundler end def unlock_names(names) - names.each do |name| - @base.delete_by_name(name) + indirect_pins = indirect_pins(names) + + if indirect_pins.any? + loosen_names(indirect_pins) + else + pins = pins(names) - @additional_base_requirements.reject! {|dep| dep.name == name } + if pins.any? + loosen_names(pins) + else + unrestrict_names(names) + end end + end - @base_requirements = nil + def include_prereleases(names) + names.each do |name| + get_package(name).consider_prereleases! + end + end + + def include_remote_specs(names) + names.each do |name| + get_package(name).consider_remote_versions! + end end private + def indirect_pins(names) + names.select {|name| @base_requirements[name].exact? && @requirements.none? {|dep| dep.name == name } } + end + + def pins(names) + names.select {|name| @base_requirements[name].exact? } + end + + def loosen_names(names) + names.each do |name| + version = @base_requirements[name].requirements.first[1] + + @base_requirements[name] = Gem::Requirement.new(">= #{version}") + + @base.delete_by_name(name) + end + end + + def unrestrict_names(names) + names.each do |name| + @base_requirements.delete(name) + end + end + def build_base_requirements base_requirements = {} @base.each do |ls| req = Gem::Requirement.new(ls.version) base_requirements[ls.name] = req end - @additional_base_requirements.each {|d| base_requirements[d.name] = d.requirement } base_requirements end end |