molinillo 0.4.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f860bde0bd4aed39aadb78bce1dd854bedf9d34e
4
- data.tar.gz: eaebd8e7e9070425f2c4c80b65fc562ff8fe210a
3
+ metadata.gz: 5ea85c0037f78e6763d19bf7d8144c33eccb1a28
4
+ data.tar.gz: da1f09939f213f0e93bc644a8ba021000c79db9e
5
5
  SHA512:
6
- metadata.gz: 2ede3f0f7aecfdf3aab7be57f3bf23f2c23e2fe440aa8c470bcfd5bdd212941aa4ad52dd5a958886448c64fd515af63ce9342dd343912d8f8213cfbc5ff6ddbf
7
- data.tar.gz: 82b5e19bb50aa3db372c838fca16a8b61628ca7bd9cfd9aa525d9cd7af4218768bf48e21b9801232959993cd258207e4deeb4356fd6b575d781af9ba2ebd7065
6
+ metadata.gz: a84d8bde06c58dcf77fe69d9128c964a35077226a8cb5b9f9af6d4aa78592426491b35e62371565d2654f035302a7797deda05584c778e6d58e4575291bc5c5e
7
+ data.tar.gz: 40f4b4b9282474acee27715541f6d2f3c5153b1e333c1ed84f42d04aa09f8aeb4e024f6010abae83d958c41baa7c596002a2457c69ec008573efccac9824cf93
@@ -3,3 +3,7 @@ require 'molinillo/errors'
3
3
  require 'molinillo/resolver'
4
4
  require 'molinillo/modules/ui'
5
5
  require 'molinillo/modules/specification_provider'
6
+
7
+ # Molinillo is a generic dependency resolution algorithm.
8
+ module Molinillo
9
+ end
@@ -14,8 +14,10 @@ module Molinillo
14
14
 
15
15
  include TSort
16
16
 
17
+ # @visibility private
17
18
  alias_method :tsort_each_node, :each
18
19
 
20
+ # @visibility private
19
21
  def tsort_each_child(vertex, &block)
20
22
  vertex.successors.each(&block)
21
23
  end
@@ -41,12 +43,14 @@ module Molinillo
41
43
  # by {Vertex#name}
42
44
  attr_reader :vertices
43
45
 
46
+ # Initializes an empty dependency graph
44
47
  def initialize
45
48
  @vertices = {}
46
49
  end
47
50
 
48
51
  # Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
49
52
  # are properly copied.
53
+ # @param [DependencyGraph] other the graph to copy.
50
54
  def initialize_copy(other)
51
55
  super
52
56
  @vertices = {}
@@ -100,6 +104,7 @@ module Molinillo
100
104
  vertex
101
105
  end
102
106
 
107
+ # Adds a vertex with the given name, or updates the existing one.
103
108
  # @param [String] name
104
109
  # @param [Object] payload
105
110
  # @return [Vertex] the vertex that was added to `self`
@@ -150,6 +155,8 @@ module Molinillo
150
155
 
151
156
  private
152
157
 
158
+ # Adds a new {Edge} to the dependency graph without checking for
159
+ # circularity.
153
160
  def add_edge_no_circular(origin, destination, requirement)
154
161
  edge = Edge.new(origin, destination, requirement)
155
162
  origin.outgoing_edges << edge
@@ -174,6 +181,7 @@ module Molinillo
174
181
  attr_accessor :root
175
182
  alias_method :root?, :root
176
183
 
184
+ # Initializes a vertex with the given name and payload.
177
185
  # @param [String] name see {#name}
178
186
  # @param [Object] payload see {#payload}
179
187
  def initialize(name, payload)
@@ -240,6 +248,7 @@ module Molinillo
240
248
  successors.to_set == other.successors.to_set
241
249
  end
242
250
 
251
+ # @param [Vertex] other the other vertex to compare to
243
252
  # @return [Boolean] whether the two vertices are equal, determined
244
253
  # solely by {#name} and {#payload} equality
