diff options
Diffstat (limited to 'lib/bundler/resolver/base.rb')
-rw-r--r-- | lib/bundler/resolver/base.rb | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/lib/bundler/resolver/base.rb b/lib/bundler/resolver/base.rb index 84e087b0ae..ad19eeb3f4 100644 --- a/lib/bundler/resolver/base.rb +++ b/lib/bundler/resolver/base.rb @@ -1,48 +1,105 @@ # 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 [](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 @base_requirements ||= build_base_requirements end - def unlock_deps(deps) - exact, lower_bound = deps.partition(&:specific?) + def unlock_names(names) + indirect_pins = indirect_pins(names) - exact.each do |exact_dep| - @base.delete_by_name_and_version(exact_dep.name, exact_dep.requirement.requirements.first.last) - end + if indirect_pins.any? + loosen_names(indirect_pins) + else + pins = pins(names) - lower_bound.each do |lower_bound_dep| - @additional_base_requirements.delete(lower_bound_dep) + 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 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| - dep = Dependency.new(ls.name, ls.version) - base_requirements[ls.name] = DepProxy.get_proxy(dep, ls.platform) + req = Gem::Requirement.new(ls.version) + base_requirements[ls.name] = req end - @additional_base_requirements.each {|d| base_requirements[d.name] = d } base_requirements end end |