molinillo 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/molinillo/dependency_graph.rb +23 -1
- data/lib/molinillo/gem_metadata.rb +1 -1
- data/lib/molinillo/modules/ui.rb +1 -2
- data/lib/molinillo/resolution.rb +73 -14
- data/spec/spec_helper/index.rb +5 -4
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59b5cd0ec4345cc73a54775616b40161fb2af5a4
|
4
|
+
data.tar.gz: d38ad81fd35dcb0cc20a05005f5945c51c22b041
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ef9ce46b630677f9ad68fe2861be96bce9a90e66e12e065f75387ed01cf50c6200e8bb79128abec09a4a56f5fd11ab5f47d1e7eb3754549c6f2fd7cd3c4ca3e
|
7
|
+
data.tar.gz: 731564965a432a6b80a74ccc312936e43c1b3ad11f8be2f322eee01e8ce3d831c91979139b079436b20bd072d52640420356c9a6db095f4582d5a514bd25485d
|
@@ -1,14 +1,36 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'tsort'
|
2
3
|
|
3
4
|
module Molinillo
|
4
5
|
# A directed acyclic graph that is tuned to hold named dependencies
|
5
6
|
class DependencyGraph
|
6
7
|
include Enumerable
|
7
8
|
|
9
|
+
# Enumerates through the vertices of the graph.
|
10
|
+
# @return [Array<Vertex>] The graph's vertices.
|
8
11
|
def each
|
9
12
|
vertices.values.each { |v| yield v }
|
10
13
|
end
|
11
14
|
|
15
|
+
include TSort
|
16
|
+
|
17
|
+
alias_method :tsort_each_node, :each
|
18
|
+
|
19
|
+
def tsort_each_child(vertex, &block)
|
20
|
+
vertex.successors.each(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Topologically sorts the given vertices.
|
24
|
+
# @param [Enumerable<Vertex>] vertices the vertices to be sorted, which must
|
25
|
+
# all belong to the same graph.
|
26
|
+
# @return [Array<Vertex>] The sorted vertices.
|
27
|
+
def self.tsort(vertices)
|
28
|
+
TSort.tsort(
|
29
|
+
lambda { |b| vertices.each(&b) },
|
30
|
+
lambda { |v, &b| (v.successors & vertices).each(&b) }
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
12
34
|
# A directed edge of a {DependencyGraph}
|
13
35
|
# @attr [Vertex] origin The origin of the directed edge
|
14
36
|
# @attr [Vertex] destination The destination of the directed edge
|
@@ -162,7 +184,7 @@ module Molinillo
|
|
162
184
|
# @return [Array<Object>] all of the requirements that required
|
163
185
|
# this vertex
|
164
186
|
def requirements
|
165
|
-
incoming_edges.
|
187
|
+
incoming_edges.map(&:requirements).flatten + explicit_requirements
|
166
188
|
end
|
167
189
|
|
168
190
|
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
|
data/lib/molinillo/modules/ui.rb
CHANGED
@@ -40,7 +40,6 @@ module Molinillo
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# Conveys debug information to the user.
|
43
|
-
# By default, prints to `STDERR` instead of {#output}.
|
44
43
|
#
|
45
44
|
# @param [Integer] depth the current depth of the resolution process.
|
46
45
|
# @return [void]
|
@@ -48,7 +47,7 @@ module Molinillo
|
|
48
47
|
if debug?
|
49
48
|
debug_info = yield
|
50
49
|
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
51
|
-
|
50
|
+
output.puts debug_info.split("\n").map { |s| ' ' * depth + s }
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
data/lib/molinillo/resolution.rb
CHANGED
@@ -9,11 +9,16 @@ module Molinillo
|
|
9
9
|
# the {#possibility}
|
10
10
|
# @attr [Object] possibility the spec that was unable to be activated due
|
11
11
|
# to a conflict
|
12
|
+
# @attr [Object] locked_requirement the relevant locking requirement.
|
13
|
+
# @attr [Array<Array<Object>>] requirement_trees the different requirement
|
14
|
+
# trees that led to every requirement for the conflicting name.
|
12
15
|
Conflict = Struct.new(
|
13
16
|
:requirement,
|
14
17
|
:requirements,
|
15
18
|
:existing,
|
16
|
-
:possibility
|
19
|
+
:possibility,
|
20
|
+
:locked_requirement,
|
21
|
+
:requirement_trees
|
17
22
|
)
|
18
23
|
|
19
24
|
# @return [SpecificationProvider] the provider that knows about
|
@@ -176,8 +181,7 @@ module Molinillo
|
|
176
181
|
def unwind_for_conflict
|
177
182
|
debug(depth) { "Unwinding for conflict: #{requirement}" }
|
178
183
|
conflicts.tap do |c|
|
179
|
-
states.slice!(state_index_for_unwind..-1)
|
180
|
-
states.pop if state
|
184
|
+
states.slice!((state_index_for_unwind + 1)..-1)
|
181
185
|
raise VersionConflict.new(c) unless state
|
182
186
|
state.conflicts = c
|
183
187
|
end
|
@@ -186,22 +190,58 @@ module Molinillo
|
|
186
190
|
# @return [Integer] The index to which the resolution should unwind in the
|
187
191
|
# case of conflict.
|
188
192
|
def state_index_for_unwind
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
)
|
193
|
+
current_requirement = requirement
|
194
|
+
existing_requirement = requirement_for_existing_name(name)
|
195
|
+
until current_requirement.nil?
|
196
|
+
current_state = find_state_for(current_requirement)
|
197
|
+
return states.index(current_state) if state_any?(current_state)
|
198
|
+
current_requirement = parent_of(current_requirement)
|
196
199
|
end
|
197
|
-
|
200
|
+
|
201
|
+
until existing_requirement.nil?
|
202
|
+
existing_state = find_state_for(existing_requirement)
|
203
|
+
return states.index(existing_state) if state_any?(existing_state)
|
204
|
+
existing_requirement = parent_of(existing_requirement)
|
205
|
+
end
|
206
|
+
-1
|
207
|
+
end
|
208
|
+
|
209
|
+
# @return [Object] the requirement that led to `requirement` being added
|
210
|
+
# to the list of requirements.
|
211
|
+
def parent_of(requirement)
|
212
|
+
return nil unless requirement
|
213
|
+
seen = false
|
214
|
+
state = states.reverse_each.find do |s|
|
215
|
+
seen ||= s.requirement == requirement
|
216
|
+
seen && s.requirement != requirement && !s.requirements.include?(requirement)
|
217
|
+
end
|
218
|
+
state && state.requirement
|
219
|
+
end
|
220
|
+
|
221
|
+
# @return [Object] the requirement that led to a version of a possibility
|
222
|
+
# with the given name being activated.
|
223
|
+
def requirement_for_existing_name(name)
|
224
|
+
return nil unless activated.vertex_named(name).payload
|
225
|
+
states.reverse_each.find { |s| !s.activated.vertex_named(name).payload }.requirement
|
226
|
+
end
|
227
|
+
|
228
|
+
# @return [ResolutionState] the state whose `requirement` is the given
|
229
|
+
# `requirement`.
|
230
|
+
def find_state_for(requirement)
|
231
|
+
return nil unless requirement
|
232
|
+
states.find { |i| requirement == i.requirement }
|
233
|
+
end
|
234
|
+
|
235
|
+
# @return [Boolean] whether or not the given state has any possibilities
|
236
|
+
# left.
|
237
|
+
def state_any?(state)
|
238
|
+
state && state.possibilities.any?
|
198
239
|
end
|
199
240
|
|
200
241
|
# @return [Conflict] a {Conflict} that reflects the failure to activate
|
201
242
|
# the {#possibility} in conjunction with the current {#state}
|
202
243
|
def create_conflict
|
203
244
|
vertex = activated.vertex_named(name)
|
204
|
-
existing = vertex.payload
|
205
245
|
requirements = {
|
206
246
|
name_for_explicit_dependency_source => vertex.explicit_requirements,
|
207
247
|
name_for_locking_dependency_source => Array(locked_requirement_named(name)),
|
@@ -210,11 +250,30 @@ module Molinillo
|
|
210
250
|
conflicts[name] = Conflict.new(
|
211
251
|
requirement,
|
212
252
|
Hash[requirements.select { |_, r| !r.empty? }],
|
213
|
-
|
214
|
-
possibility
|
253
|
+
vertex.payload,
|
254
|
+
possibility,
|
255
|
+
locked_requirement_named(name),
|
256
|
+
requirement_trees
|
215
257
|
)
|
216
258
|
end
|
217
259
|
|
260
|
+
# @return [Array<Array<Object>>] The different requirement
|
261
|
+
# trees that led to every requirement for the current spec.
|
262
|
+
def requirement_trees
|
263
|
+
activated.vertex_named(name).requirements.map { |r| requirement_tree_for(r) }
|
264
|
+
end
|
265
|
+
|
266
|
+
# @return [Array<Object>] the list of requirements that led to
|
267
|
+
# `requirement` being required.
|
268
|
+
def requirement_tree_for(requirement)
|
269
|
+
tree = []
|
270
|
+
while requirement
|
271
|
+
tree.unshift(requirement)
|
272
|
+
requirement = parent_of(requirement)
|
273
|
+
end
|
274
|
+
tree
|
275
|
+
end
|
276
|
+
|
218
277
|
# Indicates progress roughly once every second
|
219
278
|
# @return [void]
|
220
279
|
def indicate_progress
|
data/spec/spec_helper/index.rb
CHANGED
@@ -7,7 +7,7 @@ module Molinillo
|
|
7
7
|
File.open(FIXTURE_INDEX_DIR + (fixture_name + '.json'), 'r') do |fixture|
|
8
8
|
self.specs = JSON.load(fixture).reduce(Hash.new([])) do |specs_by_name, (name, versions)|
|
9
9
|
specs_by_name.tap do |specs|
|
10
|
-
specs[name] = versions.map { |s| TestSpecification.new s }.
|
10
|
+
specs[name] = versions.map { |s| TestSpecification.new s }.sort_by(&:version)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -24,8 +24,9 @@ module Molinillo
|
|
24
24
|
|
25
25
|
def search_for(dependency)
|
26
26
|
pre_release = dependency_pre_release?(dependency)
|
27
|
-
specs[dependency.name].
|
28
|
-
pre_release ?
|
27
|
+
specs[dependency.name].select do |spec|
|
28
|
+
(pre_release ? true : !spec.version.pre_release?) &&
|
29
|
+
dependency.satisfied_by?(spec.version)
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
@@ -43,7 +44,7 @@ module Molinillo
|
|
43
44
|
activated.vertex_named(d.name).payload ? 0 : 1,
|
44
45
|
dependency_pre_release?(d) ? 0 : 1,
|
45
46
|
conflicts[d.name] ? 0 : 1,
|
46
|
-
|
47
|
+
activated.vertex_named(d.name).payload ? 0 : search_for(d).count,
|
47
48
|
]
|
48
49
|
end
|
49
50
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: molinillo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel E. Giddins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description:
|
@@ -45,9 +45,6 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- LICENSE
|
49
|
-
- README.md
|
50
|
-
- lib/molinillo.rb
|
51
48
|
- lib/molinillo/dependency_graph.rb
|
52
49
|
- lib/molinillo/errors.rb
|
53
50
|
- lib/molinillo/gem_metadata.rb
|
@@ -56,12 +53,15 @@ files:
|
|
56
53
|
- lib/molinillo/resolution.rb
|
57
54
|
- lib/molinillo/resolver.rb
|
58
55
|
- lib/molinillo/state.rb
|
56
|
+
- lib/molinillo.rb
|
57
|
+
- README.md
|
58
|
+
- LICENSE
|
59
59
|
- spec/dependency_graph_spec.rb
|
60
60
|
- spec/resolver_spec.rb
|
61
|
-
- spec/spec_helper.rb
|
62
61
|
- spec/spec_helper/index.rb
|
63
62
|
- spec/spec_helper/specification.rb
|
64
63
|
- spec/spec_helper/ui.rb
|
64
|
+
- spec/spec_helper.rb
|
65
65
|
- spec/state_spec.rb
|
66
66
|
homepage: https://github.com/CocoaPods/Molinillo
|
67
67
|
licenses:
|
@@ -73,17 +73,17 @@ require_paths:
|
|
73
73
|
- lib
|
74
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
75
75
|
requirements:
|
76
|
-
- -
|
76
|
+
- - '>='
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: '0'
|
79
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - '>='
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
requirements: []
|
85
85
|
rubyforge_project:
|
86
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.0.14
|
87
87
|
signing_key:
|
88
88
|
specification_version: 4
|
89
89
|
summary: Provides support for dependency resolution
|