bundler 1.17.3 → 2.1.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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +794 -570
  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 +4 -4
  10. data/lib/bundler/cli.rb +178 -140
  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 +1 -1
  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 +11 -10
  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 +32 -12
  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 +9 -7
  32. data/lib/bundler/definition.rb +35 -26
  33. data/lib/bundler/dependency.rb +16 -4
  34. data/lib/bundler/deployment.rb +1 -1
  35. data/lib/bundler/dsl.rb +16 -40
  36. data/lib/bundler/env.rb +8 -13
  37. data/lib/bundler/environment_preserver.rb +0 -1
  38. data/lib/bundler/feature_flag.rb +23 -34
  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 +40 -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 -8
  73. data/lib/bundler/rubygems_integration.rb +148 -400
  74. data/lib/bundler/runtime.rb +2 -9
  75. data/lib/bundler/settings.rb +22 -51
  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 +23 -12
  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 -2
  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 +273 -304
  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 +2 -2
  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 +17 -20
  231. data/man/gemfile.5.ronn +14 -18
  232. data/man/gemfile.5.txt +108 -112
  233. data/man/index.txt +1 -1
  234. metadata +34 -110
  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
@@ -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
@@ -10,13 +10,6 @@ module Bundler
10
10
  end
11
11
  end
12
12
 
13
- attr_reader :options
14
-
15
- def initialize(gem, options = {})
16
- @options = {}
17
- super
18
- end
19
-
20
13
  def check_executable_overwrite(filename)
21
14
  # Bundler needs to install gems regardless of binstub overwriting
22
15
  end
@@ -73,7 +66,7 @@ module Bundler
73
66
 
74
67
  If you wish to continue installing the downloaded gem, and are certain it does not pose a \
75
68
  security issue despite the mismatching checksum, do the following:
76
- 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
77
70
  2. run `bundle install`
78
71
 
