rubygems-update 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.txt +32 -2
- data/Manifest.txt +1 -1
- data/README.rdoc +3 -3
- data/Rakefile +10 -21
- data/lib/rubygems.rb +3 -4
- data/lib/rubygems/basic_specification.rb +56 -39
- data/lib/rubygems/commands/list_command.rb +1 -1
- data/lib/rubygems/core_ext/kernel_require.rb +1 -3
- data/lib/rubygems/installer.rb +2 -2
- data/lib/rubygems/request.rb +4 -1
- data/lib/rubygems/requirement.rb +3 -3
- data/lib/rubygems/resolver.rb +2 -2
- data/lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb +82 -71
- data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +1 -1
- data/lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb +16 -12
- data/lib/rubygems/specification.rb +76 -33
- data/lib/rubygems/stub_specification.rb +68 -58
- data/lib/rubygems/util/licenses.rb +21 -1
- data/lib/rubygems/version.rb +1 -1
- data/test/rubygems/specifications/{foo-0.0.1.gemspec → foo-0.0.1-x86-mswin32.gemspec} +0 -0
- data/test/rubygems/test_bundled_ca.rb +2 -2
- data/test/rubygems/test_gem_resolver.rb +1 -1
- data/test/rubygems/test_gem_specification.rb +76 -0
- data/test/rubygems/test_gem_stub_specification.rb +10 -8
- data/test/rubygems/test_require.rb +15 -0
- data/util/generate_spdx_license_list.rb +18 -3
- metadata +5 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a8f0806e772b0fd07258556709de623f75d0614
|
4
|
+
data.tar.gz: 08f55fd0671659873c7af22435ecfa9e852636ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de055f8e3f751b3ab5b3b138a488089df9891df5dc8e97f5cf5a11df67d120cb9e7e2d348a699e1de43bb940484f76dbe76116da02f357355f2c9d9283ddfb14
|
7
|
+
data.tar.gz: a2fdc146da6f5f44eecfffe93a2412d04eb7423b96a2cd4fe0983b66f8ca6e7e8ee6c4707d673d7fa87ea607e8bc5102a4d1d52be71d163f7bf1ae21fff1c1da
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
# coding: UTF-8
|
2
2
|
|
3
|
-
=== 2.5.
|
3
|
+
=== 2.5.1 / 2015-12-10
|
4
|
+
|
5
|
+
Bug fixes:
|
6
|
+
|
7
|
+
* Ensure platform sorting only uses strings. Affected binary installs on Windows.
|
8
|
+
Issue #1369 reported by Ryan Atball (among others).
|
9
|
+
Pull request #1375 by Samuel E. Giddins.
|
10
|
+
* Revert PR #1332. Unable to reproduce, and nil should be impossible.
|
11
|
+
* Gem::Specification#to_fullpath now returns .rb extensions when such a file
|
12
|
+
exists. Pull request #1114 by y-yagi.
|
13
|
+
* RubyGems now handles Net::HTTPFatalError instead of crashing. Pull
|
14
|
+
request #1314 by Samuel E. Giddins.
|
15
|
+
* Updated bundled Molinillo to 0.4.0. Pull request #1322, #1396 by Samuel E.
|
16
|
+
Giddins.
|
17
|
+
* Improved performance of spec loading by reducing likelihood of loading he
|
18
|
+
complete specification. Pull request #1373 by Aaron Patterson.
|
19
|
+
* Improved caching of requirable files Pull request #1377 by Aaron Patterson.
|
20
|
+
* Fixed activation of gems with development dependencies. Pull request #1388
|
21
|
+
by Samuel E. Giddins.
|
22
|
+
* RubyGems now uses the same Molinillo vendoring strategy as Bundler. Pull
|
23
|
+
request #1397 by Samuel E. Giddins.
|
24
|
+
* Fixed documentation of Gem::Requirement.parse. Pull request #1398 by
|
25
|
+
Juanito Fatas.
|
26
|
+
* RubyGems no longer warns when a prerelease gem has prerelease dependencies.
|
27
|
+
Pull request #1399 by Samuel E. Giddins.
|
28
|
+
* Fixed Gem::Version documentation example. Pull request #1401 by Guilherme
|
29
|
+
Goettems Schneider.
|
30
|
+
* Updated documentation links to https://. Pull request #1404 by Suriyaa
|
31
|
+
Kudo.
|
32
|
+
* Fixed double word typo. Pull request #1411 by Jake Worth.
|
33
|
+
|
34
|
+
=== 2.5.0 / 2015-11-03
|
4
35
|
|
5
36
|
Major enhancements:
|
6
37
|
|
@@ -2979,4 +3010,3 @@ See ChangeLog
|
|
2979
3010
|
=== 0.2.0 / 2004-03-14
|
2980
3011
|
|
2981
3012
|
* Initial public release
|
2982
|
-
|
data/Manifest.txt
CHANGED
@@ -233,7 +233,7 @@ test/rubygems/rubygems_plugin.rb
|
|
233
233
|
test/rubygems/sff/discover.rb
|
234
234
|
test/rubygems/simple_gem.rb
|
235
235
|
test/rubygems/specifications/bar-0.0.2.gemspec
|
236
|
-
test/rubygems/specifications/foo-0.0.1.gemspec
|
236
|
+
test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec
|
237
237
|
test/rubygems/ssl_cert.pem
|
238
238
|
test/rubygems/ssl_key.pem
|
239
239
|
test/rubygems/test_bundled_ca.rb
|
data/README.rdoc
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
= RubyGems
|
2
2
|
|
3
|
-
Homepage: ::
|
3
|
+
Homepage: :: https://rubygems.org
|
4
4
|
Announcements: :: http://blog.rubygems.org
|
5
5
|
Documentation: :: http://guides.rubygems.org
|
6
6
|
Support: :: http://help.rubygems.org
|
7
|
-
Source: ::
|
8
|
-
Bugtracker: ::
|
7
|
+
Source: :: https://github.com/rubygems/rubygems
|
8
|
+
Bugtracker: :: https://github.com/rubygems/rubygems/issues
|
9
9
|
|
10
10
|
== DESCRIPTION
|
11
11
|
|
data/Rakefile
CHANGED
@@ -108,29 +108,18 @@ task :install_test_deps => :clean_env do
|
|
108
108
|
sh "gem install minitest -v '~> 4.0'"
|
109
109
|
end
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
files = Dir.glob('lib/rubygems/resolver/molinillo/**/*.rb')
|
114
|
-
sh "sed -i.bak 's/Molinillo/Gem::Resolver::Molinillo/g' #{files.join(' ')}"
|
115
|
-
sh "sed -i.bak \"s/require 'molinillo/require 'rubygems\\/resolver\\/molinillo\\/lib\\/molinillo/g\" #{files.join(' ')}"
|
116
|
-
sh "rm #{files.join('.bak ')}.bak"
|
117
|
-
end
|
111
|
+
begin
|
112
|
+
require "automatiek"
|
118
113
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
114
|
+
Automatiek::RakeTask.new("molinillo") do |lib|
|
115
|
+
lib.download = { :github => "https://github.com/CocoaPods/Molinillo" }
|
116
|
+
lib.namespace = "Molinillo"
|
117
|
+
lib.prefix = "Gem::Resolver"
|
118
|
+
lib.vendor_lib = "lib/rubygems/resolver/molinillo"
|
123
119
|
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
Dir.chdir 'lib/rubygems/resolver' do
|
128
|
-
sh "rm -rf molinillo"
|
129
|
-
sh "curl -L https://github.com/CocoaPods/molinillo/archive/#{tag}.tar.gz | tar -xz"
|
130
|
-
sh "mv Molinillo-* molinillo"
|
131
|
-
end
|
132
|
-
Rake::Task['molinillo:namespace'].invoke
|
133
|
-
Rake::Task['molinillo:clean'].invoke
|
120
|
+
rescue LoadError
|
121
|
+
namespace :vendor do
|
122
|
+
task(:molinillo) { abort "Install the automatiek gem to be able to vendor gems." }
|
134
123
|
end
|
135
124
|
end
|
136
125
|
|
data/lib/rubygems.rb
CHANGED
@@ -9,7 +9,7 @@ require 'rbconfig'
|
|
9
9
|
require 'thread'
|
10
10
|
|
11
11
|
module Gem
|
12
|
-
VERSION = '2.5.
|
12
|
+
VERSION = '2.5.1'
|
13
13
|
end
|
14
14
|
|
15
15
|
# Must be first since it unloads the prelude from 1.9.2
|
@@ -307,11 +307,10 @@ module Gem
|
|
307
307
|
# package is not available as a gem, return nil.
|
308
308
|
|
309
309
|
def self.datadir(gem_name)
|
310
|
-
# TODO: deprecate
|
311
|
-
# and drop the extra ", gem_name" which is uselessly redundant
|
310
|
+
# TODO: deprecate
|
312
311
|
spec = @loaded_specs[gem_name]
|
313
312
|
return nil if spec.nil?
|
314
|
-
|
313
|
+
spec.datadir
|
315
314
|
end
|
316
315
|
|
317
316
|
##
|
@@ -37,6 +37,14 @@ class Gem::BasicSpecification
|
|
37
37
|
File.join(Gem.default_dir, "specifications", "default")
|
38
38
|
end
|
39
39
|
|
40
|
+
##
|
41
|
+
# The path to the gem.build_complete file within the extension install
|
42
|
+
# directory.
|
43
|
+
|
44
|
+
def gem_build_complete_path # :nodoc:
|
45
|
+
File.join extension_dir, 'gem.build_complete'
|
46
|
+
end
|
47
|
+
|
40
48
|
##
|
41
49
|
# True when the gem has been activated
|
42
50
|
|
@@ -50,39 +58,24 @@ class Gem::BasicSpecification
|
|
50
58
|
# eg: /usr/local/lib/ruby/gems/1.8
|
51
59
|
|
52
60
|
def base_dir
|
53
|
-
|
54
|
-
@base_dir ||= if default_gem? then
|
55
|
-
File.dirname File.dirname File.dirname loaded_from
|
56
|
-
else
|
57
|
-
File.dirname File.dirname loaded_from
|
58
|
-
end
|
61
|
+
raise NotImplementedError
|
59
62
|
end
|
60
63
|
|
61
64
|
##
|
62
65
|
# Return true if this spec can require +file+.
|
63
66
|
|
64
67
|
def contains_requirable_file? file
|
65
|
-
@
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
"Try: gem pristine #{name} --version #{version}"
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
|
78
|
-
suffixes = Gem.suffixes
|
68
|
+
if @ignored then
|
69
|
+
return false
|
70
|
+
elsif missing_extensions? then
|
71
|
+
@ignored = true
|
72
|
+
|
73
|
+
warn "Ignoring #{full_name} because its extensions are not built. " +
|
74
|
+
"Try: gem pristine #{name} --version #{version}"
|
75
|
+
return false
|
76
|
+
end
|
79
77
|
|
80
|
-
|
81
|
-
base = "#{dir}/#{file}"
|
82
|
-
suffixes.any? { |suf| File.file? "#{base}#{suf}" }
|
83
|
-
end
|
84
|
-
end ? :yes : :no
|
85
|
-
@contains_requirable_file[file] == :yes
|
78
|
+
have_file? file, Gem.suffixes
|
86
79
|
end
|
87
80
|
|
88
81
|
def default_gem?
|
@@ -94,7 +87,7 @@ class Gem::BasicSpecification
|
|
94
87
|
# Returns full path to the directory where gem's extensions are installed.
|
95
88
|
|
96
89
|
def extension_dir
|
97
|
-
@extension_dir ||= File.expand_path
|
90
|
+
@extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).untaint
|
98
91
|
end
|
99
92
|
|
100
93
|
##
|
@@ -110,7 +103,7 @@ class Gem::BasicSpecification
|
|
110
103
|
# TODO: also, shouldn't it default to full_name if it hasn't been written?
|
111
104
|
path = File.expand_path File.join(gems_dir, full_name)
|
112
105
|
path.untaint
|
113
|
-
path
|
106
|
+
path
|
114
107
|
end
|
115
108
|
|
116
109
|
private :find_full_gem_path
|
@@ -148,12 +141,20 @@ class Gem::BasicSpecification
|
|
148
141
|
File.join full_gem_path, path.untaint
|
149
142
|
end
|
150
143
|
|
151
|
-
full_paths << extension_dir
|
144
|
+
full_paths << extension_dir if have_extensions?
|
152
145
|
|
153
146
|
full_paths
|
154
147
|
end
|
155
148
|
end
|
156
149
|
|
150
|
+
##
|
151
|
+
# The path to the data directory for this gem.
|
152
|
+
|
153
|
+
def datadir
|
154
|
+
# TODO: drop the extra ", gem_name" which is uselessly redundant
|
155
|
+
File.expand_path(File.join(gems_dir, full_name, "data", name)).untaint
|
156
|
+
end
|
157
|
+
|
157
158
|
##
|
158
159
|
# Full path of the target library file.
|
159
160
|
# If the file is not in this gem, return nil.
|
@@ -165,8 +166,8 @@ class Gem::BasicSpecification
|
|
165
166
|
begin
|
166
167
|
fullpath = nil
|
167
168
|
suffixes = Gem.suffixes
|
168
|
-
|
169
|
-
|
169
|
+
suffixes.find do |suf|
|
170
|
+
full_require_paths.find do |dir|
|
170
171
|
File.file?(fullpath = "#{dir}/#{path}#{suf}")
|
171
172
|
end
|
172
173
|
end ? fullpath : nil
|
@@ -189,8 +190,7 @@ class Gem::BasicSpecification
|
|
189
190
|
# gem directory. eg: /usr/local/lib/ruby/1.8/gems
|
190
191
|
|
191
192
|
def gems_dir
|
192
|
-
|
193
|
-
@gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
|
193
|
+
raise NotImplementedError
|
194
194
|
end
|
195
195
|
|
196
196
|
def internal_init # :nodoc:
|
@@ -198,8 +198,7 @@ class Gem::BasicSpecification
|
|
198
198
|
@extensions_dir = nil
|
199
199
|
@full_gem_path = nil
|
200
200
|
@gem_dir = nil
|
201
|
-
@
|
202
|
-
@base_dir = nil
|
201
|
+
@ignored = nil
|
203
202
|
end
|
204
203
|
|
205
204
|
##
|
@@ -217,7 +216,7 @@ class Gem::BasicSpecification
|
|
217
216
|
end
|
218
217
|
|
219
218
|
def raw_require_paths # :nodoc:
|
220
|
-
|
219
|
+
raise NotImplementedError
|
221
220
|
end
|
222
221
|
|
223
222
|
##
|
@@ -238,7 +237,7 @@ class Gem::BasicSpecification
|
|
238
237
|
# spec.require_path = '.'
|
239
238
|
|
240
239
|
def require_paths
|
241
|
-
return raw_require_paths
|
240
|
+
return raw_require_paths unless have_extensions?
|
242
241
|
|
243
242
|
[extension_dir].concat raw_require_paths
|
244
243
|
end
|
@@ -250,8 +249,8 @@ class Gem::BasicSpecification
|
|
250
249
|
def source_paths
|
251
250
|
paths = raw_require_paths.dup
|
252
251
|
|
253
|
-
if
|
254
|
-
ext_dirs =
|
252
|
+
if have_extensions? then
|
253
|
+
ext_dirs = extensions.map do |extension|
|
255
254
|
extension.split(File::SEPARATOR, 2).first
|
256
255
|
end.uniq
|
257
256
|
|
@@ -307,5 +306,23 @@ class Gem::BasicSpecification
|
|
307
306
|
raise NotImplementedError
|
308
307
|
end
|
309
308
|
|
309
|
+
private
|
310
|
+
|
311
|
+
def have_extensions?; !extensions.empty?; end
|
312
|
+
|
313
|
+
def have_file? file, suffixes
|
314
|
+
return true if raw_require_paths.any? do |path|
|
315
|
+
base = File.join(gems_dir, full_name, path.untaint, file).untaint
|
316
|
+
suffixes.any? { |suf| File.file? base + suf }
|
317
|
+
end
|
318
|
+
|
319
|
+
if have_extensions?
|
320
|
+
base = File.join extension_dir, file
|
321
|
+
suffixes.any? { |suf| File.file? base + suf }
|
322
|
+
else
|
323
|
+
false
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
310
327
|
end
|
311
328
|
|
@@ -60,9 +60,7 @@ module Kernel
|
|
60
60
|
#--
|
61
61
|
# TODO request access to the C implementation of this to speed up RubyGems
|
62
62
|
|
63
|
-
spec = Gem::Specification.
|
64
|
-
s.activated? and s.contains_requirable_file? path
|
65
|
-
}
|
63
|
+
spec = Gem::Specification.find_active_stub_by_path path
|
66
64
|
|
67
65
|
begin
|
68
66
|
RUBYGEMS_ACTIVATION_MONITOR.exit
|
data/lib/rubygems/installer.rb
CHANGED
@@ -391,7 +391,7 @@ class Gem::Installer
|
|
391
391
|
end
|
392
392
|
|
393
393
|
##
|
394
|
-
# The location of
|
394
|
+
# The location of the spec file that is installed.
|
395
395
|
#
|
396
396
|
|
397
397
|
def spec_file
|
@@ -399,7 +399,7 @@ class Gem::Installer
|
|
399
399
|
end
|
400
400
|
|
401
401
|
##
|
402
|
-
# The location of
|
402
|
+
# The location of the default spec file for default gems.
|
403
403
|
#
|
404
404
|
|
405
405
|
def default_spec_file
|
data/lib/rubygems/request.rb
CHANGED
@@ -185,6 +185,10 @@ class Gem::Request
|
|
185
185
|
|
186
186
|
bad_response = true
|
187
187
|
retry
|
188
|
+
rescue Net::HTTPFatalError
|
189
|
+
verbose "fatal error"
|
190
|
+
|
191
|
+
raise Gem::RemoteFetcher::FetchError.new('fatal error', @uri)
|
188
192
|
# HACK work around EOFError bug in Net::HTTP
|
189
193
|
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
190
194
|
# to install gems.
|
@@ -241,4 +245,3 @@ end
|
|
241
245
|
require 'rubygems/request/http_pool'
|
242
246
|
require 'rubygems/request/https_pool'
|
243
247
|
require 'rubygems/request/connection_pools'
|
244
|
-
|
data/lib/rubygems/requirement.rb
CHANGED
@@ -89,9 +89,9 @@ class Gem::Requirement
|
|
89
89
|
# specification, like <tt>">= 1.2"</tt>, or a simple version number,
|
90
90
|
# like <tt>"1.2"</tt>.
|
91
91
|
#
|
92
|
-
# parse("> 1.0") # => [">", "1.0"]
|
93
|
-
# parse("1.0") # => ["=", "1.0"]
|
94
|
-
# parse(Gem::Version.new("1.0")) # => ["=, "1.0"]
|
92
|
+
# parse("> 1.0") # => [">", Gem::Version.new("1.0")]
|
93
|
+
# parse("1.0") # => ["=", Gem::Version.new("1.0")]
|
94
|
+
# parse(Gem::Version.new("1.0")) # => ["=, Gem::Version.new("1.0")]
|
95
95
|
|
96
96
|
def self.parse obj
|
97
97
|
return ["=", obj] if Gem::Version === obj
|
data/lib/rubygems/resolver.rb
CHANGED
@@ -187,7 +187,7 @@ class Gem::Resolver
|
|
187
187
|
|
188
188
|
def resolve
|
189
189
|
locking_dg = Molinillo::DependencyGraph.new
|
190
|
-
Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload)
|
190
|
+
Molinillo::Resolver.new(self, self).resolve(@needed.map { |d| DependencyRequest.new d, nil }, locking_dg).tsort.map(&:payload).compact
|
191
191
|
rescue Molinillo::VersionConflict => e
|
192
192
|
conflict = e.conflicts.values.first
|
193
193
|
raise Gem::DependencyResolutionError, Conflict.new(conflict.requirement_trees.first.first, conflict.existing, conflict.requirement)
|
@@ -232,7 +232,7 @@ class Gem::Resolver
|
|
232
232
|
exc.errors = @set.errors
|
233
233
|
raise exc
|
234
234
|
end
|
235
|
-
possibles.sort_by { |s| [s.source, s.version, s.platform == Gem::Platform.local.to_s ? 1 : 0] }.
|
235
|
+
possibles.sort_by { |s| [s.source, s.version, s.platform.to_s == Gem::Platform.local.to_s ? 1 : 0] }.
|
236
236
|
map { |s| ActivationRequest.new s, dependency, [] }
|
237
237
|
end
|
238
238
|
|
@@ -34,40 +34,34 @@ module Gem::Resolver::Molinillo
|
|
34
34
|
# A directed edge of a {DependencyGraph}
|
35
35
|
# @attr [Vertex] origin The origin of the directed edge
|
36
36
|
# @attr [Vertex] destination The destination of the directed edge
|
37
|
-
# @attr [
|
38
|
-
Edge = Struct.new(:origin, :destination, :
|
37
|
+
# @attr [Object] requirement The requirement the directed edge represents
|
38
|
+
Edge = Struct.new(:origin, :destination, :requirement)
|
39
39
|
|
40
|
-
# @return [{String => Vertex}] vertices that have no {Vertex#predecessors},
|
41
|
-
# keyed by by {Vertex#name}
|
42
|
-
attr_reader :root_vertices
|
43
40
|
# @return [{String => Vertex}] the vertices of the dependency graph, keyed
|
44
41
|
# by {Vertex#name}
|
45
42
|
attr_reader :vertices
|
46
|
-
# @return [Set<Edge>] the edges of the dependency graph
|
47
|
-
attr_reader :edges
|
48
43
|
|
49
44
|
def initialize
|
50
45
|
@vertices = {}
|
51
|
-
@edges = Set.new
|
52
|
-
@root_vertices = {}
|
53
46
|
end
|
54
47
|
|
55
48
|
# Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
|
56
|
-
#
|
49
|
+
# are properly copied.
|
57
50
|
def initialize_copy(other)
|
58
51
|
super
|
59
|
-
@vertices =
|
60
|
-
|
61
|
-
|
52
|
+
@vertices = {}
|
53
|
+
traverse = lambda do |new_v, old_v|
|
54
|
+
return if new_v.outgoing_edges.size == old_v.outgoing_edges.size
|
55
|
+
old_v.outgoing_edges.each do |edge|
|
56
|
+
destination = add_vertex(edge.destination.name, edge.destination.payload)
|
57
|
+
add_edge_no_circular(new_v, destination, edge.requirement)
|
58
|
+
traverse.call(destination, edge.destination)
|
62
59
|
end
|
63
60
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
vertex_named(edge.destination.name),
|
69
|
-
edge.requirements.dup
|
70
|
-
)
|
61
|
+
other.vertices.each do |name, vertex|
|
62
|
+
new_vertex = add_vertex(name, vertex.payload, vertex.root?)
|
63
|
+
new_vertex.explicit_requirements.replace(vertex.explicit_requirements)
|
64
|
+
traverse.call(new_vertex, vertex)
|
71
65
|
end
|
72
66
|
end
|
73
67
|
|
@@ -80,7 +74,12 @@ module Gem::Resolver::Molinillo
|
|
80
74
|
# by a recursive traversal of each {#root_vertices} and its
|
81
75
|
# {Vertex#successors}
|
82
76
|
def ==(other)
|
83
|
-
|
77
|
+
return false unless other
|
78
|
+
vertices.each do |name, vertex|
|
79
|
+
other_vertex = other.vertex_named(name)
|
80
|
+
return false unless other_vertex
|
81
|
+
return false unless other_vertex.successors.map(&:name).to_set == vertex.successors.map(&:name).to_set
|
82
|
+
end
|
84
83
|
end
|
85
84
|
|
86
85
|
# @param [String] name
|
@@ -89,15 +88,13 @@ module Gem::Resolver::Molinillo
|
|
89
88
|
# @param [Object] requirement the requirement that is requiring the child
|
90
89
|
# @return [void]
|
91
90
|
def add_child_vertex(name, payload, parent_names, requirement)
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
vertex.payload ||= payload
|
100
|
-
parent_nodes.each do |parent_node|
|
91
|
+
vertex = add_vertex(name, payload)
|
92
|
+
parent_names.each do |parent_name|
|
93
|
+
unless parent_name
|
94
|
+
vertex.root = true
|
95
|
+
next
|
96
|
+
end
|
97
|
+
parent_node = vertex_named(parent_name)
|
101
98
|
add_edge(parent_node, vertex, requirement)
|
102
99
|
end
|
103
100
|
vertex
|
@@ -106,16 +103,11 @@ module Gem::Resolver::Molinillo
|
|
106
103
|
# @param [String] name
|
107
104
|
# @param [Object] payload
|
108
105
|
# @return [Vertex] the vertex that was added to `self`
|
109
|
-
def add_vertex(name, payload)
|
110
|
-
vertex = vertices[name] ||= Vertex.new(
|
111
|
-
vertex.
|
112
|
-
|
113
|
-
|
114
|
-
# @param [String] name
|
115
|
-
# @param [Object] payload
|
116
|
-
# @return [Vertex] the vertex that was added to `self`
|
117
|
-
def add_root_vertex(name, payload)
|
118
|
-
add_vertex(name, payload).tap { |v| root_vertices[name] = v }
|
106
|
+
def add_vertex(name, payload, root = false)
|
107
|
+
vertex = vertices[name] ||= Vertex.new(name, payload)
|
108
|
+
vertex.payload ||= payload
|
109
|
+
vertex.root ||= root
|
110
|
+
vertex
|
119
111
|
end
|
120
112
|
|
121
113
|
# Detaches the {#vertex_named} `name` {Vertex} from the graph, recursively
|
@@ -123,12 +115,12 @@ module Gem::Resolver::Molinillo
|
|
123
115
|
# @param [String] name
|
124
116
|
# @return [void]
|
125
117
|
def detach_vertex_named(name)
|
126
|
-
vertex =
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
118
|
+
return unless vertex = vertices.delete(name)
|
119
|
+
vertex.outgoing_edges.each do |e|
|
120
|
+
v = e.destination
|
121
|
+
v.incoming_edges.delete(e)
|
122
|
+
detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
|
123
|
+
end
|
132
124
|
end
|
133
125
|
|
134
126
|
# @param [String] name
|
@@ -140,7 +132,8 @@ module Gem::Resolver::Molinillo
|
|
140
132
|
# @param [String] name
|
141
133
|
# @return [Vertex,nil] the root vertex with the given name
|
142
134
|
def root_vertex_named(name)
|
143
|
-
|
135
|
+
vertex = vertex_named(name)
|
136
|
+
vertex if vertex && vertex.root?
|
144
137
|
end
|
145
138
|
|
146
139
|
# Adds a new {Edge} to the dependency graph
|
@@ -149,18 +142,24 @@ module Gem::Resolver::Molinillo
|
|
149
142
|
# @param [Object] requirement the requirement that this edge represents
|
150
143
|
# @return [Edge] the added edge
|
151
144
|
def add_edge(origin, destination, requirement)
|
152
|
-
if
|
145
|
+
if destination.path_to?(origin)
|
153
146
|
raise CircularDependencyError.new([origin, destination])
|
154
147
|
end
|
155
|
-
|
148
|
+
add_edge_no_circular(origin, destination, requirement)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def add_edge_no_circular(origin, destination, requirement)
|
154
|
+
edge = Edge.new(origin, destination, requirement)
|
155
|
+
origin.outgoing_edges << edge
|
156
|
+
destination.incoming_edges << edge
|
157
|
+
edge
|
156
158
|
end
|
157
159
|
|
158
160
|
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
|
159
161
|
# {#payload}
|
160
162
|
class Vertex
|
161
|
-
# @return [DependencyGraph] the graph this vertex is a node of
|
162
|
-
attr_accessor :graph
|
163
|
-
|
164
163
|
# @return [String] the name of the vertex
|
165
164
|
attr_accessor :name
|
166
165
|
|
@@ -171,50 +170,62 @@ module Gem::Resolver::Molinillo
|
|
171
170
|
# this vertex
|
172
171
|
attr_reader :explicit_requirements
|
173
172
|
|
174
|
-
# @
|
173
|
+
# @return [Boolean] whether the vertex is considered a root vertex
|
174
|
+
attr_accessor :root
|
175
|
+
alias_method :root?, :root
|
176
|
+
|
175
177
|
# @param [String] name see {#name}
|
176
178
|
# @param [Object] payload see {#payload}
|
177
|
-
def initialize(
|
178
|
-
@graph = graph
|
179
|
+
def initialize(name, payload)
|
179
180
|
@name = name
|
180
181
|
@payload = payload
|
181
182
|
@explicit_requirements = []
|
183
|
+
@outgoing_edges = []
|
184
|
+
@incoming_edges = []
|
182
185
|
end
|
183
186
|
|
184
187
|
# @return [Array<Object>] all of the requirements that required
|
185
188
|
# this vertex
|
186
189
|
def requirements
|
187
|
-
incoming_edges.map(&:
|
190
|
+
incoming_edges.map(&:requirement) + explicit_requirements
|
188
191
|
end
|
189
192
|
|
190
193
|
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
191
194
|
# {Edge#origin}
|
192
|
-
|
193
|
-
graph.edges.select { |e| e.origin.shallow_eql?(self) }
|
194
|
-
end
|
195
|
+
attr_accessor :outgoing_edges
|
195
196
|
|
196
197
|
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
197
198
|
# {Edge#destination}
|
198
|
-
|
199
|
-
graph.edges.select { |e| e.destination.shallow_eql?(self) }
|
200
|
-
end
|
199
|
+
attr_accessor :incoming_edges
|
201
200
|
|
202
|
-
# @return [
|
201
|
+
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
203
202
|
# `self` as their {Edge#destination}
|
204
203
|
def predecessors
|
205
|
-
incoming_edges.map(&:origin)
|
204
|
+
incoming_edges.map(&:origin)
|
205
|
+
end
|
206
|
+
|
207
|
+
# @return [Array<Vertex>] the vertices of {#graph} where `self` is a
|
208
|
+
# {#descendent?}
|
209
|
+
def recursive_predecessors
|
210
|
+
vertices = predecessors
|
211
|
+
vertices += vertices.map(&:recursive_predecessors).flatten(1)
|
212
|
+
vertices.uniq!
|
213
|
+
vertices
|
206
214
|
end
|
207
215
|
|
208
|
-
# @return [
|
216
|
+
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
|
209
217
|
# `self` as their {Edge#origin}
|
210
218
|
def successors
|
211
|
-
outgoing_edges.map(&:destination)
|
219
|
+
outgoing_edges.map(&:destination)
|
212
220
|
end
|
213
221
|
|
214
|
-
# @return [
|
222
|
+
# @return [Array<Vertex>] the vertices of {#graph} where `self` is an
|
215
223
|
# {#ancestor?}
|
216
224
|
def recursive_successors
|
217
|
-
|
225
|
+
vertices = successors
|
226
|
+
vertices += vertices.map(&:recursive_successors).flatten(1)
|
227
|
+
vertices.uniq!
|
228
|
+
vertices
|
218
229
|
end
|
219
230
|
|
220
231
|
# @return [String] a string suitable for debugging
|
@@ -226,7 +237,7 @@ module Gem::Resolver::Molinillo
|
|
226
237
|
# by a recursive traversal of each {Vertex#successors}
|
227
238
|
def ==(other)
|
228
239
|
shallow_eql?(other) &&
|
229
|
-
successors == other.successors
|
240
|
+
successors.to_set == other.successors.to_set
|
230
241
|
end
|
231
242
|
|
232
243
|
# @return [Boolean] whether the two vertices are equal, determined
|
@@ -248,7 +259,7 @@ module Gem::Resolver::Molinillo
|
|
248
259
|
# dependency graph?
|
249
260
|
# @return true iff there is a path following edges within this {#graph}
|
250
261
|
def path_to?(other)
|
251
|
-
|
262
|
+
equal?(other) || successors.any? { |v| v.path_to?(other) }
|
252
263
|
end
|
253
264
|
|
254
265
|
alias_method :descendent?, :path_to?
|
@@ -257,7 +268,7 @@ module Gem::Resolver::Molinillo
|
|
257
268
|
# dependency graph?
|
258
269
|
# @return true iff there is a path following edges within this {#graph}
|
259
270
|
def ancestor?(other)
|
260
|
-
|
271
|
+
other.path_to?(self)
|
261
272
|
end
|
262
273
|
|
263
274
|
alias_method :is_reachable_from?, :ancestor?
|