diff options
| author | Diego Steiner <diego.steiner@renuo.ch> | 2016-09-27 14:07:35 +0200 |
|---|---|---|
| committer | Diego Steiner <diego.steiner@renuo.ch> | 2016-09-27 14:07:35 +0200 |
| commit | f809209b0c13a48a6da75692483bb51cf3ac0342 (patch) | |
| tree | 37ca2dd297079ef5b91faefc423cd1b997d3991f /lib/bundler/resolver.rb | |
| parent | 14c1a12b711878c7d7d7f360cb70c9398496b018 (diff) | |
| parent | 121ada2a1842ebe9989f35567e2dd829ec06b7a1 (diff) | |
| download | bundler-f809209b0c13a48a6da75692483bb51cf3ac0342.tar.gz | |
Merge remote-tracking branch 'origin/master' into 4854-gemnotfound-error
Diffstat (limited to 'lib/bundler/resolver.rb')
| -rw-r--r-- | lib/bundler/resolver.rb | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 81537baf24..e636e1f815 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -66,48 +66,39 @@ module Bundler end end - ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze - class SpecGroup < Array include GemHelpers - attr_reader :activated, :required_by + attr_reader :activated def initialize(a) super - @required_by = [] - @activated = [] + @required_by = [] + @activated_platforms = [] @dependencies = nil - @specs = {} - - ALL.each do |p| - @specs[p] = reverse.find {|s| s.match_platform(p) } + @specs = Hash.new do |specs, platform| + specs[platform] = select_best_platform_match(self, platform) end end def initialize_copy(o) super - @required_by = o.required_by.dup - @activated = o.activated.dup + @activated_platforms = o.activated.dup end def to_specs - specs = {} - - @activated.each do |p| + @activated_platforms.map do |p| next unless s = @specs[p] - platform = generic(Gem::Platform.new(s.platform)) - next if specs[platform] - - lazy_spec = LazySpecification.new(name, version, platform, source) + lazy_spec = LazySpecification.new(name, version, s.platform, source) lazy_spec.dependencies.replace s.dependencies - specs[platform] = lazy_spec - end - specs.values + lazy_spec + end.compact end def activate_platform!(platform) - @activated << platform if !@activated.include?(platform) && for?(platform, nil) + return unless for?(platform) + return if @activated_platforms.include?(platform) + @activated_platforms << platform end def name @@ -122,17 +113,9 @@ module Bundler @source ||= first.source end - def for?(platform, ruby_version) + def for?(platform) spec = @specs[platform] - return false unless spec - - return true if ruby_version.nil? - # Only allow endpoint specifications since they won't hit the network to - # fetch the full gemspec when calling required_ruby_version - return true if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification) - return true if spec.required_ruby_version.nil? - - spec.required_ruby_version.satisfied_by?(ruby_version.to_gem_version_with_patchlevel) + !spec.nil? end def to_s @@ -140,7 +123,11 @@ module Bundler end def dependencies_for_activated_platforms - @activated.map {|p| __dependencies[p] }.flatten + dependencies = @activated_platforms.map {|p| __dependencies[p] } + metadata_dependencies = @activated_platforms.map do |platform| + metadata_dependencies(@specs[platform], platform) + end + dependencies.concat(metadata_dependencies).flatten end def platforms_for_dependency_named(dependency) @@ -150,18 +137,31 @@ module Bundler private def __dependencies - @dependencies ||= begin - dependencies = {} - ALL.each do |p| - next unless spec = @specs[p] - dependencies[p] = [] + @dependencies = Hash.new do |dependencies, platform| + dependencies[platform] = [] + if spec = @specs[platform] spec.dependencies.each do |dep| next if dep.type == :development - dependencies[p] << DepProxy.new(dep, p) + dependencies[platform] << DepProxy.new(dep, platform) end end - dependencies + dependencies[platform] + end + end + + def metadata_dependencies(spec, platform) + return [] unless spec + # Only allow endpoint specifications since they won't hit the network to + # fetch the full gemspec when calling required_ruby_version + return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification) + dependencies = [] + if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none? + dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform) end + if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none? + dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform) + end + dependencies end end @@ -175,29 +175,34 @@ module Bundler # ==== Returns # <GemBundle>,nil:: If the list of dependencies can be resolved, a # collection of gemspecs is returned. Otherwise, nil is returned. - def self.resolve(requirements, index, source_requirements = {}, base = [], ruby_version = nil, gem_version_promoter = GemVersionPromoter.new) + def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = []) base = SpecSet.new(base) unless base.is_a?(SpecSet) - resolver = new(index, source_requirements, base, ruby_version, gem_version_promoter) + resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements) result = resolver.start(requirements) SpecSet.new(result) end - def initialize(index, source_requirements, base, ruby_version, gem_version_promoter) + def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements) @index = index @source_requirements = source_requirements @base = base @resolver = Molinillo::Resolver.new(self, self) @search_for = {} @base_dg = Molinillo::DependencyGraph.new - @base.each {|ls| @base_dg.add_vertex(ls.name, Dependency.new(ls.name, ls.version), true) } - @ruby_version = ruby_version + @base.each do |ls| + dep = Dependency.new(ls.name, ls.version) + @base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true) + end + additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) } @gem_version_promoter = gem_version_promoter end def start(requirements) verify_gemfile_dependencies_are_found!(requirements) dg = @resolver.resolve(requirements, @base_dg) - dg.map(&:payload).map(&:to_specs).flatten + dg.map(&:payload). + reject {|sg| sg.name.end_with?("\0") }. + map(&:to_specs).flatten rescue Molinillo::VersionConflict => e raise VersionConflict.new(e.conflicts.keys.uniq, e.message) rescue Molinillo::CircularDependencyError => e @@ -278,7 +283,7 @@ module Bundler @gem_version_promoter.sort_versions(dependency, spec_groups) end end - search.select {|sg| sg.for?(platform, @ruby_version) }.each {|sg| sg.activate_platform!(platform) } + search.select {|sg| sg.for?(platform) }.each {|sg| sg.activate_platform!(platform) } end def index_for(dependency) @@ -302,7 +307,8 @@ module Bundler end def requirement_satisfied_by?(requirement, activated, spec) - requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec) + return false unless requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec) + spec.activate_platform!(requirement.__platform) || spec.for?(requirement.__platform) end def sort_dependencies(dependencies, activated, conflicts) |