245
254
  def shallow_eql?(other)
@@ -11,6 +11,7 @@ module Molinillo
11
11
  # @return [Array<Object>] the specifications that depended upon {#dependency}
12
12
  attr_accessor :required_by
13
13
 
14
+ # Initializes a new error with the given missing dependency.
14
15
  # @param [Object] dependency @see {#dependency}
15
16
  # @param [Array<Object>] required_by @see {#required_by}
16
17
  def initialize(dependency, required_by = [])
@@ -19,6 +20,8 @@ module Molinillo
19
20
  super()
20
21
  end
21
22
 
23
+ # The error message for the missing dependency, including the specifications
24
+ # that had this dependency.
22
25
  def message
23
26
  sources = required_by.map { |r| "`#{r}`" }.join(' and ')
24
27
  message = "Unable to find a specification for `#{dependency}`"
@@ -36,6 +39,7 @@ module Molinillo
36
39
  # [Set<Object>] the dependencies responsible for causing the error
37
40
  attr_reader :dependencies
38
41
 
42
+ # Initializes a new error with the given circular vertices.
39
43
  # @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
40
44
  # that caused the error
41
45
  def initialize(nodes)
@@ -50,6 +54,7 @@ module Molinillo
50
54
  # resolution to fail
51
55
  attr_reader :conflicts
52
56
 
57
+ # Initializes a new error with the given version conflicts.
53
58
  # @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
54
59
  def initialize(conflicts)
55
60
  pairs = []
@@ -1,3 +1,4 @@
1
1
  module Molinillo
2
- VERSION = '0.4.0'
2
+ # The version of Molinillo.
3
+ VERSION = '0.4.1'.freeze
3
4
  end
@@ -38,6 +38,7 @@ module Molinillo
38
38
  # @return [Array] the dependencies that were explicitly required
39
39
  attr_reader :original_requested
40
40
 
41
+ # Initializes a new resolution.
41
42
  # @param [SpecificationProvider] specification_provider
42
43
  # see {#specification_provider}
43
44
  # @param [UI] resolver_ui see {#resolver_ui}
@@ -3,7 +3,7 @@ require 'molinillo/dependency_graph'
3
3
  module Molinillo
4
4
  # This class encapsulates a dependency resolver.
5
5
  # The resolver is responsible for determining which set of dependencies to
6
- # activate, with feedback from the the {#specification_provider}
6
+ # activate, with feedback from the {#specification_provider}
7
7
  #
8
8
  #
9
9
  class Resolver
@@ -17,6 +17,7 @@ module Molinillo
17
17
  # during the resolution process
18
18
  attr_reader :resolver_ui
19
19
 
20
+ # Initializes a new resolver.
20
21
  # @param [SpecificationProvider] specification_provider
21
22
  # see {#specification_provider}
22
23
  # @param [UI] resolver_ui
@@ -1,12 +1,12 @@
1
1
  module Molinillo
2
2
  # A state that a {Resolution} can be in
