molinillo 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5b31401d705c0bd1b9839f3b560996af5339a632
4
- data.tar.gz: daabc784cc8a0385da64f2befa949887c70e3502
2
+ SHA256:
3
+ metadata.gz: e6828b175f84c2dae7fadfaf7c614a3a6198089a11f0e2c20defc697b1108e2b
4
+ data.tar.gz: b4e8a71693257b7726be5c21fee26571197b0cd69b1445bb51107aad984b0e89
5
5
  SHA512:
6
- metadata.gz: 139afb59678e775ae0e93214dfa78e13f1da4b4e73a42b514ab696818cfa00947e57b16a01b4582dbbc2563c222166c3779e032e899244cebf95f4573259ee7b
7
- data.tar.gz: 708818cffc500e0f686a51e6025d254150408e206d48e176b5fa97d6466bd8efcf3897ab6fc4f21602197e5c1ac56b5f623b796617741451be77f5d182126ca0
6
+ metadata.gz: 67df28dfe97c6a0b66d96df61e543fa917de1bd63e2ffa169d8499f62940722a72629b37fe1c7a8db4408d7dfbfc8d718ceac09956a5160c875d74db23ab15cf
7
+ data.tar.gz: d750b24f9a1dd5a4a2a846f00c1ef0f6e05fdff166266a9427c9918254ff991c8bc0fb7fae861ec172ac0a305942981d0c991932a282522e2bb0eb7c981a1b13
@@ -33,7 +33,7 @@ This stack-based approach is used because backtracking (also known as *unwinding
33
33
  13. If there is an existing, `activated` vertex for the dependency, `attempt_to_filter_existing_spec`
34
34
  - This filters the contents of the existing vertex's `PossibilitySet` by the current state's `requirement`
35
35
  - If any possibilities remain within the `PossibilitySet`, it updates the activated vertex's payload with the new, filtered state and pushes a new `DependencyState`
36
- - If no possibilities remain within the `PossibilitySet` after filtering, or if the current state's `PossibilitySet` had a different set of sub-dependecy requirements to the existing vertex's `PossibilitySet`, `create_conflict` and `unwind_for_conflict`, back to the last `DependencyState` that has a chance to not generate a conflict. Go to #6
36
+ - If no possibilities remain within the `PossibilitySet` after filtering, or if the current state's `PossibilitySet` had a different set of sub-dependency requirements to the existing vertex's `PossibilitySet`, `create_conflict` and `unwind_for_conflict`, back to the last `DependencyState` that has a chance to not generate a conflict. Go to #6
37
37
  15. Terminate with the topmost state's dependency graph when there are no more requirements left
38
38
  16. For each vertex with a payload of allowable versions for this resolution (i.e., a `PossibilitySet`), pick a single specific version.
39
39
 
@@ -52,7 +52,7 @@ the previous unwinds that have determined our current state.
52
52
  1. First, consider the current conflict as follows:
53
53
  - Find the earliest (lowest index) set of requirements which combine to cause
54
54
  the conflict. Any non-binding requirements can be ignored, as removing them
55
- would not resolve the current onflict
55
+ would not resolve the current conflict
56
56
  - For each binding requirement, find all the alternative possibilities that
57
57
  would relax the requirement:
58
58
  - the requirement's DependencyState might have alternative possibilities
@@ -79,7 +79,7 @@ different, smaller unwind was chosen instead):
79
79
  error as resolution is not possible.
80
80
  3b. Filter the state that we're unwinding to, in order to remove any
81
81
  possibilities we know will result in a conflict. Consider all possible unwinds
