bundler 2.0.1 → 2.1.4

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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +788 -572
  3. data/LICENSE.md +18 -19
  4. data/README.md +9 -8
  5. data/bundler.gemspec +8 -25
  6. data/exe/bundle +19 -3
  7. data/lib/bundler.rb +202 -87
  8. data/lib/bundler/build_metadata.rb +3 -3
  9. data/lib/bundler/capistrano.rb +5 -5
  10. data/lib/bundler/cli.rb +182 -144
  11. data/lib/bundler/cli/add.rb +28 -16
  12. data/lib/bundler/cli/cache.rb +25 -13
  13. data/lib/bundler/cli/common.rb +11 -12
  14. data/lib/bundler/cli/config.rb +161 -86
  15. data/lib/bundler/cli/console.rb +2 -2
  16. data/lib/bundler/cli/doctor.rb +4 -4
  17. data/lib/bundler/cli/exec.rb +4 -16
  18. data/lib/bundler/cli/gem.rb +5 -5
  19. data/lib/bundler/cli/info.rb +17 -5
  20. data/lib/bundler/cli/init.rb +1 -1
  21. data/lib/bundler/cli/install.rb +15 -13
  22. data/lib/bundler/cli/issue.rb +3 -3
  23. data/lib/bundler/cli/open.rb +10 -6
  24. data/lib/bundler/cli/outdated.rb +85 -81
  25. data/lib/bundler/cli/plugin.rb +9 -2
  26. data/lib/bundler/cli/pristine.rb +1 -1
  27. data/lib/bundler/cli/show.rb +1 -1
  28. data/lib/bundler/cli/update.rb +31 -11
  29. data/lib/bundler/compact_index_client.rb +25 -9
  30. data/lib/bundler/compact_index_client/updater.rb +2 -6
  31. data/lib/bundler/current_ruby.rb +8 -7
  32. data/lib/bundler/definition.rb +36 -27
  33. data/lib/bundler/dependency.rb +16 -4
  34. data/lib/bundler/deployment.rb +2 -2
  35. data/lib/bundler/dsl.rb +19 -43
  36. data/lib/bundler/env.rb +8 -13
  37. data/lib/bundler/environment_preserver.rb +0 -1
  38. data/lib/bundler/feature_flag.rb +2 -14
  39. data/lib/bundler/fetcher.rb +16 -13
  40. data/lib/bundler/fetcher/compact_index.rb +26 -12
  41. data/lib/bundler/fetcher/dependency.rb +1 -1
  42. data/lib/bundler/fetcher/downloader.rb +5 -2
  43. data/lib/bundler/fetcher/index.rb +5 -3
  44. data/lib/bundler/friendly_errors.rb +6 -7
  45. data/lib/bundler/gem_helper.rb +39 -25
  46. data/lib/bundler/gem_helpers.rb +2 -4
  47. data/lib/bundler/gem_tasks.rb +1 -1
  48. data/lib/bundler/gem_version_promoter.rb +3 -3
  49. data/lib/bundler/graph.rb +2 -2
  50. data/lib/bundler/injector.rb +10 -8
  51. data/lib/bundler/inline.rb +40 -30
  52. data/lib/bundler/installer.rb +7 -14
  53. data/lib/bundler/installer/gem_installer.rb +5 -1
  54. data/lib/bundler/installer/parallel_installer.rb +4 -8
  55. data/lib/bundler/installer/standalone.rb +1 -2
  56. data/lib/bundler/lazy_specification.rb +2 -3
  57. data/lib/bundler/lockfile_parser.rb +14 -21
  58. data/lib/bundler/match_platform.rb +1 -1
  59. data/lib/bundler/mirror.rb +3 -3
  60. data/lib/bundler/plugin.rb +42 -29
  61. data/lib/bundler/plugin/api.rb +1 -1
  62. data/lib/bundler/plugin/api/source.rb +4 -6
  63. data/lib/bundler/plugin/index.rb +14 -3
  64. data/lib/bundler/plugin/installer.rb +28 -15
  65. data/lib/bundler/psyched_yaml.rb +1 -1
  66. data/lib/bundler/remote_specification.rb +0 -2
  67. data/lib/bundler/resolver.rb +72 -24
  68. data/lib/bundler/resolver/spec_group.rb +3 -2
  69. data/lib/bundler/retry.rb +2 -2
  70. data/lib/bundler/ruby_version.rb +4 -19
  71. data/lib/bundler/rubygems_ext.rb +11 -67
  72. data/lib/bundler/rubygems_gem_installer.rb +1 -1
  73. data/lib/bundler/rubygems_integration.rb +149 -399
  74. data/lib/bundler/runtime.rb +2 -9
  75. data/lib/bundler/settings.rb +22 -52
  76. data/lib/bundler/setup.rb +11 -12
  77. data/lib/bundler/shared_helpers.rb +51 -77
  78. data/lib/bundler/similarity_detector.rb +2 -2
  79. data/lib/bundler/source.rb +5 -5
  80. data/lib/bundler/source/git.rb +24 -17
  81. data/lib/bundler/source/git/git_proxy.rb +38 -41
  82. data/lib/bundler/source/metadata.rb +7 -2
  83. data/lib/bundler/source/path.rb +13 -8
  84. data/lib/bundler/source/rubygems.rb +14 -8
  85. data/lib/bundler/source/rubygems/remote.rb +2 -3
  86. data/lib/bundler/source_list.rb +9 -12
  87. data/lib/bundler/spec_set.rb +1 -6
  88. data/lib/bundler/stub_specification.rb +18 -30
  89. data/lib/bundler/templates/Executable.bundler +23 -14
  90. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
  91. data/lib/bundler/templates/newgem/Gemfile.tt +8 -0
  92. data/lib/bundler/templates/newgem/README.md.tt +4 -3
  93. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -27
  94. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +1 -1
  95. data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
  96. data/lib/bundler/ui.rb +3 -3
  97. data/lib/bundler/ui/rg_proxy.rb +1 -1
  98. data/lib/bundler/ui/shell.rb +4 -8
  99. data/lib/bundler/uri_credentials_filter.rb +7 -3
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  101. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  102. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  103. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  104. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +273 -147
  105. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  107. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  108. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  109. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  110. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  111. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
  112. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
  115. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  116. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  117. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
  118. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +270 -323
  119. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  120. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  121. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  122. data/lib/bundler/vendor/thor/lib/thor.rb +19 -4
  123. data/lib/bundler/vendor/thor/lib/thor/actions.rb +27 -12
  124. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  125. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  126. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +7 -17
  127. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +16 -7
  128. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +19 -8
  129. data/lib/bundler/vendor/thor/lib/thor/base.rb +54 -43
  130. data/lib/bundler/vendor/thor/lib/thor/command.rb +21 -14
  131. data/lib/bundler/vendor/thor/lib/thor/error.rb +78 -0
  132. data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
  133. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -0
  134. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  135. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +1 -1
  136. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
  137. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  138. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  139. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +2 -2
  140. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +20 -7
  141. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +20 -5
  142. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
  143. data/lib/bundler/vendor/thor/lib/thor/runner.rb +15 -14
  144. data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
  145. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +62 -8
  146. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +6 -2
  147. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -3
  148. data/lib/bundler/vendor/thor/lib/thor/util.rb +18 -2
  149. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  150. data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  151. data/lib/bundler/vendor/uri/lib/uri/common.rb +744 -0
  152. data/lib/bundler/vendor/uri/lib/uri/file.rb +94 -0
  153. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  154. data/lib/bundler/vendor/uri/lib/uri/generic.rb +1568 -0
  155. data/lib/bundler/vendor/uri/lib/uri/http.rb +88 -0
  156. data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  157. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  158. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +21 -0
  159. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +294 -0
  160. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
  161. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +125 -0
  162. data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  163. data/lib/bundler/vendored_fileutils.rb +1 -6
  164. data/lib/bundler/vendored_molinillo.rb +1 -1
  165. data/lib/bundler/vendored_persistent.rb +7 -5
  166. data/lib/bundler/vendored_thor.rb +2 -2
  167. data/lib/bundler/vendored_uri.rb +4 -0
  168. data/lib/bundler/version.rb +1 -20
  169. data/lib/bundler/version_ranges.rb +51 -5
  170. data/lib/bundler/vlad.rb +3 -3
  171. data/lib/bundler/worker.rb +1 -3
  172. data/lib/bundler/yaml_serializer.rb +2 -3
  173. data/man/bundle-add.1 +10 -2
  174. data/man/bundle-add.1.txt +11 -5
  175. data/man/bundle-add.ronn +7 -1
  176. data/man/bundle-binstubs.1 +2 -2
  177. data/man/bundle-binstubs.1.txt +2 -2
  178. data/man/bundle-binstubs.ronn +1 -1
  179. data/man/bundle-cache.1 +55 -0
  180. data/man/bundle-cache.1.txt +78 -0
  181. data/man/{bundle-package.ronn → bundle-cache.ronn} +15 -15
  182. data/man/bundle-check.1 +1 -1
  183. data/man/bundle-check.1.txt +6 -6
  184. data/man/bundle-clean.1 +1 -1
  185. data/man/bundle-clean.1.txt +1 -1
  186. data/man/bundle-config.1 +36 -36
  187. data/man/bundle-config.1.txt +66 -67
  188. data/man/bundle-config.ronn +42 -40
  189. data/man/bundle-doctor.1 +1 -1
  190. data/man/bundle-doctor.1.txt +1 -1
  191. data/man/bundle-exec.1 +2 -2
  192. data/man/bundle-exec.1.txt +2 -2
  193. data/man/bundle-exec.ronn +1 -1
  194. data/man/bundle-gem.1 +1 -1
  195. data/man/bundle-gem.1.txt +3 -3
  196. data/man/bundle-info.1 +1 -1
  197. data/man/bundle-info.1.txt +1 -1
  198. data/man/bundle-init.1 +2 -2
  199. data/man/bundle-init.1.txt +2 -2
  200. data/man/bundle-init.ronn +1 -1
  201. data/man/bundle-inject.1 +1 -1
  202. data/man/bundle-inject.1.txt +1 -1
  203. data/man/bundle-install.1 +8 -5
  204. data/man/bundle-install.1.txt +56 -51
  205. data/man/bundle-install.ronn +9 -4
  206. data/man/bundle-list.1 +1 -1
  207. data/man/bundle-list.1.txt +1 -1
  208. data/man/bundle-lock.1 +1 -1
  209. data/man/bundle-lock.1.txt +16 -16
  210. data/man/bundle-open.1 +1 -1
  211. data/man/bundle-open.1.txt +1 -1
  212. data/man/bundle-outdated.1 +1 -1
  213. data/man/bundle-outdated.1.txt +1 -1
  214. data/man/bundle-platform.1 +1 -1
  215. data/man/bundle-platform.1.txt +1 -1
  216. data/man/bundle-pristine.1 +1 -1
  217. data/man/bundle-pristine.1.txt +1 -1
  218. data/man/bundle-remove.1 +1 -1
  219. data/man/bundle-remove.1.txt +1 -1
  220. data/man/bundle-show.1 +1 -1
  221. data/man/bundle-show.1.txt +1 -1
  222. data/man/bundle-update.1 +4 -4
  223. data/man/bundle-update.1.txt +64 -65
  224. data/man/bundle-update.ronn +3 -3
  225. data/man/bundle-viz.1 +1 -1
  226. data/man/bundle-viz.1.txt +1 -1
  227. data/man/bundle.1 +3 -3
  228. data/man/bundle.1.txt +8 -8
  229. data/man/bundle.ronn +2 -2
  230. data/man/gemfile.5 +13 -16
  231. data/man/gemfile.5.ronn +10 -14
  232. data/man/gemfile.5.txt +104 -108
  233. data/man/index.txt +1 -1
  234. metadata +33 -108
  235. data/exe/bundle_ruby +0 -60
  236. data/lib/bundler/cli/package.rb +0 -49
  237. data/lib/bundler/compatibility_guard.rb +0 -14
  238. data/lib/bundler/gem_remote_fetcher.rb +0 -43
  239. data/lib/bundler/ssl_certs/.document +0 -1
  240. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  241. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  242. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  243. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  244. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  245. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
  246. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -12
  247. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -129
  248. data/man/bundle-package.1 +0 -55
  249. data/man/bundle-package.1.txt +0 -79