3
- # @attr [String] name
4
- # @attr [Array<Object>] requirements
5
- # @attr [DependencyGraph] activated
6
- # @attr [Object] requirement
7
- # @attr [Object] possibility
8
- # @attr [Integer] depth
9
- # @attr [Set<Object>] conflicts
3
+ # @attr [String] name the name of the current requirement
4
+ # @attr [Array<Object>] requirements currently unsatisfied requirements
5
+ # @attr [DependencyGraph] activated the graph of activated dependencies
6
+ # @attr [Object] requirement the current requirement
7
+ # @attr [Object] possibilities the possibilities to satisfy the current requirement
8
+ # @attr [Integer] depth the depth of the resolution
9
+ # @attr [Set<Object>] conflicts unresolved conflicts
10
10
  ResolutionState = Struct.new(
11
11
  :name,
12
12
  :requirements,
@@ -4,59 +4,49 @@ module Molinillo
4
4
  describe DependencyGraph do
5
5
  describe 'in general' do
6
6
  before do
7
- @graph = DependencyGraph.new
7
+ @graph = described_class.new
8
8
  @root = @graph.add_vertex('Root', 'Root', true)
9
9
  @root2 = @graph.add_vertex('Root2', 'Root2', true)
10
10
  @child = @graph.add_child_vertex('Child', 'Child', %w(Root), 'Child')
11
11
  end
12
12
 
13
13
  it 'returns root vertices by name' do
14
- @graph.root_vertex_named('Root').
15
- should.equal @root
14
+ expect(@graph.root_vertex_named('Root')).to eq(@root)
16
15
  end
17
16
 
18
17
  it 'returns vertices by name' do
19
- @graph.vertex_named('Root').
20
- should.equal @root
21
- @graph.vertex_named('Child').
22
- should.equal @child
18
+ expect(@graph.vertex_named('Root')).to eq(@root)
19
+ expect(@graph.vertex_named('Child')).to eq(@child)
23
20
  end
24
21
 
25
22
  it 'returns nil for non-existant root vertices' do
26
- @graph.root_vertex_named('missing').
27
- should.equal nil
23
+ expect(@graph.root_vertex_named('missing')).to be_nil
28
24
  end
29
25
 
30
26
  it 'returns nil for non-existant vertices' do
31
- @graph.vertex_named('missing').
32
- should.equal nil
27
+ expect(@graph.vertex_named('missing')).to be_nil
33
28
  end
34
29
  end
35
30
 
36
31
  describe 'detaching a node' do
37
32
  before do
38
- @graph = DependencyGraph.new
33
+ @graph = described_class.new
39
34
  end
40
35
 
41
36
  it 'detaches a root vertex without successors' do
42
37
  root = @graph.add_vertex('root', 'root', true)
43
38
  @graph.detach_vertex_named(root.name)
44
- @graph.vertex_named(root.name).
45
- should.equal nil
46
- @graph.vertices.count.
47
- should.equal 0
39
+ expect(@graph.vertex_named(root.name)).to be_nil
40
+ expect(@graph.vertices).to be_empty
48
41
  end
49
42
 
50
43
  it 'detaches a root vertex with successors' do
51
44
  root = @graph.add_vertex('root', 'root', true)
52
45
  child = @graph.add_child_vertex('child', 'child', %w(root), 'child')
53
46
  @graph.detach_vertex_named(root.name)
54
- @graph.vertex_named(root.name).
55
- should.equal nil
56
- @graph.vertex_named(child.name).
57
- should.equal nil
58
- @graph.vertices.count.
59
- should.equal 0
47
+ expect(@graph.vertex_named(root.name)).to be_nil
48
+ expect(@graph.vertex_named(child.name)).to be_nil
49
+ expect(@graph.vertices).to be_empty
60
50
  end
61
51
 
62
52
  it 'detaches a root vertex with successors with other parents' do
@@ -64,14 +54,10 @@ module Molinillo
64
54
  root2 = @graph.add_vertex('root2', 'root2', true)
65
55
  child = @graph.add_child_vertex('child', 'child', %w(root root2), 'child')
66
56
  @graph.detach_vertex_named(root.name)
67
- @graph.vertex_named(root.name).
68
- should.equal nil
69
- @graph.vertex_named(child.name).
70
- should.equal child
71
- child.predecessors.
72
- should.equal [root2]
73
- @graph.vertices.count.
74
- should.equal 2
57
+ expect(@graph.vertex_named(root.name)).to be_nil
58
+ expect(@graph.vertex_named(child.name)).to eq(child)
59
+ expect(child.predecessors).to eq([root2])
60
+ expect(@graph.vertices.count).to eq(2)
75
61
  end
76
62
  end
77
63
  end
@@ -14,7 +14,6 @@ module Molinillo
14
14
 
15
15
  attr_accessor :name, :requested, :base, :conflicts, :resolver, :result, :index
16
16
 
17
- # rubocop:disable Metrics/MethodLength
18
17
  def initialize(fixture_path)
19
18
  File.open(fixture_path) do |fixture|
20
19
  JSON.load(fixture).tap do |test_case|
@@ -54,7 +53,6 @@ module Molinillo
54
53
 
55
54
  self.resolver = Resolver.new(index, TestUI.new)
56
55
  end
57
- # rubocop:enable Metrics/MethodLength
58
56
  end
59
57
 
60
58
  describe Resolver do
@@ -65,27 +63,25 @@ module Molinillo
65
63
  resolve = lambda { test_case.resolver.resolve(test_case.requested, test_case.base) }
66
64
 
67
65
  if test_case.conflicts.any?
68
- error = should.raise ResolverError do
69
- resolve.call
66
+ expect { resolve.call }.to raise_error do |error|
67
+ expect(error).to be_a(ResolverError)
68
+ names = case error
69
+ when CircularDependencyError
70
+ error.dependencies.map(&:name)
71
+ when VersionConflict
72
+ error.conflicts.keys
73
+ end.to_set
74
+ expect(names).to eq(test_case.conflicts)
70
75
  end
71
-
72
- names = case error
73
- when CircularDependencyError
74
- error.dependencies.map(&:name)
75
- when VersionConflict
76
- error.conflicts.keys
77
- end.to_set
78
- names.should.equal test_case.conflicts
79
76
  else
80
77
  result = resolve.call
81
78
 
82
79
  pretty_dependencies = lambda do |dg|
83
80
  dg.vertices.values.map { |v| "#{v.payload.name} (#{v.payload.version})" }.sort
84
81
  end
85
- pretty_dependencies.call(result).should.
86
- equal pretty_dependencies.call(test_case.result)
82
+ expect(pretty_dependencies.call(result)).to eq(pretty_dependencies.call(test_case.result))
87
83
 
88
- result.should.equal test_case.result
84
+ expect(result).to eq(test_case.result)
89
85
  end
90
86
  end
91
87
  end
@@ -93,36 +89,35 @@ module Molinillo
93
89
 
94
90
  describe 'in general' do
95
91
  before do
96
- @resolver = Resolver.new(TestIndex.new('awesome'), TestUI.new)
92
+ @resolver = described_class.new(TestIndex.new('awesome'), TestUI.new)
97
93
  end
98
94
 
99
95
  it 'can resolve a list of 0 requirements' do
100
- @resolver.resolve([], DependencyGraph.new).
101
- should.equal DependencyGraph.new
96
+ expect(@resolver.resolve([], DependencyGraph.new)).to eq(DependencyGraph.new)
102
97
  end
103
98
 
104
99
  it 'includes the source of a user-specified unsatisfied dependency' do
105
- should.raise VersionConflict do
100
+ expect do
106
101
  @resolver.resolve([VersionKit::Dependency.new('missing', '3.0')], DependencyGraph.new)
107
- end.message.should.match /required by `user-specified dependency`/
102
+ end.to raise_error(VersionConflict, /required by `user-specified dependency`/)
108
103
  end
109
104
 
110
105
  it 'can handle when allow_missing? returns true for the only requirement' do
111
106
  dep = VersionKit::Dependency.new('missing', '3.0')
112
- @resolver.specification_provider.stubs(:allow_missing?).with(dep).returns(true)
113
- @resolver.resolve([dep], DependencyGraph.new).to_a.should == []
107
+ allow(@resolver.specification_provider).to receive(:allow_missing?).with(dep).and_return(true)
108
+ expect(@resolver.resolve([dep], DependencyGraph.new).to_a).to be_empty
114
109
  end
115
110
 
116
111
  it 'can handle when allow_missing? returns true for a nested requirement' do
117
- index = TestIndex.new('awesome')
118
112
  dep = VersionKit::Dependency.new('actionpack', '1.2.3')
119
- @resolver.specification_provider.stubs(:allow_missing?).
120
- with { |d| d.name == 'activesupport' }.returns(true)
121
- @resolver.specification_provider.stubs(:search_for).
122
- with { |d| d.name == 'activesupport' }.returns([])
123
- @resolver.specification_provider.stubs(:search_for).
124
- with { |d| d.name == 'actionpack' }.returns(index.search_for(dep))
125
- @resolver.resolve([dep], DependencyGraph.new).map(&:payload).map(&:to_s).should == ['actionpack (1.2.3)']
113
+ allow(@resolver.specification_provider).to receive(:allow_missing?).
114
+ with(have_attributes(:name => 'activesupport')).and_return(true)
115
+ allow(@resolver.specification_provider).to receive(:search_for).
116
+ with(have_attributes(:name => 'activesupport')).and_return([])
117
+ allow(@resolver.specification_provider).to receive(:search_for).
118
+ with(have_attributes(:name => 'actionpack')).and_call_original
119
+ resolved = @resolver.resolve([dep], DependencyGraph.new)
120
+ expect(resolved.map(&:payload).map(&:to_s)).to eq(['actionpack (1.2.3)'])
126
121
  end
127
122
  end
128
123
  end
@@ -1,8 +1,9 @@
1
+ require 'bundler/setup'
1
2
 
2
3
  # Set up coverage analysis
3
4
  #-----------------------------------------------------------------------------#
4
5
 
5
- if (ENV['CI'] || ENV['GENERATE_COVERAGE']) && RUBY_VERSION >= '2.0.0'
6
+ if (ENV['CI'] || ENV['GENERATE_COVERAGE']) && RUBY_VERSION >= '2.0.0' && Bundler.current_ruby.mri?
6
7
  require 'simplecov'
7
8
  require 'codeclimate-test-reporter'
8
9
 
@@ -26,9 +27,5 @@ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
26
27
  $LOAD_PATH.unshift((ROOT + 'lib').to_s)
27
28
  $LOAD_PATH.unshift((ROOT + 'spec').to_s)
28
29
 
29
- require 'bundler/setup'
30
- require 'bacon'
31
- require 'mocha-on-bacon'
32
- require 'pretty_bacon'
33
30
  require 'version_kit'
34
31
  require 'molinillo'
@@ -4,7 +4,7 @@ module Molinillo
4
4
  describe ResolutionState do
5
5
  describe DependencyState do
6
6
  before do
7
- @state = DependencyState.new(
7
+ @state = described_class.new(
8
8
  'name',
9
9
  %w(requirement1 requirement2 requirement3),
10
10
  DependencyGraph.new,
@@ -18,15 +18,11 @@ module Molinillo
18
18
  it 'pops a possibility state' do
19
19
  possibility_state = @state.pop_possibility_state
20
20
  %w(name requirements activated requirement conflicts).each do |attr|
21
- possibility_state.send(attr).
22
- should.equal @state.send(attr)
21
+ expect(possibility_state.send(attr)).to eq(@state.send(attr))
23
22
  end
24
- possibility_state.is_a?(PossibilityState).
25
- should.be.true?
26
- possibility_state.depth.
27
- should.equal @state.depth + 1
28
- possibility_state.possibilities.
29
- should.equal %w(possibility)
23
+ expect(possibility_state).to be_a(PossibilityState)
24
+ expect(possibility_state.depth).to eq(@state.depth + 1)
25
+ expect(possibility_state.possibilities).to eq(%w(possibility))
30
26
  end
31
27
  end
32
28
  end
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.4.0
4
+ version: 0.4.1
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: 2015-07-27 00:00:00.000000000 Z
11
+ date: 2015-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
84
  version: '0'
85
85
  requirements: []
86
86
  rubyforge_project:
87
- rubygems_version: 2.4.8
87
+ rubygems_version: 2.5.1
88
88
  signing_key:
89
89
  specification_version: 4
90
90
  summary: Provides support for dependency resolution
@@ -97,3 +97,4 @@ test_files:
97
97
  - spec/spec_helper/ui.rb
98
98
  - spec/spec_helper.rb
99
99
  - spec/state_spec.rb
100
+ has_rdoc: