molinillo 0.1.2 → 0.2.0
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.
- 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
|