@@ -27,7 +27,7 @@ module Bundler
27
27
  end
28
28
  end
29
29
 
30
- require "bundler/deprecate"
30
+ require_relative "deprecate"
31
31
  begin
32
32
  Bundler::Deprecate.skip_during do
33
33
  require "rubygems/safe_yaml"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "uri"
4
-
5
3
  module Bundler
6
4
  # Represents a lazily loaded gem specification, where the full specification
7
5
  # is on the source server in rubygems' "quick" index. The proxy object is to
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Bundler
4
4
  class Resolver
5
- require "bundler/vendored_molinillo"
6
- require "bundler/resolver/spec_group"
5
+ require_relative "vendored_molinillo"
6
+ require_relative "resolver/spec_group"
7
7
 
8
8
  # Figures out the best possible configuration of gems that satisfies
9
9
  # the list of passed dependencies and any child dependencies without
@@ -38,8 +38,8 @@ module Bundler
38
38
  @platforms = platforms
39
39
  @gem_version_promoter = gem_version_promoter
40
40
  @allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
41
- @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.lockfile_uses_separate_rubygems_sources?
42
41
  @use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
42
+ @lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
43
43
  end
44
44
 
45
45
  def start(requirements)
@@ -48,9 +48,12 @@ module Bundler
48
48
 
