diff options
Diffstat (limited to 'lib/rubygems/resolver')
35 files changed, 137 insertions, 55 deletions
diff --git a/lib/rubygems/resolver/activation_request.rb b/lib/rubygems/resolver/activation_request.rb index 2dd540cda0..135d75d6bc 100644 --- a/lib/rubygems/resolver/activation_request.rb +++ b/lib/rubygems/resolver/activation_request.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Specifies a Specification object that should be activated. Also contains a # dependency that was used to introduce this activation. @@ -50,15 +50,27 @@ class Gem::Resolver::ActivationRequest # Downloads a gem at +path+ and returns the file path. def download path - if @spec.respond_to? :source + Gem.ensure_gem_subdirectories path + + if @spec.respond_to? :sources + exception = nil + path = @spec.sources.find{ |source| + begin + source.download full_spec, path + rescue exception + end + } + return path if path + raise exception if exception + + elsif @spec.respond_to? :source source = @spec.source + source.download full_spec, path + else source = Gem.sources.first + source.download full_spec, path end - - Gem.ensure_gem_subdirectories path - - source.download full_spec, path end ## diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb index 611c74ad10..ee3046af63 100644 --- a/lib/rubygems/resolver/api_set.rb +++ b/lib/rubygems/resolver/api_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The global rubygems pool, available via the rubygems.org API. # Returns instances of APISpecification. diff --git a/lib/rubygems/resolver/api_specification.rb b/lib/rubygems/resolver/api_specification.rb index e7ba38d614..1e22dd0b6f 100644 --- a/lib/rubygems/resolver/api_specification.rb +++ b/lib/rubygems/resolver/api_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Represents a specification retrieved via the rubygems.org API. # diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb index c3c756c5e3..4479535abe 100644 --- a/lib/rubygems/resolver/best_set.rb +++ b/lib/rubygems/resolver/best_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The BestSet chooses the best available method to query a remote index. # diff --git a/lib/rubygems/resolver/composed_set.rb b/lib/rubygems/resolver/composed_set.rb index 66d927be2a..0b65942dca 100644 --- a/lib/rubygems/resolver/composed_set.rb +++ b/lib/rubygems/resolver/composed_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A ComposedSet allows multiple sets to be queried like a single set. # diff --git a/lib/rubygems/resolver/conflict.rb b/lib/rubygems/resolver/conflict.rb index 101923eb74..7997f92950 100644 --- a/lib/rubygems/resolver/conflict.rb +++ b/lib/rubygems/resolver/conflict.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Used internally to indicate that a dependency conflicted # with a spec that would be activated. diff --git a/lib/rubygems/resolver/current_set.rb b/lib/rubygems/resolver/current_set.rb index f8cec599de..265c639f15 100644 --- a/lib/rubygems/resolver/current_set.rb +++ b/lib/rubygems/resolver/current_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A set which represents the installed gems. Respects # all the normal settings that control where to look diff --git a/lib/rubygems/resolver/dependency_request.rb b/lib/rubygems/resolver/dependency_request.rb index ded554a85a..c2918911cd 100644 --- a/lib/rubygems/resolver/dependency_request.rb +++ b/lib/rubygems/resolver/dependency_request.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Used Internally. Wraps a Dependency object to also track which spec # contained the Dependency. diff --git a/lib/rubygems/resolver/git_set.rb b/lib/rubygems/resolver/git_set.rb index 2b5aae64c6..723a202d7a 100644 --- a/lib/rubygems/resolver/git_set.rb +++ b/lib/rubygems/resolver/git_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A GitSet represents gems that are sourced from git repositories. # diff --git a/lib/rubygems/resolver/git_specification.rb b/lib/rubygems/resolver/git_specification.rb index 507f346812..2448797d3f 100644 --- a/lib/rubygems/resolver/git_specification.rb +++ b/lib/rubygems/resolver/git_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A GitSpecification represents a gem that is sourced from a git repository # and is being loaded through a gem dependencies file through the +git:+ diff --git a/lib/rubygems/resolver/index_set.rb b/lib/rubygems/resolver/index_set.rb index e7cd989095..2450f14b4f 100644 --- a/lib/rubygems/resolver/index_set.rb +++ b/lib/rubygems/resolver/index_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The global rubygems pool represented via the traditional # source index. diff --git a/lib/rubygems/resolver/index_specification.rb b/lib/rubygems/resolver/index_specification.rb index 632a8a2d89..4340f46943 100644 --- a/lib/rubygems/resolver/index_specification.rb +++ b/lib/rubygems/resolver/index_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Represents a possible Specification object returned from IndexSet. Used to # delay needed to download full Specification objects when only the +name+ diff --git a/lib/rubygems/resolver/installed_specification.rb b/lib/rubygems/resolver/installed_specification.rb index 06da6af3db..d9c6a5e5cf 100644 --- a/lib/rubygems/resolver/installed_specification.rb +++ b/lib/rubygems/resolver/installed_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # An InstalledSpecification represents a gem that is already installed # locally. diff --git a/lib/rubygems/resolver/installer_set.rb b/lib/rubygems/resolver/installer_set.rb index d840b71711..1ed02e6f9f 100644 --- a/lib/rubygems/resolver/installer_set.rb +++ b/lib/rubygems/resolver/installer_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A set of gems for installation sourced from remote sources and local .gem # files diff --git a/lib/rubygems/resolver/local_specification.rb b/lib/rubygems/resolver/local_specification.rb index 76192e4c0b..1d9d22f0ac 100644 --- a/lib/rubygems/resolver/local_specification.rb +++ b/lib/rubygems/resolver/local_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A LocalSpecification comes from a .gem file on the local filesystem. diff --git a/lib/rubygems/resolver/lock_set.rb b/lib/rubygems/resolver/lock_set.rb index fb581a1508..7fddc93e1c 100644 --- a/lib/rubygems/resolver/lock_set.rb +++ b/lib/rubygems/resolver/lock_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A set of gems from a gem dependencies lockfile. @@ -28,11 +28,9 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set def add name, version, platform # :nodoc: version = Gem::Version.new version - - specs = @sources.map do |source| - Gem::Resolver::LockSpecification.new self, name, version, source, - platform - end + specs = [ + Gem::Resolver::LockSpecification.new(self, name, version, @sources, platform) + ] @specs.concat specs diff --git a/lib/rubygems/resolver/lock_specification.rb b/lib/rubygems/resolver/lock_specification.rb index 0226878752..f485675673 100644 --- a/lib/rubygems/resolver/lock_specification.rb +++ b/lib/rubygems/resolver/lock_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The LockSpecification comes from a lockfile (Gem::RequestSet::Lockfile). # @@ -7,13 +7,16 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification - def initialize set, name, version, source, platform + attr_reader :sources + + def initialize set, name, version, sources, platform super() @name = name @platform = platform @set = set - @source = source + @source = sources.first + @sources = sources @version = version @dependencies = [] diff --git a/lib/rubygems/resolver/molinillo.rb b/lib/rubygems/resolver/molinillo.rb index 019536dc9b..2357f41bee 100644 --- a/lib/rubygems/resolver/molinillo.rb +++ b/lib/rubygems/resolver/molinillo.rb @@ -1,2 +1,2 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'rubygems/resolver/molinillo/lib/molinillo' diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo.rb b/lib/rubygems/resolver/molinillo/lib/molinillo.rb index 34dc7787dc..0ae4b6a912 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo.rb @@ -1,6 +1,10 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'rubygems/resolver/molinillo/lib/molinillo/gem_metadata' require 'rubygems/resolver/molinillo/lib/molinillo/errors' require 'rubygems/resolver/molinillo/lib/molinillo/resolver' require 'rubygems/resolver/molinillo/lib/molinillo/modules/ui' require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider' + +# Gem::Resolver::Molinillo is a generic dependency resolution algorithm. +module Gem::Resolver::Molinillo +end diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb index c3a1d5a2ef..deb4659448 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'set' require 'tsort' @@ -15,8 +15,10 @@ module Gem::Resolver::Molinillo include TSort + # @visibility private alias_method :tsort_each_node, :each + # @visibility private def tsort_each_child(vertex, &block) vertex.successors.each(&block) end @@ -42,12 +44,14 @@ module Gem::Resolver::Molinillo # by {Vertex#name} attr_reader :vertices + # Initializes an empty dependency graph def initialize @vertices = {} end # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices} # are properly copied. + # @param [DependencyGraph] other the graph to copy. def initialize_copy(other) super @vertices = {} @@ -101,6 +105,7 @@ module Gem::Resolver::Molinillo vertex end + # Adds a vertex with the given name, or updates the existing one. # @param [String] name # @param [Object] payload # @return [Vertex] the vertex that was added to `self` @@ -151,6 +156,8 @@ module Gem::Resolver::Molinillo private + # Adds a new {Edge} to the dependency graph without checking for + # circularity. def add_edge_no_circular(origin, destination, requirement) edge = Edge.new(origin, destination, requirement) origin.outgoing_edges << edge @@ -175,6 +182,7 @@ module Gem::Resolver::Molinillo attr_accessor :root alias_method :root?, :root + # Initializes a vertex with the given name and payload. # @param [String] name see {#name} # @param [Object] payload see {#payload} def initialize(name, payload) @@ -241,6 +249,7 @@ module Gem::Resolver::Molinillo successors.to_set == other.successors.to_set end + # @param [Vertex] other the other vertex to compare to # @return [Boolean] whether the two vertices are equal, determined # solely by {#name} and {#payload} equality def shallow_eql?(other) diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb index 074ee9dd7d..3fad948392 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo # An error that occurred during the resolution process class ResolverError < StandardError; end @@ -12,6 +12,7 @@ module Gem::Resolver::Molinillo # @return [Array<Object>] the specifications that depended upon {#dependency} attr_accessor :required_by + # Initializes a new error with the given missing dependency. # @param [Object] dependency @see {#dependency} # @param [Array<Object>] required_by @see {#required_by} def initialize(dependency, required_by = []) @@ -20,6 +21,8 @@ module Gem::Resolver::Molinillo super() end + # The error message for the missing dependency, including the specifications + # that had this dependency. def message sources = required_by.map { |r| "`#{r}`" }.join(' and ') message = "Unable to find a specification for `#{dependency}`" @@ -37,6 +40,7 @@ module Gem::Resolver::Molinillo # [Set<Object>] the dependencies responsible for causing the error attr_reader :dependencies + # Initializes a new error with the given circular vertices. # @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency # that caused the error def initialize(nodes) @@ -51,6 +55,7 @@ module Gem::Resolver::Molinillo # resolution to fail attr_reader :conflicts + # Initializes a new error with the given version conflicts. # @param [{String => Resolution::Conflict}] conflicts see {#conflicts} def initialize(conflicts) pairs = [] diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb index 8140c57a58..79cae2c697 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb @@ -1,4 +1,5 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo - VERSION = '0.4.0' + # The version of Gem::Resolver::Molinillo. + VERSION = '0.4.1'.freeze end diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb index 10c655ac32..916345b12a 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo # Provides information about specifcations and dependencies to the resolver, # allowing the {Resolver} class to remain generic while still providing power diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb index 100b694ebc..348ace286a 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo # Conveys information about the resolution process to a user. module UI diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb index 5a0eb36849..0f822f0b82 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo class Resolver # A specific resolution from a given {Resolver} @@ -39,6 +39,7 @@ module Gem::Resolver::Molinillo # @return [Array] the dependencies that were explicitly required attr_reader :original_requested + # Initializes a new resolution. # @param [SpecificationProvider] specification_provider # see {#specification_provider} # @param [UI] resolver_ui see {#resolver_ui} diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb index a92b3273ab..5c59a45c3d 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb @@ -1,10 +1,10 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph' module Gem::Resolver::Molinillo # This class encapsulates a dependency resolver. # The resolver is responsible for determining which set of dependencies to - # activate, with feedback from the the {#specification_provider} + # activate, with feedback from the {#specification_provider} # # class Resolver @@ -18,6 +18,7 @@ module Gem::Resolver::Molinillo # during the resolution process attr_reader :resolver_ui + # Initializes a new resolver. # @param [SpecificationProvider] specification_provider # see {#specification_provider} # @param [UI] resolver_ui diff --git a/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb index 7bc9d98927..ac25538a5a 100644 --- a/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb +++ b/lib/rubygems/resolver/molinillo/lib/molinillo/state.rb @@ -1,13 +1,13 @@ -# frozen_string_literal: false +# frozen_string_literal: true module Gem::Resolver::Molinillo # A state that a {Resolution} can be in - # @attr [String] name - # @attr [Array<Object>] requirements - # @attr [DependencyGraph] activated - # @attr [Object] requirement - # @attr [Object] possibility - # @attr [Integer] depth - # @attr [Set<Object>] conflicts + # @attr [String] name the name of the current requirement + # @attr [Array<Object>] requirements currently unsatisfied requirements + # @attr [DependencyGraph] activated the graph of activated dependencies + # @attr [Object] requirement the current requirement + # @attr [Object] possibilities the possibilities to satisfy the current requirement + # @attr [Integer] depth the depth of the resolution + # @attr [Set<Object>] conflicts unresolved conflicts ResolutionState = Struct.new( :name, :requirements, diff --git a/lib/rubygems/resolver/requirement_list.rb b/lib/rubygems/resolver/requirement_list.rb index 32f2ac5a99..2768c80170 100644 --- a/lib/rubygems/resolver/requirement_list.rb +++ b/lib/rubygems/resolver/requirement_list.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The RequirementList is used to hold the requirements being considered # while resolving a set of gems. diff --git a/lib/rubygems/resolver/set.rb b/lib/rubygems/resolver/set.rb index e2253abf3a..cc12633d46 100644 --- a/lib/rubygems/resolver/set.rb +++ b/lib/rubygems/resolver/set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # Resolver sets are used to look up specifications (and their # dependencies) used in resolution. This set is abstract. diff --git a/lib/rubygems/resolver/source_set.rb b/lib/rubygems/resolver/source_set.rb new file mode 100644 index 0000000000..66f5963e54 --- /dev/null +++ b/lib/rubygems/resolver/source_set.rb @@ -0,0 +1,48 @@ +## +# The SourceSet chooses the best available method to query a remote index. +# +# Kind off like BestSet but filters the sources for gems + +class Gem::Resolver::SourceSet < Gem::Resolver::Set + + ## + # Creates a SourceSet for the given +sources+ or Gem::sources if none are + # specified. +sources+ must be a Gem::SourceList. + + def initialize + super() + + @links = {} + @sets = {} + end + + def find_all req # :nodoc: + if set = get_set(req.dependency.name) + set.find_all req + else + [] + end + end + + # potentially no-op + def prefetch reqs # :nodoc: + reqs.each do |req| + if set = get_set(req.dependency.name) + set.prefetch reqs + end + end + end + + def add_source_gem name, source + @links[name] = source + end + +private + + def get_set(name) + link = @links[name] + @sets[link] ||= Gem::Source.new(link).dependency_resolver_set if link + end + +end + diff --git a/lib/rubygems/resolver/spec_specification.rb b/lib/rubygems/resolver/spec_specification.rb index 00a0533bb5..35ee8cc247 100644 --- a/lib/rubygems/resolver/spec_specification.rb +++ b/lib/rubygems/resolver/spec_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # The Resolver::SpecSpecification contains common functionality for # Resolver specifications that are backed by a Gem::Specification. diff --git a/lib/rubygems/resolver/specification.rb b/lib/rubygems/resolver/specification.rb index 5833320660..44989d39ae 100644 --- a/lib/rubygems/resolver/specification.rb +++ b/lib/rubygems/resolver/specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A Resolver::Specification contains a subset of the information # contained in a Gem::Specification. Only the information necessary for diff --git a/lib/rubygems/resolver/stats.rb b/lib/rubygems/resolver/stats.rb index 4de766f2e1..3b95efebf7 100644 --- a/lib/rubygems/resolver/stats.rb +++ b/lib/rubygems/resolver/stats.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true class Gem::Resolver::Stats def initialize @max_depth = 0 diff --git a/lib/rubygems/resolver/vendor_set.rb b/lib/rubygems/resolver/vendor_set.rb index a006220ffe..f30ce534af 100644 --- a/lib/rubygems/resolver/vendor_set.rb +++ b/lib/rubygems/resolver/vendor_set.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A VendorSet represents gems that have been unpacked into a specific # directory that contains a gemspec. diff --git a/lib/rubygems/resolver/vendor_specification.rb b/lib/rubygems/resolver/vendor_specification.rb index ecf8e74def..c624f3e834 100644 --- a/lib/rubygems/resolver/vendor_specification.rb +++ b/lib/rubygems/resolver/vendor_specification.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true ## # A VendorSpecification represents a gem that has been unpacked into a project # and is being loaded through a gem dependencies file through the +path:+ |