bundler 1.11.2 → 1.12.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +24 -0
  3. data/.gitignore +2 -2
  4. data/.rubocop.yml +17 -2
  5. data/.rubocop_todo.yml +145 -18
  6. data/.travis.yml +9 -2
  7. data/CHANGELOG.md +42 -0
  8. data/Rakefile +20 -13
  9. data/bin/rake +5 -0
  10. data/bin/rspec +5 -0
  11. data/bin/rubocop +7 -1
  12. data/bundler.gemspec +2 -1
  13. data/exe/bundle +10 -2
  14. data/exe/bundle_ruby +2 -1
  15. data/exe/bundler +3 -1
  16. data/lib/bundler.rb +54 -51
  17. data/lib/bundler/capistrano.rb +1 -0
  18. data/lib/bundler/cli.rb +26 -4
  19. data/lib/bundler/cli/binstubs.rb +1 -0
  20. data/lib/bundler/cli/cache.rb +1 -0
  21. data/lib/bundler/cli/check.rb +4 -1
  22. data/lib/bundler/cli/clean.rb +1 -0
  23. data/lib/bundler/cli/common.rb +1 -0
  24. data/lib/bundler/cli/config.rb +5 -5
  25. data/lib/bundler/cli/console.rb +1 -0
  26. data/lib/bundler/cli/exec.rb +4 -9
  27. data/lib/bundler/cli/gem.rb +12 -9
  28. data/lib/bundler/cli/init.rb +1 -0
  29. data/lib/bundler/cli/inject.rb +1 -0
  30. data/lib/bundler/cli/install.rb +8 -5
  31. data/lib/bundler/cli/lock.rb +2 -0
  32. data/lib/bundler/cli/open.rb +1 -0
  33. data/lib/bundler/cli/outdated.rb +36 -9
  34. data/lib/bundler/cli/package.rb +1 -0
  35. data/lib/bundler/cli/platform.rb +4 -1
  36. data/lib/bundler/cli/show.rb +1 -0
  37. data/lib/bundler/cli/update.rb +6 -6
  38. data/lib/bundler/cli/viz.rb +4 -6
  39. data/lib/bundler/constants.rb +1 -0
  40. data/lib/bundler/current_ruby.rb +34 -168
  41. data/lib/bundler/definition.rb +41 -15
  42. data/lib/bundler/dep_proxy.rb +1 -0
  43. data/lib/bundler/dependency.rb +10 -0
  44. data/lib/bundler/deployment.rb +1 -0
  45. data/lib/bundler/deprecate.rb +1 -0
  46. data/lib/bundler/dsl.rb +19 -9
  47. data/lib/bundler/endpoint_specification.rb +37 -8
  48. data/lib/bundler/env.rb +4 -3
  49. data/lib/bundler/environment.rb +1 -0
  50. data/lib/bundler/errors.rb +51 -32
  51. data/lib/bundler/fetcher.rb +44 -30
  52. data/lib/bundler/fetcher/base.rb +3 -2
  53. data/lib/bundler/fetcher/compact_index.rb +98 -0
  54. data/lib/bundler/fetcher/dependency.rb +36 -36
  55. data/lib/bundler/fetcher/downloader.rb +14 -8
  56. data/lib/bundler/fetcher/index.rb +28 -5
  57. data/lib/bundler/friendly_errors.rb +93 -85
  58. data/lib/bundler/gem_helper.rb +20 -21
  59. data/lib/bundler/gem_helpers.rb +9 -2
  60. data/lib/bundler/gem_remote_fetcher.rb +1 -0
  61. data/lib/bundler/gem_tasks.rb +1 -0
  62. data/lib/bundler/graph.rb +16 -17
  63. data/lib/bundler/index.rb +4 -6
  64. data/lib/bundler/injector.rb +1 -0
  65. data/lib/bundler/inline.rb +8 -2
  66. data/lib/bundler/installer.rb +4 -4
  67. data/lib/bundler/installer/gem_installer.rb +1 -0
  68. data/lib/bundler/installer/parallel_installer.rb +3 -2
  69. data/lib/bundler/installer/standalone.rb +5 -1
  70. data/lib/bundler/lazy_specification.rb +5 -2
  71. data/lib/bundler/lockfile_parser.rb +22 -15
  72. data/lib/bundler/match_platform.rb +1 -0
  73. data/lib/bundler/mirror.rb +218 -0
  74. data/lib/bundler/path_preserver.rb +12 -0
  75. data/lib/bundler/psyched_yaml.rb +1 -0
  76. data/lib/bundler/remote_specification.rb +4 -1
  77. data/lib/bundler/resolver.rb +17 -16
  78. data/lib/bundler/retry.rb +1 -0
  79. data/lib/bundler/ruby_dsl.rb +8 -2
  80. data/lib/bundler/ruby_version.rb +58 -61
  81. data/lib/bundler/rubygems_ext.rb +4 -3
  82. data/lib/bundler/rubygems_gem_installer.rb +1 -0
  83. data/lib/bundler/rubygems_integration.rb +9 -14
  84. data/lib/bundler/runtime.rb +17 -22
  85. data/lib/bundler/settings.rb +17 -21
  86. data/lib/bundler/setup.rb +1 -0
  87. data/lib/bundler/shared_helpers.rb +47 -17
  88. data/lib/bundler/similarity_detector.rb +1 -0
  89. data/lib/bundler/source.rb +2 -1
  90. data/lib/bundler/source/git.rb +2 -1
  91. data/lib/bundler/source/git/git_proxy.rb +33 -7
  92. data/lib/bundler/source/path.rb +17 -10
  93. data/lib/bundler/source/path/installer.rb +1 -0
  94. data/lib/bundler/source/rubygems.rb +4 -3
  95. data/lib/bundler/source/rubygems/remote.rb +16 -0
  96. data/lib/bundler/source_list.rb +1 -0
  97. data/lib/bundler/spec_set.rb +1 -0
  98. data/lib/bundler/ssl_certs/certificate_manager.rb +1 -0
  99. data/lib/bundler/stub_specification.rb +1 -0
  100. data/lib/bundler/templates/Executable +1 -0
  101. data/lib/bundler/templates/Gemfile +1 -0
  102. data/lib/bundler/templates/newgem/.travis.yml.tt +1 -0
  103. data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -2
  104. data/lib/bundler/ui.rb +1 -0
  105. data/lib/bundler/ui/rg_proxy.rb +1 -0
  106. data/lib/bundler/ui/shell.rb +2 -1
  107. data/lib/bundler/ui/silent.rb +1 -0
  108. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +78 -0
  109. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/cache.rb +97 -0
  110. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/updater.rb +55 -0
  111. data/lib/bundler/vendor/compact_index_client/lib/compact_index_client/version.rb +3 -0
  112. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +4 -0
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +13 -0
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +5 -0
  115. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +2 -1
  116. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +2 -1
  117. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +37 -14
  118. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -1
  119. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +7 -7
  120. data/lib/bundler/vendored_molinillo.rb +1 -0
  121. data/lib/bundler/vendored_persistent.rb +1 -0
  122. data/lib/bundler/vendored_thor.rb +1 -0
  123. data/lib/bundler/version.rb +6 -1
  124. data/lib/bundler/vlad.rb +1 -0
  125. data/lib/bundler/worker.rb +12 -2
  126. data/man/bundle-config.ronn +6 -0
  127. data/man/bundle-gem.ronn +5 -5
  128. metadata +14 -6
  129. data/lib/bundler/gem_path_manipulation.rb +0 -8
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Bundler
2
3
  module UI