49
49
  verify_gemfile_dependencies_are_found!(requirements)
50
50
  dg = @resolver.resolve(requirements, @base_dg)
51
- dg.map(&:payload).
51
+ dg.
52
+ tap {|resolved| validate_resolved_specs!(resolved) }.
53
+ map(&:payload).
52
54
  reject {|sg| sg.name.end_with?("\0") }.
53
- map(&:to_specs).flatten
55
+ map(&:to_specs).
56
+ flatten
54
57
  rescue Molinillo::VersionConflict => e
55
58
  message = version_conflict_message(e)
56
59
  raise VersionConflict.new(e.conflicts.keys.uniq, message)
@@ -72,7 +75,7 @@ module Bundler
72
75
  return unless debug?
73
76
  debug_info = yield
74
77
  debug_info = debug_info.inspect unless debug_info.is_a?(String)
75
- STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
78
+ warn debug_info.split("\n").map {|s| " " * depth + s }
76
79
  end
77
80
 
78
81
  def debug?
@@ -169,13 +172,13 @@ module Bundler
169
172
 
170
173
  def name_for_explicit_dependency_source
171
174
  Bundler.default_gemfile.basename.to_s
172
- rescue
175
+ rescue StandardError
173
176
  "Gemfile"
174
177
  end
175
178
 
176
179
  def name_for_locking_dependency_source
177
180
  Bundler.default_lockfile.basename.to_s
178
- rescue
181
+ rescue StandardError
179
182
  "Gemfile.lock"
180
183
  end
181
184
 
@@ -276,10 +279,10 @@ module Bundler
276
279
  versions_with_platforms = specs.map {|s| [s.version, s.platform] }
277
280
  message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
278
281
  message << if versions_with_platforms.any?
279
- "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
280
- else
281
- "The source does not contain any versions of '#{name}'"
282
- end
282
+ "The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}"
283
+ else
284
+ "The source does not contain any versions of '#{name}'"
285
+ end
283
286
  else
284
287
  message = "Could not find gem '#{requirement}' in any of the gem sources " \
285
288
  "listed in your Gemfile#{cache_message}."
@@ -300,9 +303,19 @@ module Bundler
300
303
  end
301
304
 
302
305
  def version_conflict_message(e)