79
72
  (More info: The expected SHA256 checksum was #{checksum.inspect}, but the \
@@ -1,14 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "monitor"
4
- require "rubygems"
5
- require "rubygems/config_file"
6
-
7
3
  module Bundler
8
4
  class RubygemsIntegration
9
5
  if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
10
6
  EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
11
7
  else
8
+ require "monitor"
9
+
12
10
  EXT_LOCK = Monitor.new
13
11
  end
14
12
 
@@ -22,6 +20,7 @@ module Bundler
22
20
 
23
21
  def initialize
24
22
  @replaced_methods = {}
23
+ backport_ext_builder_monitor
25
24
  end
26
25
 
27
26
  def version
@@ -40,14 +39,22 @@ module Bundler
40
39
  Gem::Command.build_args = args
41
40
  end
42
41
 
43
- def load_path_insert_index
44
- Gem.load_path_insert_index
45
- end
46
-
47
42
  def loaded_specs(name)
48
43
  Gem.loaded_specs[name]
49
44
  end
50
45
 
46
+ def add_to_load_path(paths)
47
+ return Gem.add_to_load_path(*paths) if Gem.respond_to?(:add_to_load_path)
48
+
49
+ if insert_index = Gem.load_path_insert_index
50
+ # Gem directories must come after -I and ENV['RUBYLIB']
51
+ $LOAD_PATH.insert(insert_index, *paths)
52
+ else
53
+ # We are probably testing in core, -I and RUBYLIB don't apply
54
+ $LOAD_PATH.unshift(*paths)
55
+ end
56
+ end
57
+
51
58
  def mark_loaded(spec)
52
59
  if spec.respond_to?(:activated=)
53
60
  current = Gem.loaded_specs[spec.name]
@@ -112,7 +119,7 @@ module Bundler
112
119
  end
113
120
 
114
121
  def configuration
115
- require "bundler/psyched_yaml"
122
+ require_relative "psyched_yaml"
116
123
  Gem.configuration
117
124
  rescue Gem::SystemExitException, LoadError => e
118
125
  Bundler.ui.error "#{e.class}: #{e.message}"
@@ -132,10 +139,20 @@ module Bundler
132
139
  end
133
140
 
134
141
  def inflate(obj)
135
- if defined?(Gem::Util)
136
- Gem::Util.inflate(obj)
142
+ require "rubygems/util"
143
+
144
+ Gem::Util.inflate(obj)
145
+ end
146
+
147
+ def correct_for_windows_path(path)
148
+ require "rubygems/util"
149
+
150
+ if Gem::Util.respond_to?(:correct_for_windows_path)
151
+ Gem::Util.correct_for_windows_path(path)
152
+ elsif path[0].chr == "/" && path[1].chr =~ /[a-z]/i && path[2].chr == ":"
153
+ path[1..-1]
137
154
  else
138
- Gem.inflate(obj)
155
+ path
139
156
  end
140
157
  end
141
158
 
@@ -196,14 +213,6 @@ module Bundler
196
213
  Gem::MARSHAL_SPEC_DIR
197
214
  end
198
215
 
199
- def config_map
200
- Gem::ConfigMap
201
- end
202
-
203
- def repository_subdirectories
204
- %w[cache doc gems specifications]
205
- end
206
-
207
216
  def clear_paths
208
217
  Gem.clear_paths
209
218
  end
@@ -212,26 +221,14 @@ module Bundler
212
221
  Gem.bin_path(gem, bin, ver)
213
222
  end
214
223
 
215
- def path_separator
216
- File::PATH_SEPARATOR
217
- end
218
-
219
224
  def preserve_paths
220
225
  # this is a no-op outside of RubyGems 1.8
221
226
  yield
222
227
  end
223
228
 
224
229
  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
230
+ loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
231
+ loaded_gem_paths.flatten
235
232
  end
236
233
 
237
234
  def load_plugins
@@ -250,36 +247,6 @@ module Bundler
250
247
  EXT_LOCK
251
248
  end
252
249
 
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
250
  def with_build_args(args)
284
251
  ext_lock.synchronize do
285
252
  old_args = build_args
@@ -292,22 +259,13 @@ module Bundler
292
259
  end
293
260
  end
294
261
 
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
262
  def spec_from_gem(path, policy = nil)
305
263
  require "rubygems/security"
306
- require "bundler/psyched_yaml"
264
+ require_relative "psyched_yaml"
307
265
  gem_from_path(path, security_policies[policy]).spec
308
266
  rescue Gem::Package::FormatError
309
267
  raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
310
- rescue Exception, Gem::Exception, Gem::Security::Exception => e
268
+ rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
311
269
  if e.is_a?(Gem::Security::Exception) ||
312
270
  e.message =~ /unknown trust policy|unsigned gem/i ||
313
271
  e.message =~ /couldn't verify (meta)?data signature/i
@@ -319,23 +277,10 @@ module Bundler
319
277
  end
320
278
  end
321
279
 
322
- def build(spec, skip_validation = false)
323
- require "rubygems/builder"
324
- Gem::Builder.new(spec).build
325
- end
326
-
327
280
  def build_gem(gem_dir, spec)
328
281
  build(spec)
329
282
  end
330
283
 
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
284
  def security_policy_keys
340
285
  %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
341
286
  end
@@ -359,14 +304,6 @@ module Bundler
359
304
  end
360
305
  end
361
306
 
362
- def binstubs_call_gem?
363
- true
364
- end
365
-
366
- def stubs_provide_full_functionality?
367
- false
368
- end
369
-
370
307
  def replace_gem(specs, specs_by_name)
371
308
  reverse_rubygems_kernel_mixin
372
309
 
@@ -375,7 +312,6 @@ module Bundler
375
312
  kernel = (class << ::Kernel; self; end)
376
313
  [kernel, ::Kernel].each do |kernel_class|
377
314
  redefine_method(kernel_class, :gem) do |dep, *reqs|
378
- executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
379
315
  if executables && executables.include?(File.basename(caller.first.split(":").first))
380
316
  break
381
317
  end
@@ -413,63 +349,45 @@ module Bundler
413
349
  end
414
350
  end
415
351
 
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
352
  # Used to make bin stubs that are not created by bundler work
437
353
  # under bundler. The new Gem.bin_path only considers gems in
438
354
  # +specs+
439
- def replace_bin_path(specs, specs_by_name)
355
+ def replace_bin_path(specs_by_name)
440
356
  gem_class = (class << Gem; self; end)
441
357
 
442
358
  redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
443
359
  exec_name = args.first
360
+ raise ArgumentError, "you must supply exec_name" unless exec_name
444
361
 
445
362
  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
363
+ matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
364
+ spec = matching_specs_by_exec_name.delete(spec_with_name)
455
365
 
456
- unless spec
366
+ unless spec || !matching_specs_by_exec_name.empty?
457
367
  message = "can't find executable #{exec_name} for gem #{gem_name}"
458
- if !exec_name || spec_with_name.nil?
368
+ if spec_with_name.nil?
459
369
  message += ". #{gem_name} is not currently included in the bundle, " \
460
370
  "perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
461
371
  end
462
372
  raise Gem::Exception, message
463
373
  end
464
374
 
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 2,
375
+ unless spec
376
+ spec = matching_specs_by_exec_name.shift
377
+ warn \
469
378
  "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
470
379
  "You should run `bundle binstub #{gem_name}` " \
471
380
  "to work around a system/bundle conflict."
472
381
  end
382
+
383
+ unless matching_specs_by_exec_name.empty?
384
+ conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
385
+ warn \
386
+ "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
387
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
388
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
389
+ end
390
+
473
391
  spec
474
392
  end
475
393
 
@@ -499,13 +417,6 @@ module Bundler
499
417
  end
500
418
  end
501
419
 
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
420
  # Replace or hook into RubyGems to provide a bundlerized view
510
421
  # of the world.
511
422
  def replace_entrypoints(specs)
@@ -514,33 +425,22 @@ module Bundler
514
425
  h
515
426
  end
516
427
 
428
+ Bundler.rubygems.default_stubs.each do |stub|
429
+ default_spec = stub.to_spec
430
+ default_spec_name = default_spec.name
431
+ next if specs_by_name.key?(default_spec_name)
432
+
433
+ specs << default_spec
434
+ specs_by_name[default_spec_name] = default_spec
435
+ end
436
+
517
437
  replace_gem(specs, specs_by_name)
518
438
  stub_rubygems(specs)
519
- replace_bin_path(specs, specs_by_name)
520
- replace_refresh
439
+ replace_bin_path(specs_by_name)
521
440
 
522
441
  Gem.clear_paths
523
442
  end
524
443
 
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
444
  # This backports base_dir which replaces installation path
545
445
  # RubyGems 1.8+
546
446
  def backport_base_dir
@@ -613,286 +513,134 @@ module Bundler
613
513
  end
614
514
  end
615
515
 
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
636
-
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
516
+ def stub_rubygems(specs)
517
+ Gem::Specification.all = specs
644
518
 
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.
519
+ Gem.post_reset do
520
+ Gem::Specification.all = specs
649
521
  end
650
522
 
651
- def post_reset_hooks
523
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
652
524
  []
653
525
  end
654
-
655
- def reset
656
- end
657
526
  end
658
527
 
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
528
+ def plain_specs
529
+ Gem::Specification._all
665
530
  end
666
531
 
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
532
+ def plain_specs=(specs)
533
+ Gem::Specification.all = specs
679
534
  end
680
535
 
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
536
+ def fetch_specs(remote, name)
537
+ path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
538
+ fetcher = gem_remote_fetcher
539
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
540
+ string = fetcher.fetch_path(path)
541
+ Bundler.load_marshal(string)
542
+ rescue Gem::RemoteFetcher::FetchError => e
543
+ # it's okay for prerelease to fail
544
+ raise e unless name == "prerelease_specs"
545
+ end
692
546
 
693
- def all_specs
694
- Gem::Specification.to_a
695
- end
547
+ def fetch_all_remote_specs(remote)
548
+ specs = fetch_specs(remote, "specs")
549
+ pres = fetch_specs(remote, "prerelease_specs") || []
696
550
 
697
- def find_name(name)
698
- Gem::Specification.find_all_by_name name
699
- end
551
+ specs.concat(pres)
700
552
  end
701
553
 
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)
554
+ def download_gem(spec, uri, path)
555
+ uri = Bundler.settings.mirror_for(uri)
556
+ fetcher = gem_remote_fetcher
557
+ fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
558
+ Bundler::Retry.new("download gem from #{uri}").attempts do
559
+ fetcher.download(spec, uri, path)
712
560
  end
