mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rubygems: Update to RubyGems 2.5.0+ HEAD(c6b4946).
this version includes #1114, #1314, #1322, #1375, #1383, #1387 * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52666 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9c065a4bfb
commit
5f6715275e
11 changed files with 211 additions and 90 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Thu Nov 19 15:16:12 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
|
||||||
|
|
||||||
|
* lib/rubygems: Update to RubyGems 2.5.0+ HEAD(c6b4946).
|
||||||
|
this version includes #1114, #1314, #1322, #1375, #1383, #1387
|
||||||
|
* test/rubygems: ditto.
|
||||||
|
|
||||||
Thu Nov 19 14:14:37 2015 NAKAMURA Usaku <usa@ruby-lang.org>
|
Thu Nov 19 14:14:37 2015 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (finish_overlapped_socket): return value of this
|
* win32/win32.c (finish_overlapped_socket): return value of this
|
||||||
|
|
|
@ -171,8 +171,8 @@ class Gem::BasicSpecification
|
||||||
begin
|
begin
|
||||||
fullpath = nil
|
fullpath = nil
|
||||||
suffixes = Gem.suffixes
|
suffixes = Gem.suffixes
|
||||||
full_require_paths.find do |dir|
|
suffixes.find do |suf|
|
||||||
suffixes.find do |suf|
|
full_require_paths.find do |dir|
|
||||||
File.file?(fullpath = "#{dir}/#{path}#{suf}")
|
File.file?(fullpath = "#{dir}/#{path}#{suf}")
|
||||||
end
|
end
|
||||||
end ? fullpath : nil
|
end ? fullpath : nil
|
||||||
|
|
|
@ -185,6 +185,10 @@ class Gem::Request
|
||||||
|
|
||||||
bad_response = true
|
bad_response = true
|
||||||
retry
|
retry
|
||||||
|
rescue Net::HTTPFatalError
|
||||||
|
verbose "fatal error"
|
||||||
|
|
||||||
|
raise Gem::RemoteFetcher::FetchError.new('fatal error', @uri)
|
||||||
# HACK work around EOFError bug in Net::HTTP
|
# HACK work around EOFError bug in Net::HTTP
|
||||||
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
||||||
# to install gems.
|
# to install gems.
|
||||||
|
@ -241,4 +245,3 @@ end
|
||||||
require 'rubygems/request/http_pool'
|
require 'rubygems/request/http_pool'
|
||||||
require 'rubygems/request/https_pool'
|
require 'rubygems/request/https_pool'
|
||||||
require 'rubygems/request/connection_pools'
|
require 'rubygems/request/connection_pools'
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ class Gem::Resolver
|
||||||
|
|
||||||
def resolve
|
def resolve
|
||||||
locking_dg = Molinillo::DependencyGraph.new
|
locking_dg = Molinillo::DependencyGraph.new
|
||||||
Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload)
|
Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact
|
||||||
rescue Molinillo::VersionConflict => e
|
rescue Molinillo::VersionConflict => e
|
||||||
conflict = e.conflicts.values.first
|
conflict = e.conflicts.values.first
|
||||||
raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
|
raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
|
||||||
|
|
|
@ -34,40 +34,34 @@ module Gem::Resolver::Molinillo
|
||||||
# A directed edge of a {DependencyGraph}
|
# A directed edge of a {DependencyGraph}
|
||||||
# @attr [Vertex] origin The origin of the directed edge
|
# @attr [Vertex] origin The origin of the directed edge
|
||||||
# @attr [Vertex] destination The destination of the directed edge
|
# @attr [Vertex] destination The destination of the directed edge
|
||||||
# @attr [Array] requirements The requirements the directed edge represents
|
# @attr [Object] requirement The requirement the directed edge represents
|
||||||
Edge = Struct.new(:origin, :destination, :requirements)
|
Edge = Struct.new(:origin, :destination, :requirement)
|
||||||
|
|
||||||
# @return [{String => Vertex}] vertices that have no {Vertex#predecessors},
|
|
||||||
# keyed by by {Vertex#name}
|
|
||||||
attr_reader :root_vertices
|
|
||||||
# @return [{String => Vertex}] the vertices of the dependency graph, keyed
|
# @return [{String => Vertex}] the vertices of the dependency graph, keyed
|
||||||
# by {Vertex#name}
|
# by {Vertex#name}
|
||||||
attr_reader :vertices
|
attr_reader :vertices
|
||||||
# @return [Set<Edge>] the edges of the dependency graph
|
|
||||||
attr_reader :edges
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@vertices = {}
|
@vertices = {}
|
||||||
@edges = Set.new
|
|
||||||
@root_vertices = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
|
# Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
|
||||||
# have the correct {Vertex#graph} set
|
# are properly copied.
|
||||||
def initialize_copy(other)
|
def initialize_copy(other)
|
||||||
super
|
super
|
||||||
@vertices = other.vertices.reduce({}) do |vertices, (name, vertex)|
|
@vertices = {}
|
||||||
vertices.tap do |hash|
|
traverse = lambda do |new_v, old_v|
|
||||||
hash[name] = vertex.dup.tap { |v| v.graph = self }
|
return if new_v.outgoing_edges.size == old_v.outgoing_edges.size
|
||||||
|
old_v.outgoing_edges.each do |edge|
|
||||||
|
destination = add_vertex(edge.destination.name, edge.destination.payload)
|
||||||
|
add_edge_no_circular(new_v, destination, edge.requirement)
|
||||||
|
traverse.call(destination, edge.destination)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@root_vertices = Hash[@vertices.select { |n, _v| other.root_vertices[n] }]
|
other.vertices.each do |name, vertex|
|
||||||
@edges = other.edges.map do |edge|
|
new_vertex = add_vertex(name, vertex.payload, vertex.root?)
|
||||||
Edge.new(
|
new_vertex.explicit_requirements.replace(vertex.explicit_requirements)
|
||||||
vertex_named(edge.origin.name),
|
traverse.call(new_vertex, vertex)
|
||||||
vertex_named(edge.destination.name),
|
|
||||||
edge.requirements.dup
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -80,7 +74,12 @@ module Gem::Resolver::Molinillo
|
||||||
# by a recursive traversal of each {#root_vertices} and its
|
# by a recursive traversal of each {#root_vertices} and its
|
||||||
# {Vertex#successors}
|
# {Vertex#successors}
|
||||||
def ==(other)
|
def ==(other)
|
||||||
root_vertices == other.root_vertices
|
return false unless other
|
||||||
|
vertices.each do |name, vertex|
|
||||||
|
other_vertex = other.vertex_named(name)
|
||||||
|
return false unless other_vertex
|
||||||
|
return false unless other_vertex.successors.map(&:name).to_set == vertex.successors.map(&:name).to_set
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [String] name
|
# @param [String] name
|
||||||
|
@ -89,15 +88,13 @@ module Gem::Resolver::Molinillo
|
||||||
# @param [Object] requirement the requirement that is requiring the child
|
# @param [Object] requirement the requirement that is requiring the child
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def add_child_vertex(name, payload, parent_names, requirement)
|
def add_child_vertex(name, payload, parent_names, requirement)
|
||||||
is_root = parent_names.include?(nil)
|
vertex = add_vertex(name, payload)
|
||||||
parent_nodes = parent_names.compact.map { |n| vertex_named(n) }
|
parent_names.each do |parent_name|
|
||||||
vertex = vertex_named(name) || if is_root
|
unless parent_name
|
||||||
add_root_vertex(name, payload)
|
vertex.root = true
|
||||||
else
|
next
|
||||||
add_vertex(name, payload)
|
end
|
||||||
end
|
parent_node = vertex_named(parent_name)
|
||||||
vertex.payload ||= payload
|
|
||||||
parent_nodes.each do |parent_node|
|
|
||||||
add_edge(parent_node, vertex, requirement)
|
add_edge(parent_node, vertex, requirement)
|
||||||
end
|
end
|
||||||
vertex
|
vertex
|
||||||
|
@ -106,16 +103,11 @@ module Gem::Resolver::Molinillo
|
||||||
# @param [String] name
|
# @param [String] name
|
||||||
# @param [Object] payload
|
# @param [Object] payload
|
||||||
# @return [Vertex] the vertex that was added to `self`
|
# @return [Vertex] the vertex that was added to `self`
|
||||||
def add_vertex(name, payload)
|
def add_vertex(name, payload, root = false)
|
||||||
vertex = vertices[name] ||= Vertex.new(self, name, payload)
|
vertex = vertices[name] ||= Vertex.new(name, payload)
|
||||||
vertex.tap { |v| v.payload = payload }
|
vertex.payload ||= payload
|
||||||
end
|
vertex.root ||= root
|
||||||
|
vertex
|
||||||
# @param [String] name
|
|
||||||
# @param [Object] payload
|
|
||||||
# @return [Vertex] the vertex that was added to `self`
|
|
||||||
def add_root_vertex(name, payload)
|
|
||||||
add_vertex(name, payload).tap { |v| root_vertices[name] = v }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
|
# Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
|
||||||
|
@ -123,12 +115,12 @@ module Gem::Resolver::Molinillo
|
||||||
# @param [String] name
|
# @param [String] name
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def detach_vertex_named(name)
|
def detach_vertex_named(name)
|
||||||
vertex = vertex_named(name)
|
return unless vertex = vertices.delete(name)
|
||||||
return unless vertex
|
vertex.outgoing_edges.each do |e|
|
||||||
successors = vertex.successors
|
v = e.destination
|
||||||
vertices.delete(name)
|
v.incoming_edges.delete(e)
|
||||||
edges.reject! { |e| e.origin == vertex || e.destination == vertex }
|
detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
|
||||||
successors.each { |v| detach_vertex_named(v.name) unless root_vertices[v.name] || v.predecessors.any? }
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [String] name
|
# @param [String] name
|
||||||
|
@ -140,7 +132,8 @@ module Gem::Resolver::Molinillo
|
||||||
# @param [String] name
|
# @param [String] name
|
||||||
# @return [Vertex,nil] the root vertex with the given name
|
# @return [Vertex,nil] the root vertex with the given name
|
||||||
def root_vertex_named(name)
|
def root_vertex_named(name)
|
||||||
root_vertices[name]
|
vertex = vertex_named(name)
|
||||||
|
vertex if vertex && vertex.root?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a new {Edge} to the dependency graph
|
# Adds a new {Edge} to the dependency graph
|
||||||
|
@ -149,18 +142,24 @@ module Gem::Resolver::Molinillo
|
||||||
# @param [Object] requirement the requirement that this edge represents
|
# @param [Object] requirement the requirement that this edge represents
|
||||||
# @return [Edge] the added edge
|
# @return [Edge] the added edge
|
||||||
def add_edge(origin, destination, requirement)
|
def add_edge(origin, destination, requirement)
|
||||||
if origin == destination || destination.path_to?(origin)
|
if destination.path_to?(origin)
|
||||||
raise CircularDependencyError.new([origin, destination])
|
raise CircularDependencyError.new([origin, destination])
|
||||||
end
|
end
|
||||||
Edge.new(origin, destination, [requirement]).tap { |e| edges << e }
|
add_edge_no_circular(origin, destination, requirement)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def add_edge_no_circular(origin, destination, requirement)
|
||||||
|
edge = Edge.new(origin, destination, requirement)
|
||||||
|
origin.outgoing_edges << edge
|
||||||
|
destination.incoming_edges << edge
|
||||||
|
edge
|
||||||
end
|
end
|
||||||
|
|
||||||
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
|
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
|
||||||
# {#payload}
|
# {#payload}
|
||||||
class Vertex
|
class Vertex
|
||||||
# @return [DependencyGraph] the graph this vertex is a node of
|
|
||||||
attr_accessor :graph
|
|
||||||
|
|
||||||
# @return [String] the name of the vertex
|
# @return [String] the name of the vertex
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
|
||||||
|
@ -171,50 +170,62 @@ module Gem::Resolver::Molinillo
|
||||||
# this vertex
|
# this vertex
|
||||||
attr_reader :explicit_requirements
|
attr_reader :explicit_requirements
|
||||||
|
|
||||||
# @param [DependencyGraph] graph see {#graph}
|
# @return [Boolean] whether the vertex is considered a root vertex
|
||||||
|
attr_accessor :root
|
||||||
|
alias_method :root?, :root
|
||||||
|
|
||||||
# @param [String] name see {#name}
|
# @param [String] name see {#name}
|
||||||
# @param [Object] payload see {#payload}
|
# @param [Object] payload see {#payload}
|
||||||
def initialize(graph, name, payload)
|
def initialize(name, payload)
|
||||||
@graph = graph
|
|
||||||
@name = name
|
@name = name
|
||||||
@payload = payload
|
@payload = payload
|
||||||
@explicit_requirements = []
|
@explicit_requirements = []
|
||||||
|
@outgoing_edges = []
|
||||||
|
@incoming_edges = []
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<Object>] all of the requirements that required
|
# @return [Array<Object>] all of the requirements that required
|
||||||
# this vertex
|
# this vertex
|
||||||
def requirements
|
def requirements
|
||||||
incoming_edges.map(&:requirements).flatten + explicit_requirements
|
incoming_edges.map(&:requirement) + explicit_requirements
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
||||||
# {Edge#origin}
|
# {Edge#origin}
|
||||||
def outgoing_edges
|
attr_accessor :outgoing_edges
|
||||||
graph.edges.select { |e| e.origin.shallow_eql?(self) }
|
|
||||||
end
|
|
||||||
|
|
||||||
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
||||||
# {Edge#destination}
|
# {Edge#destination}
|
||||||
def incoming_edges
|
attr_accessor :incoming_edges
|
||||||
graph.edges.select { |e| e.destination.shallow_eql?(self) }
|
|
||||||
end
|
|
||||||
|
|
||||||
# @return [Set<Vertex>] the vertices of {#graph} that have an edge with
|
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
||||||
# `self` as their {Edge#destination}
|
# `self` as their {Edge#destination}
|
||||||
def predecessors
|
def predecessors
|
||||||
incoming_edges.map(&:origin).to_set
|
incoming_edges.map(&:origin)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Set<Vertex>] the vertices of {#graph} that have an edge with
|
# @return [Array<Vertex>] the vertices of {#graph} where `self` is a
|
||||||
|
# {#descendent?}
|
||||||
|
def recursive_predecessors
|
||||||
|
vertices = predecessors
|
||||||
|
vertices += vertices.map(&:recursive_predecessors).flatten(1)
|
||||||
|
vertices.uniq!
|
||||||
|
vertices
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
||||||
# `self` as their {Edge#origin}
|
# `self` as their {Edge#origin}
|
||||||
def successors
|
def successors
|
||||||
outgoing_edges.map(&:destination).to_set
|
outgoing_edges.map(&:destination)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Set<Vertex>] the vertices of {#graph} where `self` is an
|
# @return [Array<Vertex>] the vertices of {#graph} where `self` is an
|
||||||
# {#ancestor?}
|
# {#ancestor?}
|
||||||
def recursive_successors
|
def recursive_successors
|
||||||
successors + successors.map(&:recursive_successors).reduce(Set.new, &:+)
|
vertices = successors
|
||||||
|
vertices += vertices.map(&:recursive_successors).flatten(1)
|
||||||
|
vertices.uniq!
|
||||||
|
vertices
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [String] a string suitable for debugging
|
# @return [String] a string suitable for debugging
|
||||||
|
@ -226,7 +237,7 @@ module Gem::Resolver::Molinillo
|
||||||
# by a recursive traversal of each {Vertex#successors}
|
# by a recursive traversal of each {Vertex#successors}
|
||||||
def ==(other)
|
def ==(other)
|
||||||
shallow_eql?(other) &&
|
shallow_eql?(other) &&
|
||||||
successors == other.successors
|
successors.to_set == other.successors.to_set
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] whether the two vertices are equal, determined
|
# @return [Boolean] whether the two vertices are equal, determined
|
||||||
|
@ -248,7 +259,7 @@ module Gem::Resolver::Molinillo
|
||||||
# dependency graph?
|
# dependency graph?
|
||||||
# @return true iff there is a path following edges within this {#graph}
|
# @return true iff there is a path following edges within this {#graph}
|
||||||
def path_to?(other)
|
def path_to?(other)
|
||||||
successors.include?(other) || successors.any? { |v| v.path_to?(other) }
|
equal?(other) || successors.any? { |v| v.path_to?(other) }
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :descendent?, :path_to?
|
alias_method :descendent?, :path_to?
|
||||||
|
@ -257,7 +268,7 @@ module Gem::Resolver::Molinillo
|
||||||
# dependency graph?
|
# dependency graph?
|
||||||
# @return true iff there is a path following edges within this {#graph}
|
# @return true iff there is a path following edges within this {#graph}
|
||||||
def ancestor?(other)
|
def ancestor?(other)
|
||||||
predecessors.include?(other) || predecessors.any? { |v| v.ancestor?(other) }
|
other.path_to?(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :is_reachable_from?, :ancestor?
|
alias_method :is_reachable_from?, :ancestor?
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module Gem::Resolver::Molinillo
|
module Gem::Resolver::Molinillo
|
||||||
VERSION = '0.3.0'
|
VERSION = '0.4.0'
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,13 +12,15 @@ module Gem::Resolver::Molinillo
|
||||||
# @attr [Object] locked_requirement the relevant locking requirement.
|
# @attr [Object] locked_requirement the relevant locking requirement.
|
||||||
# @attr [Array<Array<Object>>] requirement_trees the different requirement
|
# @attr [Array<Array<Object>>] requirement_trees the different requirement
|
||||||
# trees that led to every requirement for the conflicting name.
|
# trees that led to every requirement for the conflicting name.
|
||||||
|
# @attr [{String=>Object}] activated_by_name the already-activated specs.
|
||||||
Conflict = Struct.new(
|
Conflict = Struct.new(
|
||||||
:requirement,
|
:requirement,
|
||||||
:requirements,
|
:requirements,
|
||||||
:existing,
|
:existing,
|
||||||
:possibility,
|
:possibility,
|
||||||
:locked_requirement,
|
:locked_requirement,
|
||||||
:requirement_trees
|
:requirement_trees,
|
||||||
|
:activated_by_name
|
||||||
)
|
)
|
||||||
|
|
||||||
# @return [SpecificationProvider] the provider that knows about
|
# @return [SpecificationProvider] the provider that knows about
|
||||||
|
@ -164,7 +166,7 @@ module Gem::Resolver::Molinillo
|
||||||
# @return [DependencyState] the initial state for the resolution
|
# @return [DependencyState] the initial state for the resolution
|
||||||
def initial_state
|
def initial_state
|
||||||
graph = DependencyGraph.new.tap do |dg|
|
graph = DependencyGraph.new.tap do |dg|
|
||||||
original_requested.each { |r| dg.add_root_vertex(name_for(r), nil).tap { |v| v.explicit_requirements << r } }
|
original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
|
||||||
end
|
end
|
||||||
|
|
||||||
requirements = sort_dependencies(original_requested, graph, {})
|
requirements = sort_dependencies(original_requested, graph, {})
|
||||||
|
@ -216,7 +218,7 @@ module Gem::Resolver::Molinillo
|
||||||
return nil unless requirement
|
return nil unless requirement
|
||||||
seen = false
|
seen = false
|
||||||
state = states.reverse_each.find do |s|
|
state = states.reverse_each.find do |s|
|
||||||
seen ||= s.requirement == requirement
|
seen ||= s.requirement == requirement || s.requirements.include?(requirement)
|
||||||
seen && s.requirement != requirement && !s.requirements.include?(requirement)
|
seen && s.requirement != requirement && !s.requirements.include?(requirement)
|
||||||
end
|
end
|
||||||
state && state.requirement
|
state && state.requirement
|
||||||
|
@ -250,21 +252,23 @@ module Gem::Resolver::Molinillo
|
||||||
name_for_explicit_dependency_source => vertex.explicit_requirements,
|
name_for_explicit_dependency_source => vertex.explicit_requirements,
|
||||||
name_for_locking_dependency_source => Array(locked_requirement_named(name)),
|
name_for_locking_dependency_source => Array(locked_requirement_named(name)),
|
||||||
}
|
}
|
||||||
vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(*edge.requirements) }
|
vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
|
||||||
conflicts[name] = Conflict.new(
|
conflicts[name] = Conflict.new(
|
||||||
requirement,
|
requirement,
|
||||||
Hash[requirements.select { |_, r| !r.empty? }],
|
Hash[requirements.select { |_, r| !r.empty? }],
|
||||||
vertex.payload,
|
vertex.payload,
|
||||||
possibility,
|
possibility,
|
||||||
locked_requirement_named(name),
|
locked_requirement_named(name),
|
||||||
requirement_trees
|
requirement_trees,
|
||||||
|
Hash[activated.map { |v| [v.name, v.payload] }.select(&:last)]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<Array<Object>>] The different requirement
|
# @return [Array<Array<Object>>] The different requirement
|
||||||
# trees that led to every requirement for the current spec.
|
# trees that led to every requirement for the current spec.
|
||||||
def requirement_trees
|
def requirement_trees
|
||||||
activated.vertex_named(name).requirements.map { |r| requirement_tree_for(r) }
|
vertex = activated.vertex_named(name)
|
||||||
|
vertex.requirements.map { |r| requirement_tree_for(r) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Array<Object>] the list of requirements that led to
|
# @return [Array<Object>] the list of requirements that led to
|
||||||
|
@ -322,7 +326,7 @@ module Gem::Resolver::Molinillo
|
||||||
existing_spec = existing_node.payload
|
existing_spec = existing_node.payload
|
||||||
if requirement_satisfied_by?(requirement, activated, existing_spec)
|
if requirement_satisfied_by?(requirement, activated, existing_spec)
|
||||||
new_requirements = requirements.dup
|
new_requirements = requirements.dup
|
||||||
push_state_for_requirements(new_requirements)
|
push_state_for_requirements(new_requirements, false)
|
||||||
else
|
else
|
||||||
return if attempt_to_swap_possibility
|
return if attempt_to_swap_possibility
|
||||||
create_conflict
|
create_conflict
|
||||||
|
@ -389,17 +393,17 @@ module Gem::Resolver::Molinillo
|
||||||
def require_nested_dependencies_for(activated_spec)
|
def require_nested_dependencies_for(activated_spec)
|
||||||
nested_dependencies = dependencies_for(activated_spec)
|
nested_dependencies = dependencies_for(activated_spec)
|
||||||
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" }
|
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" }
|
||||||
nested_dependencies.each { |d| activated.add_child_vertex name_for(d), nil, [name_for(activated_spec)], d }
|
nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
|
||||||
|
|
||||||
push_state_for_requirements(requirements + nested_dependencies)
|
push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Pushes a new {DependencyState} that encapsulates both existing and new
|
# Pushes a new {DependencyState} that encapsulates both existing and new
|
||||||
# requirements
|
# requirements
|
||||||
# @param [Array] new_requirements
|
# @param [Array] new_requirements
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def push_state_for_requirements(new_requirements, new_activated = activated.dup)
|
def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated.dup)
|
||||||
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts)
|
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
|
||||||
new_requirement = new_requirements.shift
|
new_requirement = new_requirements.shift
|
||||||
new_name = new_requirement ? name_for(new_requirement) : ''
|
new_name = new_requirement ? name_for(new_requirement) : ''
|
||||||
possibilities = new_requirement ? search_for(new_requirement) : []
|
possibilities = new_requirement ? search_for(new_requirement) : []
|
||||||
|
@ -420,7 +424,7 @@ module Gem::Resolver::Molinillo
|
||||||
def handle_missing_or_push_dependency_state(state)
|
def handle_missing_or_push_dependency_state(state)
|
||||||
if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
|
if state.requirement && state.possibilities.empty? && allow_missing?(state.requirement)
|
||||||
state.activated.detach_vertex_named(state.name)
|
state.activated.detach_vertex_named(state.name)
|
||||||
push_state_for_requirements(state.requirements, state.activated)
|
push_state_for_requirements(state.requirements.dup, false, state.activated)
|
||||||
else
|
else
|
||||||
states.push state
|
states.push state
|
||||||
end
|
end
|
||||||
|
|
|
@ -2593,6 +2593,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
trail.push(self)
|
trail.push(self)
|
||||||
begin
|
begin
|
||||||
dependencies.each do |dep|
|
dependencies.each do |dep|
|
||||||
|
next unless dep.runtime?
|
||||||
dep.to_specs.reverse_each do |dep_spec|
|
dep.to_specs.reverse_each do |dep_spec|
|
||||||
next if visited.has_key?(dep_spec)
|
next if visited.has_key?(dep_spec)
|
||||||
visited[dep_spec] = true
|
visited[dep_spec] = true
|
||||||
|
@ -2744,7 +2745,7 @@ class Gem::Specification < Gem::BasicSpecification
|
||||||
"each license must be 64 characters or less"
|
"each license must be 64 characters or less"
|
||||||
end
|
end
|
||||||
|
|
||||||
if !Gem::Licenses::IDENTIFIERS.include?(license) && !license.eql?(Gem::Licenses::NONSTANDARD)
|
if !Gem::Licenses.match?(license)
|
||||||
warning <<-warning
|
warning <<-warning
|
||||||
WARNING: license value '#{license}' is invalid. Use a license identifier from
|
WARNING: license value '#{license}' is invalid. Use a license identifier from
|
||||||
http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
|
http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
|
||||||
|
|
|
@ -4,7 +4,8 @@ class Gem::Licenses
|
||||||
# Software Package Data Exchange (SPDX) standard open-source software
|
# Software Package Data Exchange (SPDX) standard open-source software
|
||||||
# license identifiers
|
# license identifiers
|
||||||
IDENTIFIERS = %w(
|
IDENTIFIERS = %w(
|
||||||
AAL
|
0BSD
|
||||||
|
AAL
|
||||||
ADSL
|
ADSL
|
||||||
AFL-1.1
|
AFL-1.1
|
||||||
AFL-1.2
|
AFL-1.2
|
||||||
|
@ -89,6 +90,7 @@ class Gem::Licenses
|
||||||
CECILL-1.0
|
CECILL-1.0
|
||||||
CECILL-1.1
|
CECILL-1.1
|
||||||
CECILL-2.0
|
CECILL-2.0
|
||||||
|
CECILL-2.1
|
||||||
CECILL-B
|
CECILL-B
|
||||||
CECILL-C
|
CECILL-C
|
||||||
CNRI-Jython
|
CNRI-Jython
|
||||||
|
@ -102,6 +104,7 @@ class Gem::Licenses
|
||||||
ClArtistic
|
ClArtistic
|
||||||
Condor-1.1
|
Condor-1.1
|
||||||
Crossword
|
Crossword
|
||||||
|
CrystalStacker
|
||||||
Cube
|
Cube
|
||||||
D-FSL-1.0
|
D-FSL-1.0
|
||||||
DOC
|
DOC
|
||||||
|
@ -146,6 +149,7 @@ class Gem::Licenses
|
||||||
Imlib2
|
Imlib2
|
||||||
Intel
|
Intel
|
||||||
Intel-ACPI
|
Intel-ACPI
|
||||||
|
Interbase-1.0
|
||||||
JSON
|
JSON
|
||||||
JasPer-2.0
|
JasPer-2.0
|
||||||
LGPL-2.0
|
LGPL-2.0
|
||||||
|
@ -254,6 +258,7 @@ class Gem::Licenses
|
||||||
SPL-1.0
|
SPL-1.0
|
||||||
SWL
|
SWL
|
||||||
Saxpath
|
Saxpath
|
||||||
|
Sendmail
|
||||||
SimPL-2.0
|
SimPL-2.0
|
||||||
Sleepycat
|
Sleepycat
|
||||||
Spencer-86
|
Spencer-86
|
||||||
|
@ -306,4 +311,19 @@ class Gem::Licenses
|
||||||
xpp
|
xpp
|
||||||
zlib-acknowledgement
|
zlib-acknowledgement
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
|
REGEXP = %r{
|
||||||
|
\A
|
||||||
|
(
|
||||||
|
#{Regexp.union(IDENTIFIERS)}
|
||||||
|
\+?
|
||||||
|
(\s WITH \s .+)?
|
||||||
|
| #{NONSTANDARD}
|
||||||
|
)
|
||||||
|
\Z
|
||||||
|
}ox.freeze
|
||||||
|
|
||||||
|
def self.match?(license)
|
||||||
|
!REGEXP.match(license).nil?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2128,6 +2128,27 @@ dependencies: []
|
||||||
assert_nil @ext.to_fullpath("notexist")
|
assert_nil @ext.to_fullpath("notexist")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fullpath_return_rb_extension_file_when_exist_the_same_name_file
|
||||||
|
ext_spec
|
||||||
|
|
||||||
|
@ext.require_paths = 'lib'
|
||||||
|
|
||||||
|
dir = File.join(@gemhome, 'gems', @ext.original_name, 'lib')
|
||||||
|
expected_rb = File.join(dir, 'code.rb')
|
||||||
|
FileUtils.mkdir_p dir
|
||||||
|
FileUtils.touch expected_rb
|
||||||
|
|
||||||
|
dir = @ext.extension_dir
|
||||||
|
ext = RbConfig::CONFIG["DLEXT"]
|
||||||
|
expected_so = File.join(dir, "code.#{ext}")
|
||||||
|
FileUtils.mkdir_p dir
|
||||||
|
FileUtils.touch expected_so
|
||||||
|
|
||||||
|
@ext.activate
|
||||||
|
|
||||||
|
assert_equal expected_rb, @ext.to_fullpath("code")
|
||||||
|
end
|
||||||
|
|
||||||
def test_require_already_activated
|
def test_require_already_activated
|
||||||
save_loaded_features do
|
save_loaded_features do
|
||||||
a1 = new_spec "a", "1", nil, "lib/d.rb"
|
a1 = new_spec "a", "1", nil, "lib/d.rb"
|
||||||
|
@ -2874,6 +2895,46 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
|
||||||
warning
|
warning
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_validate_license_values_plus
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@a1.licenses = ['GPL-2.0+']
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_empty @ui.error
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_license_values_with
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@a1.licenses = ['GPL-2.0+ WITH Autoconf-exception-2.0']
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_empty @ui.error
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_license_with_nonsense_suffix
|
||||||
|
util_setup_validate
|
||||||
|
|
||||||
|
use_ui @ui do
|
||||||
|
@a1.licenses = ['GPL-2.0+ FOO', 'GPL-2.0 FOO']
|
||||||
|
@a1.validate
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match <<-warning, @ui.error
|
||||||
|
WARNING: license value 'GPL-2.0+ FOO' is invalid. Use a license identifier from
|
||||||
|
http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
|
||||||
|
warning
|
||||||
|
assert_match <<-warning, @ui.error
|
||||||
|
WARNING: license value 'GPL-2.0 FOO' is invalid. Use a license identifier from
|
||||||
|
http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
|
||||||
|
warning
|
||||||
|
end
|
||||||
|
|
||||||
def test_validate_name
|
def test_validate_name
|
||||||
util_setup_validate
|
util_setup_validate
|
||||||
|
|
||||||
|
|
|
@ -277,6 +277,21 @@ class TestGemRequire < Gem::TestCase
|
||||||
assert_equal %w(a-1.0 b-2.0), loaded_spec_names
|
assert_equal %w(a-1.0 b-2.0), loaded_spec_names
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_require_doesnt_traverse_development_dependencies
|
||||||
|
a = new_spec("a", "1", nil, "lib/a.rb")
|
||||||
|
z = new_spec("z", "1", "w" => "> 0")
|
||||||
|
w1 = new_spec("w", "1") { |s| s.add_development_dependency "non-existent" }
|
||||||
|
w2 = new_spec("w", "2") { |s| s.add_development_dependency "non-existent" }
|
||||||
|
|
||||||
|
install_specs a, w1, w2, z
|
||||||
|
|
||||||
|
assert gem("z")
|
||||||
|
assert_equal %w(z-1), loaded_spec_names
|
||||||
|
assert_equal ["w (> 0)"], unresolved_names
|
||||||
|
|
||||||
|
assert require("a")
|
||||||
|
end
|
||||||
|
|
||||||
def test_default_gem_only
|
def test_default_gem_only
|
||||||
default_gem_spec = new_default_spec("default", "2.0.0.0",
|
default_gem_spec = new_default_spec("default", "2.0.0.0",
|
||||||
nil, "default/gem.rb")
|
nil, "default/gem.rb")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue