rubygems-update 2.5.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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?
|