713
561
  end
714
562
 
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
563
+ def gem_remote_fetcher
564
+ require "resolv"
565
+ proxy = configuration[:http_proxy]
566
+ dns = Resolv::DNS.new
567
+ Gem::RemoteFetcher.new(proxy, dns)
723
568
  end
724
569
 
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
570
+ def gem_from_path(path, policy = nil)
571
+ require "rubygems/package"
572
+ p = Gem::Package.new(path)
573
+ p.security_policy = policy if policy
574
+ p
575
+ end
742
576
 
743
- def find_name(name)
744
- Gem::Specification.find_all_by_name name
745
- end
577
+ def build(spec, skip_validation = false)
578
+ require "rubygems/package"
579
+ Gem::Package.build(spec, skip_validation)
580
+ end
746
581
 
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
582
+ def repository_subdirectories
583
+ Gem::REPOSITORY_SUBDIRECTORIES
584
+ end
757
585
 
758
- def fetch_all_remote_specs(remote)
759
- source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
586
+ def install_with_build_args(args)
587
+ yield
588
+ end
760
589
 
761
- specs = fetch_specs(source, remote, "specs")
762
- pres = fetch_specs(source, remote, "prerelease_specs") || []
590
+ def path_separator
591
+ Gem.path_separator
592
+ end
763
593
 