3
4
  class Silent
@@ -0,0 +1,78 @@
1
+ require "pathname"
2
+ require "set"
3
+
4
+ class Bundler::CompactIndexClient
5
+ class Error < StandardError; end
6
+
7
+ require "bundler/vendor/compact_index_client/lib/compact_index_client/cache"
8
+ require "bundler/vendor/compact_index_client/lib/compact_index_client/updater"
9
+ require "bundler/vendor/compact_index_client/lib/compact_index_client/version"
10
+
11
+ attr_reader :directory
12
+
13
+ # @return [Lambda] A lambda that takes an array of inputs and a block, and
14
+ # maps the inputs with the block in parallel.
15
+ #
16
+ attr_accessor :in_parallel
17
+
18
+ def initialize(directory, fetcher)
19
+ @directory = Pathname.new(directory)
20
+ @updater = Updater.new(fetcher)
21
+ @cache = Cache.new(@directory)
22
+ @endpoints = Set.new
23
+ @info_checksums_by_name = {}
24
+ @in_parallel = lambda do |inputs, &blk|
25
+ inputs.map(&blk)
26
+ end
27
+ end
28
+
29
+ def names
30
+ update(@cache.names_path, "names")
31
+ @cache.names
32
+ end
33
+
34
+ def versions
35
+ update(@cache.versions_path, "versions")
36
+ versions, @info_checksums_by_name = @cache.versions
37
+ versions
38
+ end
39
+
40
+ def dependencies(names)
41
+ in_parallel.call(names) do |name|
42
+ update_info(name)
43
+ @cache.dependencies(name).map {|d| d.unshift(name) }
44
+ end.flatten(1)
45
+ end
46
+
47
+ def spec(name, version, platform = nil)
48
+ update_info(name)
49
+ @cache.specific_dependency(name, version, platform)
50
+ end
51
+
52
+ def update_and_parse_checksums!
53
+ return @info_checksums_by_name if @parsed_checksums
54
+ update(@cache.versions_path, "versions")
55
+ @info_checksums_by_name = @cache.checksums
56
+ @parsed_checksums = true
57
+ end
58
+
59
+ private
60
+
61
+ def update(local_path, remote_path)
62
+ return if @endpoints.include?(remote_path)
63
+ @updater.update(local_path, url(remote_path))
64
+ @endpoints << remote_path
65
+ end
66
+
67
+ def update_info(name)
68
+ path = @cache.info_path(name)
69
+ checksum = @updater.checksum_for_file(path)
70
+ return unless existing = @info_checksums_by_name[name]
71
+ return if checksum == existing
72
+ update(path, "info/#{name}")
73
+ end
74
+
75
+ def url(path)
76
+ path
77
+ end
78
+ end
@@ -0,0 +1,97 @@
1
+ class Bundler::CompactIndexClient
2
+ class Cache
3
+ attr_reader :directory
4
+
5
+ def initialize(directory)
6
+ @directory = Pathname.new(directory).expand_path
7
+ FileUtils.mkdir_p info_path(nil)
8
+ end
9
+
10
+ def names
11
+ lines(names_path)
12
+ end
13
+
14
+ def names_path
15
+ directory.join("names")
16
+ end
17
+
18
+ def versions
19
+ versions_by_name = Hash.new {|hash, key| hash[key] = [] }
20
+ info_checksums_by_name = {}
21
+
22
+ lines(versions_path).each do |line|
23
+ name, versions_string, info_checksum = line.split(" ", 3)
24
+ info_checksums_by_name[name] = info_checksum || ""
25
+ versions_string.split(",").each do |version|
26
+ if version.start_with?("-")
27
+ version = version[1..-1].split("-", 2).unshift(name)
28
+ versions_by_name[name].delete(version)
29
+ else
30
+ version = version.split("-", 2).unshift(name)
31
+ versions_by_name[name] << version
32
+ end
33
+ end
34
+ end
35
+
36
+ [versions_by_name, info_checksums_by_name]
37
+ end
38
+
39
+ def versions_path
40
+ directory.join("versions")
41
+ end
42
+
43
+ def checksums
44
+ checksums = {}
45
+
46
+ lines(versions_path).each do |line|
47
+ name, _, checksum = line.split(" ", 3)
48
+ checksums[name] = checksum
49
+ end
50
+
51
+ checksums
52
+ end
53
+
54
+ def dependencies(name)
55
+ lines(info_path(name)).map do |line|
56
+ parse_gem(line)
57
+ end
58
+ end
59
+
60
+ def info_path(name)
61
+ directory.join("info", name.to_s)
62
+ end
63
+
64
+ def specific_dependency(name, version, platform)
65
+ pattern = [version, platform].compact.join("-")
66
+ return nil if pattern.empty?
67
+
68
+ gem_lines = info_path(name).read
69
+ gem_line = gem_lines[/^#{Regexp.escape(pattern)}\b.*/, 0]
70
+ gem_line ? parse_gem(gem_line) : nil
71
+ end
72
+
73
+ private
74
+
75
+ def lines(path)
76
+ return [] unless path.file?
77
+ lines = path.read.split("\n")
78
+ header = lines.index("---")
79
+ lines = header ? lines[header + 1..-1] : lines
80
+ end
81
+
82
+ def parse_gem(string)
83
+ version_and_platform, rest = string.split(" ", 2)
84
+ version, platform = version_and_platform.split("-", 2)
85
+ dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
86
+ dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
87
+ requirements = requirements ? requirements.map {|r| parse_dependency(r) } : []
88
+ [version, platform, dependencies, requirements]
89
+ end
90
+
91
+ def parse_dependency(string)
92
+ dependency = string.split(":")
93
+ dependency[-1] = dependency[-1].split("&") if dependency.size > 1
94
+ dependency
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,55 @@
1
+ require "stringio"
2
+ require "zlib"
3
+
4
+ class Bundler::CompactIndexClient
5
+ class Updater
6
+ class MisMatchedChecksumError < Error; end
7
+
8
+ def initialize(fetcher)
9
+ @fetcher = fetcher
10
+ end
11
+
12
+ def update(local_path, remote_path, retrying = nil)
13
+ headers = {}
14
+
15
+ if local_path.file?
16
+ headers["If-None-Match"] = etag_for(local_path)
17
+ headers["Range"] = "bytes=#{local_path.size}-"
18
+ else
19
+ # Fastly ignores Range when Accept-Encoding: gzip is set
20
+ headers["Accept-Encoding"] = "gzip"
21
+ end
22
+
23
+ response = @fetcher.call(remote_path, headers)
24
+ return if response.is_a?(Net::HTTPNotModified)
25
+
26
+ content = response.body
27
+ if response["Content-Encoding"] == "gzip"
28
+ content = Zlib::GzipReader.new(StringIO.new(content)).read
29
+ end
30
+
31
+ mode = response.is_a?(Net::HTTPPartialContent) ? "a" : "w"
32
+ local_path.open(mode) {|f| f << content }
33
+
34
+ return if etag_for(local_path) == response["ETag"]
35
+
36
+ if retrying.nil?
37
+ local_path.delete
38
+ update(local_path, remote_path, :retrying)
39
+ else
40
+ raise MisMatchedChecksumError, "Checksum of /#{remote_path} " \
41
+ "does not match the checksum provided by server! Something is wrong."
42
+ end
43
+ end
44
+
45
+ def etag_for(path)
46
+ sum = checksum_for_file(path)
47
+ sum ? '"' << sum << '"' : nil
48
+ end
49
+
50
+ def checksum_for_file(path)
51
+ return nil unless path.file?
52
+ Digest::MD5.file(path).hexdigest
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ class Bundler::CompactIndexClient
2
+ VERSION = "0.1.0"
3
+ end
@@ -3,3 +3,7 @@ require 'bundler/vendor/molinillo/lib/molinillo/errors'
3
3
  require 'bundler/vendor/molinillo/lib/molinillo/resolver'
4
4
  require 'bundler/vendor/molinillo/lib/molinillo/modules/ui'
5
5
  require 'bundler/vendor/molinillo/lib/molinillo/modules/specification_provider'
6
+
7
+ # Bundler::Molinillo is a generic dependency resolution algorithm.
8
+ module Bundler::Molinillo
9
+ end
@@ -14,8 +14,10 @@ module Bundler::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 Bundler::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 Bundler::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`
@@ -121,6 +126,10 @@ module Bundler::Molinillo
121
126
  v.incoming_edges.delete(e)
122
127
  detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
123
128
  end
129
+ vertex.incoming_edges.each do |e|
130
+ v = e.origin
131
+ v.outgoing_edges.delete(e)
132
+ end
124
133
  end
125
134
 
126
135
  # @param [String] name
@@ -150,6 +159,8 @@ module Bundler::Molinillo
150
159
 
151
160
  private
152
161
 
162
+ # Adds a new {Edge} to the dependency graph without checking for
163
+ # circularity.
153
164
  def add_edge_no_circular(origin, destination, requirement)
154
165
  edge = Edge.new(origin, destination, requirement)
155
166
  origin.outgoing_edges << edge
@@ -174,6 +185,7 @@ module Bundler::Molinillo
174
185
  attr_accessor :root
175
186
  alias_method :root?, :root
176
187
 
188
+ # Initializes a vertex with the given name and payload.
177
189
  # @param [String] name see {#name}
178
190
  # @param [Object] payload see {#payload}
179
191
  def initialize(name, payload)
@@ -240,6 +252,7 @@ module Bundler::Molinillo
240
252
  successors.to_set == other.successors.to_set
241
253
  end
242
254
 
255
+ # @param [Vertex] other the other vertex to compare to
243
256
  # @return [Boolean] whether the two vertices are equal, determined
244
257
  # solely by {#name} and {#payload} equality
245
258
  def shallow_eql?(other)
@@ -11,6 +11,7 @@ module Bundler::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 Bundler::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 Bundler::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 Bundler::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 Bundler::Molinillo
2
- VERSION = '0.4.0'
2
+ # The version of Bundler::Molinillo.
3
+ VERSION = '0.4.2'.freeze
3
4
  end
@@ -57,7 +57,8 @@ module Bundler::Molinillo
57
57
  #
58
58
  # @return [Boolean]
59
59
  def debug?
60
- @debug_mode ||= ENV['MOLINILLO_DEBUG']
60
+ return @debug_mode if defined?(@debug_mode)
61
+ @debug_mode = ENV['MOLINILLO_DEBUG']
61
62
  end
62
63
  end
63
64
  end
@@ -38,6 +38,7 @@ module Bundler::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}
@@ -340,26 +341,36 @@ module Bundler::Molinillo
340
341
  # @return [Boolean] Whether the possibility was swapped into {#activated}
341
342
  def attempt_to_swap_possibility
342
343
  swapped = activated.dup
343
- swapped.vertex_named(name).payload = possibility
344
- return unless swapped.vertex_named(name).requirements.
344
+ vertex = swapped.vertex_named(name)
345
+ vertex.payload = possibility
346
+ return unless vertex.requirements.
345
347
  all? { |r| requirement_satisfied_by?(r, swapped, possibility) }
346
- attempt_to_activate_new_spec
348
+ return unless new_spec_satisfied?
349
+ actual_vertex = activated.vertex_named(name)
350
+ actual_vertex.payload = possibility
351
+ fixup_swapped_children(actual_vertex)
352
+ activate_spec
353
+ end
354
+
355
+ # Ensures there are no orphaned successors to the given {vertex}.
356
+ # @param [DependencyGraph::Vertex] vertex the vertex to fix up.
357
+ # @return [void]
358
+ def fixup_swapped_children(vertex)
359
+ payload = vertex.payload
360
+ dep_names = dependencies_for(payload).map(&method(:name_for))
361
+ vertex.successors.each do |succ|
362
+ if !dep_names.include?(succ.name) && !succ.root? && succ.predecessors.to_a == [vertex]
363
+ debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
364
+ activated.detach_vertex_named(succ.name)
365
+ end
366
+ end
347
367
  end
348
368
 
349
369
  # Attempts to activate the current {#possibility} (given that it hasn't
350
370
  # already been activated)
351
371
  # @return [void]
352
372
  def attempt_to_activate_new_spec
353
- satisfied = begin
354
- locked_requirement = locked_requirement_named(name)
355
- requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
356
- locked_spec_satisfied = !locked_requirement ||
357
- requirement_satisfied_by?(locked_requirement, activated, possibility)
358
- debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
359
- debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
360
- requested_spec_satisfied && locked_spec_satisfied
361
- end
362
- if satisfied
373
+ if new_spec_satisfied?
363
374
  activate_spec
364
375
  else
365
376
  create_conflict
@@ -367,6 +378,18 @@ module Bundler::Molinillo
367
378
  end
368
379
  end
369
380
 
381
+ # @return [Boolean] whether the current spec is satisfied as a new
382
+ # possibility.
383
+ def new_spec_satisfied?
384
+ locked_requirement = locked_requirement_named(name)
385
+ requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
386
+ locked_spec_satisfied = !locked_requirement ||
387
+ requirement_satisfied_by?(locked_requirement, activated, possibility)
388
+ debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
389
+ debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
390
+ requested_spec_satisfied && locked_spec_satisfied
391
+ end
392
+
370
393
  # @param [String] requirement_name the spec name to search for
371
394
  # @return [Object] the locked spec named `requirement_name`, if one
372
395
  # is found on {#base}
@@ -392,7 +415,7 @@ module Bundler::Molinillo
392
415
  # @return [void]
393
416
  def require_nested_dependencies_for(activated_spec)
394
417
  nested_dependencies = dependencies_for(activated_spec)
395
- debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" }
418
+ debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
396
419
  nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }
397
420
 
398
421
  push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)