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.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

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)