764
- specs.concat(pres)
594
+ def all_specs
595
+ require_relative "remote_specification"
596
+ Gem::Specification.stubs.map do |stub|
597
+ StubSpecification.from_stub(stub)
765
598
  end
599
+ end
766
600
 
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)
601
+ def backport_ext_builder_monitor
602
+ # So we can avoid requiring "rubygems/ext" in its entirety
603
+ Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
604
+ module Ext
773
605
  end
774
- end
606
+ RB
775
607
 
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
+ require "rubygems/ext/builder"
789
609
 
790
- def build(spec, skip_validation = false)
791
- require "rubygems/package"
792
- Gem::Package.build(spec, skip_validation)
793
- end
794
-
795
- def repository_subdirectories
796
- Gem::REPOSITORY_SUBDIRECTORIES
797
- end
798
-
799
- def install_with_build_args(args)
800
- yield
801
- end
610
+ Gem::Ext::Builder.class_eval do
611
+ unless const_defined?(:CHDIR_MONITOR)
612
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
613
+ end
802
614
 
803
- def path_separator
804
- Gem.path_separator
615
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
616
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
805
617
  end
806
618
  end
807
619
 
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
620
+ def find_name(name)
621
+ Gem::Specification.stubs_for(name).map(&:to_spec)
622
+ end
840
623
 
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
624
+ if Gem::Specification.respond_to?(:default_stubs)
625
+ def default_stubs
626
+ Gem::Specification.default_stubs("*.gemspec")
851
627
  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]
628
+ else
629
+ def default_stubs
630
+ Gem::Specification.send(:default_stubs, "*.gemspec")
860
631
  end
632
+ end
861
633
 
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
634
+ def use_gemdeps(gemfile)
635
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
636
+ require_relative "gemdeps"
637
+ runtime = Bundler.setup
638
+ activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
639
+ [Gemdeps.new(runtime), activated_spec_names]
876
640
  end
877
641
  end
878
642
 
879
643
  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
644
+ @rubygems ||= RubygemsIntegration.new
897
645
  end
898
646
  end