82
- to the chosen state (there may be several, amasssed from previous unused
82
+ to the chosen state (there may be several, amassed from previous unused
83
83
  unwinds for different conflicts) when doing this filtering - only
84
84
  possibilities that will certainly result in *all* of those conflicts can be
85
85
  filtered out as having no chance of resolution
@@ -1,5 +1,83 @@
1
1
  # Molinillo Changelog
2
2
 
3
+ ## 0.7.0 (2020-10-21)
4
+
5
+ ##### Breaking
6
+
7
+ * Support for Ruby 1.8.7 and 1.9.3 has been dropped, the minimum supported
8
+ Ruby version is now 2.0.
9
+ [Samuel Giddins](https://github.com/segiddins)
10
+
11
+ ##### Enhancements
12
+
13
+ * Circular dependency errors include the full (shortest) path between the
14
+ circularly-dependent vertices.
15
+ [Samuel Giddins](https://github.com/segiddins)
16
+
17
+ ##### Bug Fixes
18
+
19
+ * None.
20
+
21
+
22
+ ## 0.6.6 (2018-08-07)
23
+
24
+ ##### Enhancements
25
+
26
+ * Improve performance of `Vertex#path_to?`.
27
+ [Samuel Giddins](https://github.com/segiddins)
28
+
29
+ * Allow customization of string used to say that a version conflict has occurred
30
+ for a particular name by passing in the `:incompatible_version_message_for_conflict`
31
+ key when constructing a version conflict message with trees.
32
+ [Samuel Giddins](https://github.com/segiddins)
33
+
34
+ ##### Bug Fixes
35
+
36
+ * None.
37
+
38
+
39
+ ## 0.6.5 (2018-03-22)
40
+
41
+ ##### Enhancements
42
+
43
+ * Improve performance of recursive vertex methods.
44
+ [Samuel Giddins](https://github.com/segiddins)
45
+
46
+ ##### Bug Fixes
47
+
48
+ * None.
49
+
50
+
51
+ ## 0.6.4 (2017-10-29)
52
+
53
+ ##### Enhancements
54
+
55
+ * Reduce memory usage during resolution by making the `Vertex#requirements`
56
+ array unique.
57
+ [Grey Baker](https://github.com/greysteil)
58
+ [Jan Krutisch](https://github.com/halfbyte)
59
+
60
+ ##### Bug Fixes
61
+
62
+ * None.
63
+
64
+
65
+ ## 0.6.3 (2017-09-06)
66
+
67
+ ##### Enhancements
68
+
69
+ * None.
70
+
71
+ ##### Bug Fixes
72
+
73
+ * Handle the case where an unwind occurs to a requirement that directly caused
74
+ the current conflict but could also have been unwound to directly from
75
+ previous conflicts. In this case, filtering must not remove any possibilities
76
+ that could have avoided the previous conflicts (even if they would not avoid
77
+ the current one).
78
+ [Grey Baker](https://github.com/greysteil)
79
+
80
+
3
81
  ## 0.6.2 (2017-08-25)
4
82
 
5
83
  ##### Enhancements
data/README.md CHANGED
@@ -28,8 +28,7 @@ $ gem install molinillo
28
28
 
29
29
  ## Usage
30
30
 
31
- See the [ARCHITECTURE](ARCHITECTURE.md) file for an overview and look at the test suite for example usage. Better documentation and examples are
32
- forthcoming.
31
+ See the [ARCHITECTURE](ARCHITECTURE.md) file for an overview and look at the test suite for example usage.
33
32
 
34
33
  ## Contributing
35
34
 
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/compatibility'
4
- require 'molinillo/gem_metadata'
5
- require 'molinillo/errors'
6
- require 'molinillo/resolver'
7
- require 'molinillo/modules/ui'
8
- require 'molinillo/modules/specification_provider'
3
+ require_relative 'molinillo/gem_metadata'
4
+ require_relative 'molinillo/errors'
5
+ require_relative 'molinillo/resolver'
6
+ require_relative 'molinillo/modules/ui'
7
+ require_relative 'molinillo/modules/specification_provider'
9
8
 
10
9
  # Molinillo is a generic dependency resolution algorithm.
11
10
  module Molinillo
@@ -3,8 +3,8 @@
3
3
  require 'set'
4
4
  require 'tsort'
5
5
 
6
- require 'molinillo/dependency_graph/log'
7
- require 'molinillo/dependency_graph/vertex'
6
+ require_relative 'dependency_graph/log'
7
+ require_relative 'dependency_graph/vertex'
8
8
 
9
9
  module Molinillo
10
10
  # A directed acyclic graph that is tuned to hold named dependencies
@@ -124,6 +124,7 @@ module Molinillo
124
124
  dot.join("\n")
125
125
  end
126
126
 
127
+ # @param [DependencyGraph] other
127
128
  # @return [Boolean] whether the two dependency graphs are equal, determined
128
129
  # by a recursive traversal of each {#root_vertices} and its
129
130
  # {Vertex#successors}
@@ -190,7 +191,7 @@ module Molinillo
190
191
  # @return [Edge] the added edge
191
192
  def add_edge(origin, destination, requirement)
192
193
  if destination.path_to?(origin)
193
- raise CircularDependencyError.new([origin, destination])
194
+ raise CircularDependencyError.new(path(destination, origin))
194
195
  end
195
196
  add_edge_no_circular(origin, destination, requirement)
196
197
  end
@@ -219,5 +220,37 @@ module Molinillo
219
220
  def add_edge_no_circular(origin, destination, requirement)
220
221
  log.add_edge_no_circular(self, origin.name, destination.name, requirement)
221
222
  end
223
+
224
+ # Returns the path between two vertices
225
+ # @raise [ArgumentError] if there is no path between the vertices
226
+ # @param [Vertex] from
227
+ # @param [Vertex] to
228
+ # @return [Array<Vertex>] the shortest path from `from` to `to`
229
+ def path(from, to)
230
+ distances = Hash.new(vertices.size + 1)
231
+ distances[from.name] = 0
232
+ predecessors = {}
233
+ each do |vertex|
234
+ vertex.successors.each do |successor|
235
+ if distances[successor.name] > distances[vertex.name] + 1
236
+ distances[successor.name] = distances[vertex.name] + 1
237
+ predecessors[successor] = vertex
238
+ end
239
+ end
240
+ end
241
+
242
+ path = [to]
243
+ while before = predecessors[to]
244
+ path << before
245
+ to = before
246
+ break if to == from
247
+ end
248
+
249
+ unless path.last.equal?(from)
250
+ raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
251
+ end
252
+
253
+ path.reverse
254
+ end
222
255
  end
223
256
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/add_edge_no_circular'
4
- require 'molinillo/dependency_graph/add_vertex'
5
- require 'molinillo/dependency_graph/delete_edge'
6
- require 'molinillo/dependency_graph/detach_vertex_named'
7
- require 'molinillo/dependency_graph/set_payload'
8
- require 'molinillo/dependency_graph/tag'
3
+ require_relative 'add_edge_no_circular'
4
+ require_relative 'add_vertex'
5
+ require_relative 'delete_edge'
6
+ require_relative 'detach_vertex_named'
7
+ require_relative 'set_payload'
8
+ require_relative 'tag'
9
9
 
10
10
  module Molinillo
11
11
  class DependencyGraph
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph/action'
3
+ require_relative 'action'
4
4
  module Molinillo
5
5
  class DependencyGraph
6
6
  # @!visibility private
@@ -14,11 +14,11 @@ module Molinillo
14
14
  end
15
15
 
16
16
  # (see Action#up)
17
- def up(_graph)
17
+ def up(graph)
18
18
  end
19
19
 
20
20
  # (see Action#down)
21
- def down(_graph)
21
+ def down(graph)
22
22
  end
23
23
 
24
24
  # @!group Tag
@@ -33,7 +33,7 @@ module Molinillo
33
33
  # @return [Array<Object>] all of the requirements that required
34
34
  # this vertex
35
35
  def requirements
36
- incoming_edges.map(&:requirement) + explicit_requirements
36
+ (incoming_edges.map(&:requirement) + explicit_requirements).uniq
37
37
  end
38
38
 
39
39
  # @return [Array<Edge>] the edges of {#graph} that have `self` as their
@@ -50,14 +50,25 @@ module Molinillo
50
50
  incoming_edges.map(&:origin)
51
51
  end
52
52
 
53
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
53
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
54
54
  # {#descendent?}
55
55
  def recursive_predecessors
56
- vertices = predecessors
57
- vertices += Compatibility.flat_map(vertices, &:recursive_predecessors)
58
- vertices.uniq!
56
+ _recursive_predecessors
57
+ end
58
+
59
+ # @param [Set<Vertex>] vertices the set to add the predecessors to
60
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is a
61
+ # {#descendent?}
62
+ def _recursive_predecessors(vertices = Set.new)
63
+ incoming_edges.each do |edge|
64
+ vertex = edge.origin
65
+ next unless vertices.add?(vertex)
66
+ vertex._recursive_predecessors(vertices)
67
+ end
68
+
59
69
  vertices
60
70
  end
71
+ protected :_recursive_predecessors
61
72
 
62
73
  # @return [Array<Vertex>] the vertices of {#graph} that have an edge with
63
74
  # `self` as their {Edge#origin}
@@ -65,14 +76,25 @@ module Molinillo
65
76
  outgoing_edges.map(&:destination)
66
77
  end
67
78
 
68
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
79
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
69
80
  # {#ancestor?}
70
81
  def recursive_successors
71
- vertices = successors
72
- vertices += Compatibility.flat_map(vertices, &:recursive_successors)
73
- vertices.uniq!
82
+ _recursive_successors
83
+ end
84
+
85
+ # @param [Set<Vertex>] vertices the set to add the successors to
86
+ # @return [Set<Vertex>] the vertices of {#graph} where `self` is an
87
+ # {#ancestor?}
88
+ def _recursive_successors(vertices = Set.new)
89
+ outgoing_edges.each do |edge|
90
+ vertex = edge.destination
91
+ next unless vertices.add?(vertex)
92
+ vertex._recursive_successors(vertices)
93
+ end
94
+
74
95
  vertices
75
96
  end
97
+ protected :_recursive_successors
76
98
 
77
99
  # @return [String] a string suitable for debugging
78
100
  def inspect
@@ -108,11 +130,21 @@ module Molinillo
108
130
  # dependency graph?
109
131
  # @return true iff there is a path following edges within this {#graph}
110
132
  def path_to?(other)
111
- equal?(other) || successors.any? { |v| v.path_to?(other) }
133
+ _path_to?(other)
112
134
  end
113
135
 
114
136
  alias descendent? path_to?
115
137
 
138
+ # @param [Vertex] other the vertex to check if there's a path to
139
+ # @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
140
+ # @return [Boolean] whether there is a path to `other` from `self`
141
+ def _path_to?(other, visited = Set.new)
142
+ return false unless visited.add?(self)
143
+ return true if equal?(other)
144
+ successors.any? { |v| v._path_to?(other, visited) }
145
+ end
146
+ protected :_path_to?
147
+
116
148
  # Is there a path from `other` to `self` following edges in the
117
149
  # dependency graph?
118
150
  # @return true iff there is a path following edges within this {#graph}
@@ -18,7 +18,7 @@ module Molinillo
18
18
  # @param [Array<Object>] required_by @see {#required_by}
19
19
  def initialize(dependency, required_by = [])
20
20
  @dependency = dependency
21
- @required_by = required_by
21
+ @required_by = required_by.uniq
22
22
  super()
23
23
  end
24
24
 
@@ -65,7 +65,7 @@ module Molinillo
65
65
  # @param [SpecificationProvider] specification_provider see {#specification_provider}
66
66
  def initialize(conflicts, specification_provider)
67
67
  pairs = []
68
- Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting|
68
+ conflicts.values.flat_map(&:requirements).each do |conflicting|
69
69
  conflicting.each do |source, conflict_requirements|
70
70
  conflict_requirements.each do |c|
71
71
  pairs << [c, source]
@@ -80,7 +80,7 @@ module Molinillo
80
80
  @specification_provider = specification_provider
81
81
  end
82
82
 
83
- require 'molinillo/delegates/specification_provider'
83
+ require_relative 'delegates/specification_provider'
84
84
  include Delegates::SpecificationProvider
85
85
 
86
86
  # @return [String] An error message that includes requirement trees,
@@ -101,9 +101,14 @@ module Molinillo
101
101
  printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
102
102
  additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
103
103
  version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
104
+ incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
105
+ proc do |name, _conflict|
106
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
107
+ end
108
+ end
104
109
 
105
110
  conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
106
- o << %(\n#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":\n)
111
+ o << "\n" << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
107
112
  if conflict.locked_requirement
108
113
  o << %( In snapshot (#{name_for_locking_dependency_source}):\n)
109
114
  o << %( #{printable_requirement.call(conflict.locked_requirement)}\n)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Molinillo
4
4
  # The version of Molinillo.
5
- VERSION = '0.6.2'.freeze
5
+ VERSION = '0.7.0'.freeze
6
6
  end
@@ -207,7 +207,7 @@ module Molinillo
207
207
  def start_resolution
208
208
  @started_at = Time.now
209
209
 
210
- handle_missing_or_push_dependency_state(initial_state)
210
+ push_initial_state
211
211
 
212
212
  debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
213
213
  resolver_ui.before_resolution
@@ -218,7 +218,7 @@ module Molinillo
218
218
  next unless vertex.payload
219
219
 
220
220
  latest_version = vertex.payload.possibilities.reverse_each.find do |possibility|
221
- vertex.requirements.uniq.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
221
+ vertex.requirements.all? { |req| requirement_satisfied_by?(req, activated, possibility) }
222
222
  end
223
223
 
224
224
  activated.set_payload(vertex.name, latest_version)
@@ -238,11 +238,11 @@ module Molinillo
238
238
  debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
239
239
  end
240
240
 
241
- require 'molinillo/state'
242
- require 'molinillo/modules/specification_provider'
241
+ require_relative 'state'
242
+ require_relative 'modules/specification_provider'
243
243
 
244
- require 'molinillo/delegates/resolution_state'
245
- require 'molinillo/delegates/specification_provider'
244
+ require_relative 'delegates/resolution_state'
245
+ require_relative 'delegates/specification_provider'
246
246
 
247
247
  include Molinillo::Delegates::ResolutionState
248
248
  include Molinillo::Delegates::SpecificationProvider
@@ -273,10 +273,10 @@ module Molinillo
273
273
  states.last
274
274
  end
275
275
 
276
- # Creates the initial state for the resolution, based upon the
276
+ # Creates and pushes the initial state for the resolution, based upon the
277
277
  # {#requested} dependencies
278
- # @return [DependencyState] the initial state for the resolution
279
- def initial_state
278
+ # @return [void]
279
+ def push_initial_state
280
280
  graph = DependencyGraph.new.tap do |dg|
281
281
  original_requested.each do |requested|
282
282
  vertex = dg.add_vertex(name_for(requested), nil, true)
@@ -285,18 +285,7 @@ module Molinillo
285
285
  dg.tag(:initial_state)
286
286
  end
287
287
 
288
- requirements = sort_dependencies(original_requested, graph, {})
289
- initial_requirement = requirements.shift
290
- DependencyState.new(
291
- initial_requirement && name_for(initial_requirement),
292
- requirements,
293
- graph,
294
- initial_requirement,
295
- possibilities_for_requirement(initial_requirement, graph),
296
- 0,
297
- {},
298
- []
299
- )
288
+ push_state_for_requirements(original_requested, true, graph)
300
289
  end
301
290
 
302
291
  # Unwinds the states stack because a conflict has been encountered
@@ -361,7 +350,7 @@ module Molinillo
361
350
  current_detail
362
351
  end
363
352
 
364
- # @param [Array<Object>] array of requirements that combine to create a conflict
353
+ # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
365
354
  # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
366
355
  # of resolving the passed requirements
367
356
  def unwind_options_for_requirements(binding_requirements)
@@ -429,7 +418,7 @@ module Molinillo
429
418
  end
430
419
 
431
420
  # @param [DependencyState] state
432
- # @param [Array] array of requirements
421
+ # @param [Array] binding_requirements array of requirements
433
422
  # @return [Boolean] whether or not the given state has any possibilities
434
423
  # that could satisfy the given requirements
435
424
  def conflict_fixing_possibilities?(state, binding_requirements)
@@ -444,7 +433,8 @@ module Molinillo
444
433
 
445
434
  # Filter's a state's possibilities to remove any that would not fix the
446
435
  # conflict we've just rewound from
447
- # @param [UnwindDetails] details of the conflict just unwound from
436
+ # @param [UnwindDetails] unwind_details details of the conflict just
437
+ # unwound from
448
438
  # @return [void]
449
439
  def filter_possibilities_after_unwind(unwind_details)
450
440
  return unless state && !state.possibilities.empty?
@@ -458,14 +448,18 @@ module Molinillo
458
448
 
459
449
  # Filter's a state's possibilities to remove any that would not satisfy
460
450
  # the requirements in the conflict we've just rewound from
461
- # @param [UnwindDetails] details of the conflict just unwound from
451
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
462
452
  # @return [void]
463
453
  def filter_possibilities_for_primary_unwind(unwind_details)
464
- all_requirements = unwind_details.conflicting_requirements
454
+ unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
455
+ unwinds_to_state << unwind_details
456
+ unwind_requirement_sets = unwinds_to_state.map(&:conflicting_requirements)
465
457
 
466
458
  state.possibilities.reject! do |possibility_set|
467
459
  possibility_set.possibilities.none? do |poss|
468
- possibility_satisfies_requirements?(poss, all_requirements)
460
+ unwind_requirement_sets.any? do |requirements|
461
+ possibility_satisfies_requirements?(poss, requirements)
462
+ end
469
463
  end
470
464
  end
471
465
  end
@@ -487,7 +481,7 @@ module Molinillo
487
481
 
488
482
  # Filter's a state's possibilities to remove any that would (eventually)
489
483
  # create a requirement in the conflict we've just rewound from
490
- # @param [UnwindDetails] details of the conflict just unwound from
484
+ # @param [UnwindDetails] unwind_details details of the conflict just unwound from
491
485
  # @return [void]
492
486
  def filter_possibilities_for_parent_unwind(unwind_details)
493
487
  unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
@@ -496,7 +490,7 @@ module Molinillo
496
490
  primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
497
491
  parent_unwinds = unwinds_to_state.uniq - primary_unwinds
498
492
 
499
- allowed_possibility_sets = Compatibility.flat_map(primary_unwinds) do |unwind|
493
+ allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
500
494
  states[unwind.state_index].possibilities.select do |possibility_set|
501
495
  possibility_set.possibilities.any? do |poss|
502
496
  possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
@@ -504,7 +498,7 @@ module Molinillo
504
498
  end
505
499
  end
506
500
 
507
- requirements_to_avoid = Compatibility.flat_map(parent_unwinds, &:sub_dependencies_to_avoid)
501
+ requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
508
502
 
509
503
  state.possibilities.reject! do |possibility_set|
510
504
  !allowed_possibility_sets.include?(possibility_set) &&
@@ -520,12 +514,12 @@ module Molinillo
520
514
 
521
515
  possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
522
516
 
523
- # When theres a `CircularDependency` error the conflicting requirement
524
- # (the one causing the circular) wont be `conflict.requirement`
525
- # (which wont be for the right state, because we wont have created it,
526
- # because its circular).
527
- # We need to make sure we have that requirement in the conflicts list,
528
- # otherwise we wont be able to unwind properly, so we just return all
517
+ # When there's a `CircularDependency` error the conflicting requirement
518
+ # (the one causing the circular) won't be `conflict.requirement`
519
+ # (which won't be for the right state, because we won't have created it,
520
+ # because it's circular).
521
+ # We need to make sure we have that requirement in the conflict's list,
522
+ # otherwise we won't be able to unwind properly, so we just return all
529
523
  # the requirements for the conflict.
530
524
  return possible_binding_requirements if conflict.underlying_error
531
525
 
@@ -554,8 +548,8 @@ module Molinillo
554
548
  end
555
549
 
556
550
  # @param [Object] requirement we wish to check
557
- # @param [Array] array of requirements
558
- # @param [Array] array of possibilities the requirements will be used to filter
551
+ # @param [Array] possible_binding_requirements array of requirements
552
+ # @param [Array] possibilities array of possibilities the requirements will be used to filter
559
553
  # @return [Boolean] whether or not the given requirement is required to filter
560
554
  # out all elements of the array of possibilities.
561
555
  def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
@@ -564,6 +558,7 @@ module Molinillo
564
558
  end
565
559
  end
566
560
 
561
+ # @param [Object] requirement
567
562
  # @return [Object] the requirement that led to `requirement` being added
568
563
  # to the list of requirements.
569
564
  def parent_of(requirement)
@@ -573,6 +568,7 @@ module Molinillo
573
568
  parent_state.requirement
574
569
  end
575
570
 
571
+ # @param [String] name
576
572
  # @return [Object] the requirement that led to a version of a possibility
577
573
  # with the given name being activated.
578
574
  def requirement_for_existing_name(name)
@@ -581,6 +577,7 @@ module Molinillo
581
577
  states.find { |s| s.name == name }.requirement
582
578
  end
583
579
 
580
+ # @param [Object] requirement
584
581
  # @return [ResolutionState] the state whose `requirement` is the given
585
582
  # `requirement`.
586
583
  def find_state_for(requirement)
@@ -588,6 +585,7 @@ module Molinillo
588
585
  states.find { |i| requirement == i.requirement }
589
586
  end
590
587
 
588
+ # @param [Object] underlying_error
591
589
  # @return [Conflict] a {Conflict} that reflects the failure to activate
592
590
  # the {#possibility} in conjunction with the current {#state}
593
591
  def create_conflict(underlying_error = nil)
@@ -624,6 +622,7 @@ module Molinillo
624
622
  vertex.requirements.map { |r| requirement_tree_for(r) }
625
623
  end
626
624
 
625
+ # @param [Object] requirement
627
626
  # @return [Array<Object>] the list of requirements that led to
628
627
  # `requirement` being required.
629
628
  def requirement_tree_for(requirement)
@@ -669,9 +668,8 @@ module Molinillo
669
668
  attempt_to_filter_existing_spec(existing_vertex)
670
669
  else
671
670
  latest = possibility.latest_version
672
- # use reject!(!satisfied) for 1.8.7 compatibility
673
- possibility.possibilities.reject! do |possibility|
674
- !requirement_satisfied_by?(requirement, activated, possibility)
671
+ possibility.possibilities.select! do |possibility|
672
+ requirement_satisfied_by?(requirement, activated, possibility)
675
673
  end
676
674
  if possibility.latest_version.nil?
677
675
  # ensure there's a possibility for better error messages
@@ -701,7 +699,7 @@ module Molinillo
701
699
 
702
700
  # Generates a filtered version of the existing vertex's `PossibilitySet` using the
703
701
  # current state's `requirement`
704
- # @param [Object] existing vertex
702
+ # @param [Object] vertex existing vertex
705
703
  # @return [PossibilitySet] filtered possibility set
706
704
  def filtered_possibility_set(vertex)
707
705
  PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
@@ -726,7 +724,7 @@ module Molinillo
726
724
  end
727
725
 
728
726
  # Requires the dependencies that the recently activated spec has
729
- # @param [Object] activated_possibility the PossibilitySet that has just been
727
+ # @param [Object] possibility_set the PossibilitySet that has just been
730
728
  # activated
731
729
  # @return [void]
732
730
  def require_nested_dependencies_for(possibility_set)
@@ -745,6 +743,8 @@ module Molinillo
745
743
  # Pushes a new {DependencyState} that encapsulates both existing and new
746
744
  # requirements
747
745
  # @param [Array] new_requirements
746
+ # @param [Boolean] requires_sort
747
+ # @param [Object] new_activated
748
748
  # @return [void]
749
749
  def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
750
750
  new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
@@ -763,7 +763,8 @@ module Molinillo
763
763
 
764
764
  # Checks a proposed requirement with any existing locked requirement
765
765
  # before generating an array of possibilities for it.
766
- # @param [Object] the proposed requirement
766
+ # @param [Object] requirement the proposed requirement
767
+ # @param [Object] activated
767
768
  # @return [Array] possibilities
768
769
  def possibilities_for_requirement(requirement, activated = self.activated)
769
770
  return [] unless requirement
@@ -774,7 +775,8 @@ module Molinillo
774
775
  group_possibilities(search_for(requirement))
775
776
  end
776
777
 
777
- # @param [Object] the proposed requirement
778
+ # @param [Object] requirement the proposed requirement
779
+ # @param [Object] activated
778
780
  # @return [Array] possibility set containing only the locked requirement, if any
779
781
  def locked_requirement_possibility_set(requirement, activated = self.activated)
780
782
  all_possibilities = search_for(requirement)
@@ -793,8 +795,8 @@ module Molinillo
793
795
  # Build an array of PossibilitySets, with each element representing a group of
794
796
  # dependency versions that all have the same sub-dependency version constraints
795
797
  # and are contiguous.
796
- # @param [Array] an array of possibilities
797
- # @return [Array] an array of possibility sets
798
+ # @param [Array] possibilities an array of possibilities
799
+ # @return [Array<PossibilitySet>] an array of possibility sets
798
800
  def group_possibilities(possibilities)
799
801
  possibility_sets = []
800
802
  current_possibility_set = nil
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'molinillo/dependency_graph'
3
+ require_relative 'dependency_graph'
4
4
 
5
5
  module Molinillo
6
6
  # This class encapsulates a dependency resolver.
@@ -9,7 +9,7 @@ module Molinillo
9
9
  #
10
10
  #
11
11
  class Resolver
12
- require 'molinillo/resolution'
12
+ require_relative 'resolution'
13
13
 
14
14
  # @return [SpecificationProvider] the specification provider used
15
15
  # in the resolution process
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: molinillo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel E. Giddins
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-25 00:00:00.000000000 Z
11
+ date: 2020-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description:
41
+ description:
42
42
  email:
43
43
  - segiddins@segiddins.me
44
44
  executables: []
@@ -50,7 +50,6 @@ files:
50
50
  - LICENSE
51
51
  - README.md
52
52
  - lib/molinillo.rb
53
- - lib/molinillo/compatibility.rb
54
53
  - lib/molinillo/delegates/resolution_state.rb
55
54
  - lib/molinillo/delegates/specification_provider.rb
56
55
  - lib/molinillo/dependency_graph.rb
@@ -74,7 +73,7 @@ homepage: https://github.com/CocoaPods/Molinillo
74
73
  licenses:
75
74
  - MIT
76
75
  metadata: {}
77
- post_install_message:
76
+ post_install_message:
78
77
  rdoc_options: []
79
78
  require_paths:
80
79
  - lib
@@ -82,17 +81,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
82
81
  requirements:
83
82
  - - ">="
84
83
  - !ruby/object:Gem::Version
85
- version: '0'
84
+ version: 2.0.0
86
85
  required_rubygems_version: !ruby/object:Gem::Requirement
87
86
  requirements:
88
87
  - - ">="
89
88
  - !ruby/object:Gem::Version
90
89
  version: '0'
91
90
  requirements: []
92
- rubyforge_project:
93
- rubygems_version: 2.6.12
94
- signing_key:
91
+ rubygems_version: 3.1.3
92
+ signing_key:
95
93
  specification_version: 4
96
94
  summary: Provides support for dependency resolution
97
95
  test_files: []
98
- has_rdoc:
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Molinillo
4
- # Hacks needed for old Ruby versions.
5
- module Compatibility
6
- module_function
7
-
8
- if [].respond_to?(:flat_map)
9
- # Flat map
10
- # @param [Enumerable] enum an enumerable object
11
- # @block the block to flat-map with
12
- # @return The enum, flat-mapped
13
- def flat_map(enum, &blk)
14
- enum.flat_map(&blk)
15
- end
16
- else
17
- # Flat map
18
- # @param [Enumerable] enum an enumerable object
19
- # @block the block to flat-map with
20
- # @return The enum, flat-mapped
21
- def flat_map(enum, &blk)
22
- enum.map(&blk).flatten(1)
23
- end
24
- end
25
- end
26
- end