306
+ # only show essential conflicts, if possible
307
+ conflicts = e.conflicts.dup
308
+ conflicts.delete_if do |_name, conflict|
309
+ deps = conflict.requirement_trees.map(&:last).flatten(1)
310
+ !Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
311
+ end
312
+ e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
313
+
314
+ solver_name = "Bundler"
315
+ possibility_type = "gem"
303
316
  e.message_with_trees(
304
- :solver_name => "Bundler",
305
- :possibility_type => "gem",
317
+ :solver_name => solver_name,
318
+ :possibility_type => possibility_type,
306
319
  :reduce_trees => lambda do |trees|
307
320
  # called first, because we want to reduce the amount of work required to find maximal empty sets
308
321
  trees = trees.uniq {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
@@ -314,10 +327,8 @@ module Bundler
314
327
  end.flatten(1).select do |deps|
315
328
  Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
316
329
  end.min_by(&:size)
317
- trees.reject! {|t| !maximal.include?(t.last) } if maximal
318
330
 
319
- trees = trees.sort_by {|t| t.flatten.map(&:to_s) }
320
- trees.uniq! {|t| t.flatten.map {|dep| [dep.name, dep.requirement] } }
331
+ trees.reject! {|t| !maximal.include?(t.last) } if maximal
321
332
 
322
333
  trees.sort_by {|t| t.reverse.map(&:name) }
323
334
  end,
@@ -325,7 +336,7 @@ module Bundler
325
336
  :additional_message_for_conflict => lambda do |o, name, conflict|
326
337
  if name == "bundler"
327
338
  o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
328
- other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new Bundler::VERSION)
339
+ other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
329
340
  end
330
341
 
331
342
  if name == "bundler" && other_bundler_required
@@ -352,7 +363,11 @@ module Bundler
352
363
  []
353
364
  end.compact.map(&:to_s).uniq.sort
354
365
 
355
- o << "Could not find gem '#{SharedHelpers.pretty_dependency(conflict.requirement)}'"
366
+ metadata_requirement = name.end_with?("\0")
367
+
368
+ o << "Could not find gem '" unless metadata_requirement
369
+ o << SharedHelpers.pretty_dependency(conflict.requirement)
370
+ o << "'" unless metadata_requirement
356
371
  if conflict.requirement_trees.first.size > 1
357
372
  o << ", which is required by "
358
373
  o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
@@ -360,14 +375,47 @@ module Bundler
360
375
  o << " "
361
376
 
362
377
  o << if relevant_sources.empty?
363
- "in any of the sources.\n"
364
- else
365
- "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
366
- end
378
+ "in any of the sources.\n"
379
+ elsif metadata_requirement
380
+ "is not available in #{relevant_sources.join(" or ")}"
381
+ else
382
+ "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
383
+ end
367
384
  end
368
385
  end,
369
- :version_for_spec => lambda {|spec| spec.version }
386
+ :version_for_spec => lambda {|spec| spec.version },
387
+ :incompatible_version_message_for_conflict => lambda do |name, _conflict|
388
+ if name.end_with?("\0")
389
+ %(#{solver_name} found conflicting requirements for the #{name} version:)
390
+ else
391
+ %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
392
+ end
393
+ end
370
394
  )
371
395
  end
396
+
397
+ def validate_resolved_specs!(resolved_specs)
398
+ resolved_specs.each do |v|
399
+ name = v.name
400
+ next unless sources = relevant_sources_for_vertex(v)
401
+ sources.compact!
402
+ if default_index = sources.index(@source_requirements[:default])
403
+ sources.delete_at(default_index)
404
+ end
405
+ sources.reject! {|s| s.specs[name].empty? }
406
+ sources.uniq!
407
+ next if sources.size <= 1
408
+
409
+ multisource_disabled = Bundler.feature_flag.disable_multisource?
410
+
411
+ msg = ["The gem '#{name}' was found in multiple relevant sources."]
412
+ msg.concat sources.map {|s| " * #{s}" }.sort
413
+ msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
414
+ msg = msg.join("\n")
415
+
416
+ raise SecurityError, msg if multisource_disabled
417
+ Bundler.ui.warn "Warning: #{msg}"
418
+ end
419
+ end
372
420
  end
373
421
  end
@@ -62,6 +62,7 @@ module Bundler
62
62
  end
63
63
 
64
64
  def eql?(other)
65
+ return unless other.is_a?(SpecGroup)
65
66
  name.eql?(other.name) &&
66
67
  version.eql?(other.version) &&
67
68
  source.eql?(other.source)
@@ -94,10 +95,10 @@ module Bundler
94
95
  return [] if !spec.is_a?(EndpointSpecification) && !spec.is_a?(Gem::Specification)
95
96
  dependencies = []
96
97
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
97
- dependencies << DepProxy.new(Gem::Dependency.new("ruby\0", spec.required_ruby_version), platform)
98
+ dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
98
99
  end
99
100
  if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
100
- dependencies << DepProxy.new(Gem::Dependency.new("rubygems\0", spec.required_rubygems_version), platform)
101
+ dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
101
102
  end
102
103
  dependencies
103
104
  end
data/lib/bundler/retry.rb CHANGED
@@ -35,10 +35,10 @@ module Bundler
35
35
  private
36
36
 
37
37
  def run(&block)
38
- @failed = false
38
+ @failed = false
39
39
  @current_run += 1
40
40
  @result = block.call
41
- rescue => e
41
+ rescue StandardError => e
42
42
  fail_attempt(e)
43
43
  end
44
44
 
@@ -49,7 +49,7 @@ module Bundler
49
49
  ([\d.]+) # ruby version
50
50
  (?:p(-?\d+))? # optional patchlevel
51
51
  (?:\s\((\S+)\s(.+)\))? # optional engine info
52
- /xo
52
+ /xo.freeze
53
53
 
54
54
  # Returns a RubyVersion from the given string.
55
55
  # @param [String] the version string to match.
@@ -74,7 +74,7 @@ module Bundler
74
74
  @host ||= [
75
75
  RbConfig::CONFIG["host_cpu"],
76
76
  RbConfig::CONFIG["host_vendor"],
77
- RbConfig::CONFIG["host_os"]
77
+ RbConfig::CONFIG["host_os"],
78
78
  ].join("-")
79
79
  end
80
80
 
@@ -102,24 +102,9 @@ module Bundler
102
102
  end
103
103
 
104
104
  def self.system
105
- ruby_engine = if defined?(RUBY_ENGINE) && !RUBY_ENGINE.nil?
106
- RUBY_ENGINE.dup
107
- else
108
- # not defined in ruby 1.8.7
109
- "ruby"
110
- end
111
- # :sob: mocking RUBY_VERSION breaks stuff on 1.8.7
105
+ ruby_engine = RUBY_ENGINE.dup
112
106
  ruby_version = ENV.fetch("BUNDLER_SPEC_RUBY_VERSION") { RUBY_VERSION }.dup
113
- ruby_engine_version = case ruby_engine
114
- when "ruby"
115
- ruby_version
116
- when "rbx"
117
- Rubinius::VERSION.dup
118
- when "jruby"
119
- JRUBY_VERSION.dup
120
- else
121
- RUBY_ENGINE_VERSION.dup
122
- end
107
+ ruby_engine_version = RUBY_ENGINE_VERSION.dup
123
108
  patchlevel = RUBY_PATCHLEVEL.to_s
124
109
 
125
110
  @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
@@ -2,53 +2,34 @@
2
2
 
3
3
  require "pathname"
4
4
 
5
- if defined?(Gem::QuickLoader)
6
- # Gem Prelude makes me a sad panda :'(
7
- Gem::QuickLoader.load_full_rubygems_library
8
- end
9
-
10
- require "rubygems"
11
5
  require "rubygems/specification"
12
6
 
13
- begin
14
- # Possible use in Gem::Specification#source below and require
15
- # shouldn't be deferred.
16
- require "rubygems/source"
17
- rescue LoadError
18
- # Not available before RubyGems 2.0.0, ignore
19
- nil
20
- end
7
+ # Possible use in Gem::Specification#source below and require
8
+ # shouldn't be deferred.
9
+ require "rubygems/source"
21
10
 
22
- require "bundler/match_platform"
11
+ require_relative "match_platform"
23
12
 
24
13
  module Gem
25
- @loaded_stacks = Hash.new {|h, k| h[k] = [] }
26
-
27
14
  class Specification
28
15
  attr_accessor :remote, :location, :relative_loaded_from
29
16
 
30
- if instance_methods(false).map(&:to_sym).include?(:source)
31
- remove_method :source
32
- attr_writer :source
33
- def source
34
- (defined?(@source) && @source) || Gem::Source::Installed.new
35
- end
36
- else
37
- attr_accessor :source
17
+ remove_method :source
18
+ attr_writer :source
19
+ def source
20
+ (defined?(@source) && @source) || Gem::Source::Installed.new
38
21
  end
39
22
 
40
23
  alias_method :rg_full_gem_path, :full_gem_path
41
24
  alias_method :rg_loaded_from, :loaded_from
42
25
 
43
- attr_writer :full_gem_path unless instance_methods.include?(:full_gem_path=)
44
-
45
26
  def full_gem_path
46
27
  # this cannot check source.is_a?(Bundler::Plugin::API::Source)
47
28
  # because that _could_ trip the autoload, and if there are unresolved
48
29
  # gems at that time, this method could be called inside another require,
49
30
  # thus raising with that constant being undefined. Better to check a method
50
31
  if source.respond_to?(:path) || (source.respond_to?(:bundler_plugin_api_source?) && source.bundler_plugin_api_source?)
51
- Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.untaint
32
+ Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap{|x| x.untaint if RUBY_VERSION < "2.7" }
52
33
  else
53
34
  rg_full_gem_path
54
35
  end
@@ -63,15 +44,7 @@ module Gem
63
44
  end
64
45
 
65
46
  def load_paths
66
- return full_require_paths if respond_to?(:full_require_paths)
67
-
68
- require_paths.map do |require_path|
69
- if require_path.include?(full_gem_path)
70
- require_path
71
- else
72
- File.join(full_gem_path, require_path)
73
- end
74
- end
47
+ full_require_paths
75
48
  end
76
49
 
77
50
  if method_defined?(:extension_dir)
@@ -85,10 +58,7 @@ module Gem
85
58
  end
86
59
  end
87
60
 
88
- # RubyGems 1.8+ used only.
89
- methods = instance_methods(false)
90
- gem_dir = methods.first.is_a?(String) ? "gem_dir" : :gem_dir
91
- remove_method :gem_dir if methods.include?(gem_dir)
61
+ remove_method :gem_dir if instance_methods(false).include?(:gem_dir)
92
62
  def gem_dir
93
63
  full_gem_path
94
64
  end
@@ -158,32 +128,6 @@ module Gem
158
128
  end
159
129
  out
160
130
  end
161
-
162
- # Backport of performance enhancement added to RubyGems 1.4
163
- def matches_spec?(spec)
164
- # name can be a Regexp, so use ===
165
- return false unless name === spec.name
166
- return true if requirement.none?
167
-
168
- requirement.satisfied_by?(spec.version)
169
- end unless allocate.respond_to?(:matches_spec?)
170
- end
171
-
172
- class Requirement
173
- # Backport of performance enhancement added to RubyGems 1.4
174
- def none?
175
- # note that it might be tempting to replace with with RubyGems 2.0's
176
- # improved implementation. Don't. It requires `DefaultRequirement` to be
177
- # defined, and more importantantly, these overrides are not used when the
178
- # running RubyGems defines these methods
179
- to_s == ">= 0"
180
- end unless allocate.respond_to?(:none?)
181
-
182
- # Backport of performance enhancement added to RubyGems 2.2
183
- def exact?
184
- return false unless @requirements.size == 1
185
- @requirements[0][0] == "="
186
- end unless allocate.respond_to?(:exact?)
187
131
  end
188
132
 
189
133
  class Platform
@@ -66,7 +66,7 @@ module Bundler
66
66
 
67
67
  If you wish to continue installing the downloaded gem, and are certain it does not pose a \
68
68
  security issue despite the mismatching checksum, do the following:
69
- 1. run `bundle config disable_checksum_validation true` to turn off checksum verification
69
+ 1. run `bundle config set disable_checksum_validation true` to turn off checksum verification
70
70
  2. run `bundle install`
71
71
 
72
72
  (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "monitor"
4
- require "rubygems"
5
- require "rubygems/config_file"
3
+ require "rubygems" unless defined?(Gem)
6
4
 
7
5
  module Bundler
8
6
  class RubygemsIntegration
9
7
  if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
10
8
  EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
11
9
  else
10
+ require "monitor"
11
+
12
12
  EXT_LOCK = Monitor.new
13
13
  end
14
14
 
@@ -22,6 +22,7 @@ module Bundler
22
22
 
23
23
  def initialize
24
24
  @replaced_methods = {}
25
+ backport_ext_builder_monitor
25
26
  end
26
27
 
27
28
  def version
@@ -40,14 +41,22 @@ module Bundler
40
41
  Gem::Command.build_args = args
41
42
  end
42
43
 
43
- def load_path_insert_index
44
- Gem.load_path_insert_index
45
- end
46
-
47
44
  def loaded_specs(name)
48
45
  Gem.loaded_specs[name]
49
46
  end
50
47
 
48
+ def add_to_load_path(paths)
49
+ return Gem.add_to_load_path(*paths) if Gem.respond_to?(:add_to_load_path)
50
+
51
+ if insert_index = Gem.load_path_insert_index
52
+ # Gem directories must come after -I and ENV['RUBYLIB']
53
+ $LOAD_PATH.insert(insert_index, *paths)
54
+ else
55
+ # We are probably testing in core, -I and RUBYLIB don't apply
56
+ $LOAD_PATH.unshift(*paths)
57
+ end
58
+ end
59
+
51
60
  def mark_loaded(spec)
52
61
  if spec.respond_to?(:activated=)
53
62
  current = Gem.loaded_specs[spec.name]
@@ -112,7 +121,7 @@ module Bundler
112
121
  end
113
122
 
114
123
  def configuration
115
- require "bundler/psyched_yaml"
124
+ require_relative "psyched_yaml"
116
125
  Gem.configuration
117
126
  rescue Gem::SystemExitException, LoadError => e
118
127
  Bundler.ui.error "#{e.class}: #{e.message}"
@@ -132,10 +141,20 @@ module Bundler
132
141
  end
133
142
 
134
143
  def inflate(obj)
135
- if defined?(Gem::Util)
136
- Gem::Util.inflate(obj)
144
+ require "rubygems/util"
145
+
146
+ Gem::Util.inflate(obj)
147
+ end
148
+
149
+ def correct_for_windows_path(path)
150
+ require "rubygems/util"
151
+
152
+ if Gem::Util.respond_to?(:correct_for_windows_path)
153
+ Gem::Util.correct_for_windows_path(path)
154
+ elsif path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":"
155
+ path[1..-1]
137
156
  else
138
- Gem.inflate(obj)
157
+ path
139
158
  end
140
159
  end
141
160
 
@@ -196,14 +215,6 @@ module Bundler
196
215
  Gem::MARSHAL_SPEC_DIR
197
216
  end
198
217
 
199
- def config_map
200
- Gem::ConfigMap
201
- end
202
-
203
- def repository_subdirectories
204
- %w[cache doc gems specifications]
205
- end
206
-
207
218
  def clear_paths
208
219
  Gem.clear_paths
209
220
  end
@@ -212,26 +223,14 @@ module Bundler
212
223
  Gem.bin_path(gem, bin, ver)
213
224
  end
214
225
 
215
- def path_separator
216
- File::PATH_SEPARATOR
217
- end
218
-
219
226
  def preserve_paths
220
227
  # this is a no-op outside of RubyGems 1.8
221
228
  yield
222
229
  end
223
230
 
224
231
  def loaded_gem_paths
225
- # RubyGems 2.2+ can put binary extension into dedicated folders,
226
- # therefore use RubyGems facilities to obtain their load paths.
227
- if Gem::Specification.method_defined? :full_require_paths
228
- loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
229
- loaded_gem_paths.flatten
230
- else
231
- $LOAD_PATH.select do |p|
232
- Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
233
- end
234
- end
232
+ loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
233
+ loaded_gem_paths.flatten
235
234
  end
236
235
 
237
236
  def load_plugins
@@ -250,36 +249,6 @@ module Bundler
250
249
  EXT_LOCK
251
250
  end
252
251
 
253
- def fetch_specs(all, pre, &blk)
254
- require "rubygems/spec_fetcher"
255
- specs = Gem::SpecFetcher.new.list(all, pre)
256
- specs.each { yield } if block_given?
257
- specs
258
- end
259
-
260
- def fetch_prerelease_specs
261
- fetch_specs(false, true)
262
- rescue Gem::RemoteFetcher::FetchError
263
- {} # if we can't download them, there aren't any
264
- end
265
-
266
- # TODO: This is for older versions of RubyGems... should we support the
267
- # X-Gemfile-Source header on these old versions?
268
- # Maybe the newer implementation will work on older RubyGems?
269
- # It seems difficult to keep this implementation and still send the header.
270
- def fetch_all_remote_specs(remote)
271
- old_sources = Bundler.rubygems.sources
272
- Bundler.rubygems.sources = [remote.uri.to_s]
273
- # Fetch all specs, minus prerelease specs
274
- spec_list = fetch_specs(true, false)
275
- # Then fetch the prerelease specs
276
- fetch_prerelease_specs.each {|k, v| spec_list[k].concat(v) }
277
-
278
- spec_list.values.first
279
- ensure
280
- Bundler.rubygems.sources = old_sources
281
- end
282
-
283
252
  def with_build_args(args)
284
253
  ext_lock.synchronize do
285
254
  old_args = build_args
@@ -292,22 +261,13 @@ module Bundler
292
261
  end
293
262
  end
294
263
 
295
- def install_with_build_args(args)
296
- with_build_args(args) { yield }
297
- end
298
-
299
- def gem_from_path(path, policy = nil)
300
- require "rubygems/format"
301
- Gem::Format.from_file_by_path(path, policy)
302
- end
303
-
304
264
  def spec_from_gem(path, policy = nil)
305
265
  require "rubygems/security"
306
- require "bundler/psyched_yaml"
266
+ require_relative "psyched_yaml"
307
267
  gem_from_path(path, security_policies[policy]).spec
308
268
  rescue Gem::Package::FormatError
309
269
  raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
310
- rescue Exception, Gem::Exception, Gem::Security::Exception => e
270
+ rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
311
271
  if e.is_a?(Gem::Security::Exception) ||
312
272
  e.message =~ /unknown trust policy|unsigned gem/i ||
313
273
  e.message =~ /couldn't verify (meta)?data signature/i
@@ -319,23 +279,10 @@ module Bundler
319
279
  end
320
280
  end
321
281
 
322
- def build(spec, skip_validation = false)
323
- require "rubygems/builder"
324
- Gem::Builder.new(spec).build
325
- end
326
-
327
282
  def build_gem(gem_dir, spec)
328
283
  build(spec)
329
284
  end
330
285
 
331
- def download_gem(spec, uri, path)
332
- uri = Bundler.settings.mirror_for(uri)
333
- fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
334
- Bundler::Retry.new("download gem from #{uri}").attempts do
335
- fetcher.download(spec, uri, path)
336
- end
337
- end
338
-
339
286
  def security_policy_keys
340
287
  %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
341
288
  end
@@ -359,14 +306,6 @@ module Bundler
359
306
  end
360
307
  end
361
308
 
362
- def binstubs_call_gem?
363
- true
364
- end
365
-
366
- def stubs_provide_full_functionality?
367
- false
368
- end
369
-
370
309
  def replace_gem(specs, specs_by_name)
371
310
  reverse_rubygems_kernel_mixin
372
311
 
@@ -375,7 +314,6 @@ module Bundler
375
314
  kernel = (class << ::Kernel; self; end)
376
315
  [kernel, ::Kernel].each do |kernel_class|
377
316
  redefine_method(kernel_class, :gem) do |dep, *reqs|
378
- executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
379
317
  if executables && executables.include?(File.basename(caller.first.split(":").first))
380
318
  break
381
319
  end
@@ -413,63 +351,45 @@ module Bundler
413
351
  end
414
352
  end
415
353
 
416
- def stub_source_index(specs)
417
- Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
418
- redefine_method(Gem::SourceIndex, :initialize) do |*args|
419
- @gems = {}
420
- # You're looking at this thinking: Oh! This is how I make those
421
- # rubygems deprecations go away!
422
- #
423
- # You'd be correct BUT using of this method in production code
424
- # must be approved by the rubygems team itself!
425
- #
426
- # This is your warning. If you use this and don't have approval
427
- # we can't protect you.
428
- #
429
- Deprecate.skip_during do
430
- self.spec_dirs = *args
431
- add_specs(*specs)
432
- end
433
- end
434
- end
435
-
436
354
  # Used to make bin stubs that are not created by bundler work
437
355
  # under bundler. The new Gem.bin_path only considers gems in
438
356
  # +specs+
439
- def replace_bin_path(specs, specs_by_name)
357
+ def replace_bin_path(specs_by_name)
440
358
  gem_class = (class << Gem; self; end)
441
359
 
442
360
  redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
443
361
  exec_name = args.first
362
+ raise ArgumentError, "you must supply exec_name" unless exec_name
444
363
 
445
364
  spec_with_name = specs_by_name[gem_name]
446
- spec = if exec_name
447
- if spec_with_name && spec_with_name.executables.include?(exec_name)
448
- spec_with_name
449
- else
450
- specs.find {|s| s.executables.include?(exec_name) }
451
- end
452
- else
453
- spec_with_name
454
- end
365
+ matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
366
+ spec = matching_specs_by_exec_name.delete(spec_with_name)
455
367
 
456
- unless spec
368
+ unless spec || !matching_specs_by_exec_name.empty?
457
369
  message = "can't find executable #{exec_name} for gem #{gem_name}"
458
- if !exec_name || spec_with_name.nil?
370
+ if spec_with_name.nil?
459
371
  message += ". #{gem_name} is not currently included in the bundle, " \
460
372
  "perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
461
373
  end
462
374
  raise Gem::Exception, message
463
375
  end
464
376
 
465
- raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
466
-
467
- unless spec.name == gem_name
468
- Bundler::SharedHelpers.major_deprecation 3,
377
+ unless spec
378
+ spec = matching_specs_by_exec_name.shift
379
+ warn \
469
380
  "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
470
381
  "You should run `bundle binstub #{gem_name}` " \
471
382
  "to work around a system/bundle conflict."
472
383
  end
384
+
385
+ unless matching_specs_by_exec_name.empty?
386
+ conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
387
+ warn \
388
+ "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
389
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
390
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
391
+ end
392
+
473
393
  spec
474
394
  end
475
395
 
@@ -499,13 +419,6 @@ module Bundler
499
419
  end
500
420
  end
501
421
 
502
- # Because Bundler has a static view of what specs are available,
503
- # we don't #refresh, so stub it out.
504
- def replace_refresh
505
- gem_class = (class << Gem; self; end)
506
- redefine_method(gem_class, :refresh) {}
507
- end
508
-
509
422
  # Replace or hook into RubyGems to provide a bundlerized view
510
423
  # of the world.
511
424
  def replace_entrypoints(specs)
@@ -514,33 +427,22 @@ module Bundler
514
427
  h
515
428
  end
516
429
 
430
+ Bundler.rubygems.default_stubs.each do |stub|
431
+ default_spec = stub.to_spec
432
+ default_spec_name = default_spec.name
433
+ next if specs_by_name.key?(default_spec_name)
434
+
435
+ specs << default_spec
436
+ specs_by_name[default_spec_name] = default_spec
437
+ end
438
+
517
439
  replace_gem(specs, specs_by_name)
518
440
  stub_rubygems(specs)
519
- replace_bin_path(specs, specs_by_name)
520
- replace_refresh
441
+ replace_bin_path(specs_by_name)
521
442
 
522
443
  Gem.clear_paths
523
444
  end
524
445
 
525
- # This backports the correct segment generation code from RubyGems 1.4+
526
- # by monkeypatching it into the method in RubyGems 1.3.6 and 1.3.7.
527
- def backport_segment_generation
528
- redefine_method(Gem::Version, :segments) do
529
- @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
530
- /^\d+$/ =~ s ? s.to_i : s
531
- end
532
- end
533
- end
534
-
535
- # This backport fixes the marshaling of @segments.
536
- def backport_yaml_initialize
537
- redefine_method(Gem::Version, :yaml_initialize) do |_, map|
538
- @version = map["version"]
539
- @segments = nil
540
- @hash = nil
541
- end
542
- end
543
-
544
446
  # This backports base_dir which replaces installation path
545
447
  # RubyGems 1.8+
546
448
  def backport_base_dir
@@ -613,286 +515,134 @@ module Bundler
613
515
  end
614
516
  end
615
517
 
616
- # RubyGems 1.4 through 1.6
617
- class Legacy < RubygemsIntegration
618
- def initialize
619
- super
620
- backport_base_dir
621
- backport_cache_file
622
- backport_spec_file
623
- backport_yaml_initialize
624
- end
625
-
626
- def stub_rubygems(specs)
627
- # RubyGems versions lower than 1.7 use SourceIndex#from_gems_in
628
- source_index_class = (class << Gem::SourceIndex; self; end)
629
- redefine_method(source_index_class, :from_gems_in) do |*args|
630
- Gem::SourceIndex.new.tap do |source_index|
631
- source_index.spec_dirs = *args
632
- source_index.add_specs(*specs)
633
- end
634
- end
635
- end
518
+ def stub_rubygems(specs)
519
+ Gem::Specification.all = specs
636
520
 
637
- def all_specs
638
- Gem.source_index.gems.values
639
- end
640
-
641
- def find_name(name)
642
- Gem.source_index.find_name(name)
643
- end
644
-
645
- def validate(spec)
646
- # These versions of RubyGems always validate in "packaging" mode,
647
- # which is too strict for the kinds of checks we care about. As a
648
- # result, validation is disabled on versions of RubyGems below 1.7.
521
+ Gem.post_reset do
522
+ Gem::Specification.all = specs
649
523
  end
650
524
 
651
- def post_reset_hooks
525
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
652
526
  []
653
527
  end
654
-
655
- def reset
656
- end
657
528
  end
658
529
 
659
- # RubyGems versions 1.3.6 and 1.3.7
660
- class Ancient < Legacy
661
- def initialize
662
- super
663
- backport_segment_generation
664
- end
530
+ def plain_specs
531
+ Gem::Specification._all
665
532
  end
666
533
 
667
- # RubyGems 1.7
668
- class Transitional < Legacy
669
- def stub_rubygems(specs)
670
- stub_source_index(specs)
671
- end
672
-
673
- def validate(spec)
674
- # Missing summary is downgraded to a warning in later versions,
675
- # so we set it to an empty string to prevent an exception here.
676
- spec.summary ||= ""
677
- RubygemsIntegration.instance_method(:validate).bind(self).call(spec)
678
- end
534
+ def plain_specs=(specs)
535
+ Gem::Specification.all = specs
679
536
  end
680
537
 
681
- # RubyGems 1.8.5-1.8.19
682
- class Modern < RubygemsIntegration
683
- def stub_rubygems(specs)
684
- Gem::Specification.all = specs
685
-
686
- Gem.post_reset do
687
- Gem::Specification.all = specs
688
- end
689
-
690
- stub_source_index(specs)
691
- end
538
+ def fetch_specs(remote, name)
539
+ path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
540
+ fetcher = gem_remote_fetcher
541
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
542
+ string = fetcher.fetch_path(path)
543
+ Bundler.load_marshal(string)
544
+ rescue Gem::RemoteFetcher::FetchError => e
545
+ # it's okay for prerelease to fail
546
+ raise e unless name == "prerelease_specs"
547
+ end
692
548
 
693
- def all_specs
694
- Gem::Specification.to_a
695
- end
549
+ def fetch_all_remote_specs(remote)
550
+ specs = fetch_specs(remote, "specs")
551
+ pres = fetch_specs(remote, "prerelease_specs") || []
696
552
 
697
- def find_name(name)
698
- Gem::Specification.find_all_by_name name
699
- end
553
+ specs.concat(pres)
700
554
  end
701
555
 
702
- # RubyGems 1.8.0 to 1.8.4
703
- class AlmostModern < Modern
704
- # RubyGems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
705
- # you call Gem::Installer#install with an :install_dir set. We have to
706
- # change it back for our sudo mode to work.
707
- def preserve_paths
708
- old_dir = gem_dir
709
- old_path = gem_path
710
- yield
711
- Gem.use_paths(old_dir, old_path)
556
+ def download_gem(spec, uri, path)
557
+ uri = Bundler.settings.mirror_for(uri)
558
+ fetcher = gem_remote_fetcher
559
+ fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
560
+ Bundler::Retry.new("download gem from #{uri}").attempts do
561
+ fetcher.download(spec, uri, path)
712
562
  end
713
563
  end
714
564
 
715
- # RubyGems 1.8.20+
716
- class MoreModern < Modern
717
- # RubyGems 1.8.20 and adds the skip_validation parameter, so that's
718
- # when we start passing it through.
719
- def build(spec, skip_validation = false)
720
- require "rubygems/builder"
721
- Gem::Builder.new(spec).build(skip_validation)
722
- end
565
+ def gem_remote_fetcher
566
+ require "resolv"
567
+ proxy = configuration[:http_proxy]
568
+ dns = Resolv::DNS.new
569
+ Gem::RemoteFetcher.new(proxy, dns)
723
570
  end
724
571
 
725
- # RubyGems 2.0
726
- class Future < RubygemsIntegration
727
- def stub_rubygems(specs)
728
- Gem::Specification.all = specs
729
-
730
- Gem.post_reset do
731
- Gem::Specification.all = specs
732
- end
733
-
734
- redefine_method((class << Gem; self; end), :finish_resolve) do |*|
735
- []
736
- end
737
- end
738
-
739
- def all_specs
740
- Gem::Specification.to_a
741
- end
572
+ def gem_from_path(path, policy = nil)
573
+ require "rubygems/package"
574
+ p = Gem::Package.new(path)
575
+ p.security_policy = policy if policy
576
+ p
577
+ end
742
578
 
743
- def find_name(name)
744
- Gem::Specification.find_all_by_name name
745
- end
579
+ def build(spec, skip_validation = false)
580
+ require "rubygems/package"
581
+ Gem::Package.build(spec, skip_validation)
582
+ end
746
583
 
747
- def fetch_specs(source, remote, name)
748
- path = source + "#{name}.#{Gem.marshal_version}.gz"
749
- fetcher = gem_remote_fetcher
750
- fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
751
- string = fetcher.fetch_path(path)
752
- Bundler.load_marshal(string)
753
- rescue Gem::RemoteFetcher::FetchError => e
754
- # it's okay for prerelease to fail
755
- raise e unless name == "prerelease_specs"
756
- end
584
+ def repository_subdirectories
585
+ Gem::REPOSITORY_SUBDIRECTORIES
586
+ end
757
587
 
758
- def fetch_all_remote_specs(remote)
759
- source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
588
+ def install_with_build_args(args)
589
+ yield
590
+ end
760
591
 
761
- specs = fetch_specs(source, remote, "specs")
762
- pres = fetch_specs(source, remote, "prerelease_specs") || []
592
+ def path_separator
593
+ Gem.path_separator
594
+ end
763
595
 
764
- specs.concat(pres)
596
+ def all_specs
597
+ require_relative "remote_specification"
598
+ Gem::Specification.stubs.map do |stub|
599
+ StubSpecification.from_stub(stub)
765
600
  end
601
+ end
766
602
 
767
- def download_gem(spec, uri, path)
768
- uri = Bundler.settings.mirror_for(uri)
769
- fetcher = gem_remote_fetcher
770
- fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
771
- Bundler::Retry.new("download gem from #{uri}").attempts do
772
- fetcher.download(spec, uri, path)
603
+ def backport_ext_builder_monitor
604
+ # So we can avoid requiring "rubygems/ext" in its entirety
605
+ Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
606
+ module Ext
773
607
  end
774
- end
775
-
776
- def gem_remote_fetcher
777
- require "resolv"
778
- proxy = configuration[:http_proxy]
779
- dns = Resolv::DNS.new
780
- Bundler::GemRemoteFetcher.new(proxy, dns)
781
- end
782
-
783
- def gem_from_path(path, policy = nil)
784
- require "rubygems/package"
785
- p = Gem::Package.new(path)
786
- p.security_policy = policy if policy
787
- p
788
- end
608
+ RB
789
609
 
790
- def build(spec, skip_validation = false)
791
- require "rubygems/package"
792
- Gem::Package.build(spec, skip_validation)
793
- end
610
+ require "rubygems/ext/builder"
794
611
 
795
- def repository_subdirectories
796
- Gem::REPOSITORY_SUBDIRECTORIES
797
- end
798
-
799
- def install_with_build_args(args)
800
- yield
801
- end
612
+ Gem::Ext::Builder.class_eval do
613
+ unless const_defined?(:CHDIR_MONITOR)
614
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
615
+ end
802
616
 
803
- def path_separator
804
- Gem.path_separator
617
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
618
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
805
619
  end
806
620
  end
807
621
 
808
- # RubyGems 2.1.0
809
- class MoreFuture < Future
810
- def initialize
811
- super
812
- backport_ext_builder_monitor
813
- end
814
-
815
- def all_specs
816
- require "bundler/remote_specification"
817
- Gem::Specification.stubs.map do |stub|
818
- StubSpecification.from_stub(stub)
819
- end
820
- end
821
-
822
- def backport_ext_builder_monitor
823
- # So we can avoid requiring "rubygems/ext" in its entirety
824
- Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
825
- module Ext
826
- end
827
- RB
828
-
829
- require "rubygems/ext/builder"
830
-
831
- Gem::Ext::Builder.class_eval do
832
- unless const_defined?(:CHDIR_MONITOR)
833
- const_set(:CHDIR_MONITOR, EXT_LOCK)
834
- end
835
-
836
- remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
837
- const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
838
- end
839
- end
622
+ def find_name(name)
623
+ Gem::Specification.stubs_for(name).map(&:to_spec)
624
+ end
840
625
 
841
- if Gem::Specification.respond_to?(:stubs_for)
842
- def find_name(name)
843
- Gem::Specification.stubs_for(name).map(&:to_spec)
844
- end
845
- else
846
- def find_name(name)
847
- Gem::Specification.stubs.find_all do |spec|
848
- spec.name == name
849
- end.map(&:to_spec)
850
- end
626
+ if Gem::Specification.respond_to?(:default_stubs)
627
+ def default_stubs
628
+ Gem::Specification.default_stubs("*.gemspec")
851
629
  end
852
-
853
- def use_gemdeps(gemfile)
854
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
855
- require "bundler/gemdeps"
856
- runtime = Bundler.setup
857
- Bundler.ui = nil
858
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
859
- [Gemdeps.new(runtime), activated_spec_names]
630
+ else
631
+ def default_stubs
632
+ Gem::Specification.send(:default_stubs, "*.gemspec")
860
633
  end
634
+ end
861
635
 
862
- if provides?(">= 2.5.2")
863
- # RubyGems-generated binstubs call Kernel#gem
864
- def binstubs_call_gem?
865
- false
866
- end
867
-
868
- # only 2.5.2+ has all of the stub methods we want to use, and since this
869
- # is a performance optimization _only_,
870
- # we'll restrict ourselves to the most
871
- # recent RG versions instead of all versions that have stubs
872
- def stubs_provide_full_functionality?
873
- true
874
- end
875
- end
636
+ def use_gemdeps(gemfile)
637
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
638
+ require_relative "gemdeps"
639
+ runtime = Bundler.setup
640
+ activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
641
+ [Gemdeps.new(runtime), activated_spec_names]
876
642
  end
877
643
  end
878
644
 
879
645
  def self.rubygems
880
- @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
881
- RubygemsIntegration::MoreFuture.new
882
- elsif RubygemsIntegration.provides?(">= 1.99.99")
883
- RubygemsIntegration::Future.new
884
- elsif RubygemsIntegration.provides?(">= 1.8.20")
885
- RubygemsIntegration::MoreModern.new
886
- elsif RubygemsIntegration.provides?(">= 1.8.5")
887
- RubygemsIntegration::Modern.new
888
- elsif RubygemsIntegration.provides?(">= 1.8.0")
889
- RubygemsIntegration::AlmostModern.new
890
- elsif RubygemsIntegration.provides?(">= 1.7.0")
891
- RubygemsIntegration::Transitional.new
892
- elsif RubygemsIntegration.provides?(">= 1.4.0")
893
- RubygemsIntegration::Legacy.new
894
- else # RubyGems 1.3.6 and 1.3.7
895
- RubygemsIntegration::Ancient.new
896
- end
646
+ @rubygems ||= RubygemsIntegration.new
897
647
  end
898
648
  end