bundler 2.0.2 → 2.1.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +687 -574
  3. data/LICENSE.md +18 -19
  4. data/README.md +8 -7
  5. data/bundler.gemspec +5 -23
  6. data/exe/bundle +19 -3
  7. data/lib/bundler.rb +121 -68
  8. data/lib/bundler/build_metadata.rb +3 -3
  9. data/lib/bundler/capistrano.rb +5 -5
  10. data/lib/bundler/cli.rb +130 -124
  11. data/lib/bundler/cli/add.rb +27 -16
  12. data/lib/bundler/cli/common.rb +10 -11
  13. data/lib/bundler/cli/config.rb +161 -86
  14. data/lib/bundler/cli/console.rb +2 -2
  15. data/lib/bundler/cli/doctor.rb +4 -4
  16. data/lib/bundler/cli/exec.rb +4 -9
  17. data/lib/bundler/cli/gem.rb +5 -5
  18. data/lib/bundler/cli/info.rb +17 -5
  19. data/lib/bundler/cli/init.rb +1 -1
  20. data/lib/bundler/cli/install.rb +3 -3
  21. data/lib/bundler/cli/issue.rb +1 -1
  22. data/lib/bundler/cli/open.rb +10 -6
  23. data/lib/bundler/cli/outdated.rb +85 -81
  24. data/lib/bundler/cli/package.rb +8 -9
  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 +8 -7
  32. data/lib/bundler/definition.rb +33 -26
  33. data/lib/bundler/dependency.rb +16 -4
  34. data/lib/bundler/deployment.rb +2 -2
  35. data/lib/bundler/dsl.rb +18 -42
  36. data/lib/bundler/env.rb +6 -5
  37. data/lib/bundler/environment_preserver.rb +0 -1
  38. data/lib/bundler/feature_flag.rb +0 -12
  39. data/lib/bundler/fetcher.rb +14 -11
  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 +3 -0
  43. data/lib/bundler/fetcher/index.rb +4 -2
  44. data/lib/bundler/friendly_errors.rb +4 -5
  45. data/lib/bundler/gem_helper.rb +8 -8
  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 +3 -1
  51. data/lib/bundler/inline.rb +19 -18
  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 -4
  55. data/lib/bundler/installer/standalone.rb +1 -2
  56. data/lib/bundler/lazy_specification.rb +2 -2
  57. data/lib/bundler/lockfile_parser.rb +13 -21
  58. data/lib/bundler/match_platform.rb +1 -1
  59. data/lib/bundler/plugin.rb +29 -18
  60. data/lib/bundler/plugin/api.rb +1 -1
  61. data/lib/bundler/plugin/api/source.rb +2 -2
  62. data/lib/bundler/plugin/index.rb +10 -2
  63. data/lib/bundler/plugin/installer.rb +28 -15
  64. data/lib/bundler/psyched_yaml.rb +1 -1
  65. data/lib/bundler/resolver.rb +72 -24
  66. data/lib/bundler/resolver/spec_group.rb +2 -2
  67. data/lib/bundler/retry.rb +2 -2
  68. data/lib/bundler/ruby_version.rb +4 -19
  69. data/lib/bundler/rubygems_ext.rb +10 -65
  70. data/lib/bundler/rubygems_gem_installer.rb +1 -1
  71. data/lib/bundler/rubygems_integration.rb +135 -403
  72. data/lib/bundler/runtime.rb +2 -9
  73. data/lib/bundler/settings.rb +15 -48
  74. data/lib/bundler/setup.rb +6 -5
  75. data/lib/bundler/shared_helpers.rb +53 -68
  76. data/lib/bundler/similarity_detector.rb +2 -2
  77. data/lib/bundler/source.rb +5 -5
  78. data/lib/bundler/source/git.rb +19 -12
  79. data/lib/bundler/source/git/git_proxy.rb +35 -39
  80. data/lib/bundler/source/metadata.rb +7 -2
  81. data/lib/bundler/source/path.rb +13 -8
  82. data/lib/bundler/source/rubygems.rb +11 -5
  83. data/lib/bundler/source/rubygems/remote.rb +1 -2
  84. data/lib/bundler/source_list.rb +9 -12
  85. data/lib/bundler/spec_set.rb +1 -6
  86. data/lib/bundler/stub_specification.rb +18 -30
  87. data/lib/bundler/templates/Executable.bundler +22 -13
  88. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
  89. data/lib/bundler/templates/newgem/Gemfile.tt +8 -0
  90. data/lib/bundler/templates/newgem/README.md.tt +4 -3
  91. data/lib/bundler/templates/newgem/newgem.gemspec.tt +2 -18
  92. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +0 -4
  93. data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
  94. data/lib/bundler/ui.rb +3 -3
  95. data/lib/bundler/ui/rg_proxy.rb +1 -1
  96. data/lib/bundler/ui/shell.rb +4 -8
  97. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  98. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  99. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  101. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1 -1
  102. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
  103. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  104. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  105. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  107. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  108. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
  109. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  110. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  111. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
  112. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
  115. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +248 -279
  116. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  117. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  118. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  119. data/lib/bundler/vendor/thor/lib/thor.rb +1 -1
  120. data/lib/bundler/vendor/thor/lib/thor/actions.rb +7 -7
  121. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  122. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  123. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
  124. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -1
  125. data/lib/bundler/vendor/thor/lib/thor/base.rb +13 -13
  126. data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
  127. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  128. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  129. data/lib/bundler/vendor/thor/lib/thor/runner.rb +4 -4
  130. data/lib/bundler/vendor/thor/lib/thor/shell.rb +3 -3
  131. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
  132. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
  133. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  134. data/lib/bundler/vendored_fileutils.rb +1 -6
  135. data/lib/bundler/vendored_molinillo.rb +1 -1
  136. data/lib/bundler/vendored_persistent.rb +7 -5
  137. data/lib/bundler/vendored_thor.rb +2 -2
  138. data/lib/bundler/version.rb +1 -20
  139. data/lib/bundler/version_ranges.rb +51 -5
  140. data/lib/bundler/vlad.rb +3 -3
  141. data/lib/bundler/worker.rb +1 -3
  142. data/lib/bundler/yaml_serializer.rb +2 -3
  143. data/man/bundle-add.1 +10 -2
  144. data/man/bundle-add.1.txt +11 -5
  145. data/man/bundle-add.ronn +7 -1
  146. data/man/bundle-binstubs.1 +2 -2
  147. data/man/bundle-binstubs.1.txt +2 -2
  148. data/man/bundle-binstubs.ronn +1 -1
  149. data/man/bundle-check.1 +1 -1
  150. data/man/bundle-check.1.txt +6 -6
  151. data/man/bundle-clean.1 +1 -1
  152. data/man/bundle-clean.1.txt +1 -1
  153. data/man/bundle-config.1 +35 -35
  154. data/man/bundle-config.1.txt +65 -66
  155. data/man/bundle-config.ronn +41 -39
  156. data/man/bundle-doctor.1 +1 -1
  157. data/man/bundle-doctor.1.txt +1 -1
  158. data/man/bundle-exec.1 +1 -1
  159. data/man/bundle-exec.1.txt +1 -1
  160. data/man/bundle-gem.1 +1 -1
  161. data/man/bundle-gem.1.txt +3 -3
  162. data/man/bundle-info.1 +1 -1
  163. data/man/bundle-info.1.txt +1 -1
  164. data/man/bundle-init.1 +1 -1
  165. data/man/bundle-init.1.txt +1 -1
  166. data/man/bundle-inject.1 +1 -1
  167. data/man/bundle-inject.1.txt +1 -1
  168. data/man/bundle-install.1 +8 -5
  169. data/man/bundle-install.1.txt +56 -51
  170. data/man/bundle-install.ronn +9 -4
  171. data/man/bundle-list.1 +1 -1
  172. data/man/bundle-list.1.txt +1 -1
  173. data/man/bundle-lock.1 +1 -1
  174. data/man/bundle-lock.1.txt +16 -16
  175. data/man/bundle-open.1 +1 -1
  176. data/man/bundle-open.1.txt +1 -1
  177. data/man/bundle-outdated.1 +1 -1
  178. data/man/bundle-outdated.1.txt +1 -1
  179. data/man/bundle-package.1 +1 -1
  180. data/man/bundle-package.1.txt +1 -1
  181. data/man/bundle-platform.1 +1 -1
  182. data/man/bundle-platform.1.txt +1 -1
  183. data/man/bundle-pristine.1 +1 -1
  184. data/man/bundle-pristine.1.txt +1 -1
  185. data/man/bundle-remove.1 +1 -1
  186. data/man/bundle-remove.1.txt +1 -1
  187. data/man/bundle-show.1 +1 -1
  188. data/man/bundle-show.1.txt +1 -1
  189. data/man/bundle-update.1 +4 -4
  190. data/man/bundle-update.1.txt +64 -65
  191. data/man/bundle-update.ronn +3 -3
  192. data/man/bundle-viz.1 +1 -1
  193. data/man/bundle-viz.1.txt +1 -1
  194. data/man/bundle.1 +2 -2
  195. data/man/bundle.1.txt +7 -7
  196. data/man/bundle.ronn +1 -1
  197. data/man/gemfile.5 +12 -15
  198. data/man/gemfile.5.ronn +9 -13
  199. data/man/gemfile.5.txt +103 -107
  200. metadata +11 -112
  201. data/exe/bundle_ruby +0 -60
  202. data/lib/bundler/cli/cache.rb +0 -36
  203. data/lib/bundler/compatibility_guard.rb +0 -13
  204. data/lib/bundler/ssl_certs/.document +0 -1
  205. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  206. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  207. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  208. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  209. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  210. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
@@ -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,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "monitor"
4
-
5
3
  module Bundler
6
4
  class RubygemsIntegration
7
5
  if defined?(Gem::Ext::Builder::CHDIR_MONITOR)
8
6
  EXT_LOCK = Gem::Ext::Builder::CHDIR_MONITOR
9
7
  else
8
+ require "monitor"
9
+
10
10
  EXT_LOCK = Monitor.new
11
11
  end
12
12
 
@@ -20,6 +20,7 @@ module Bundler
20
20
 
21
21
  def initialize
22
22
  @replaced_methods = {}
23
+ backport_ext_builder_monitor
23
24
  end
24
25
 
25
26
  def version
@@ -38,14 +39,22 @@ module Bundler
38
39
  Gem::Command.build_args = args
39
40
  end
40
41
 
41
- def load_path_insert_index
42
- Gem.load_path_insert_index
43
- end
44
-
45
42
  def loaded_specs(name)
46
43
  Gem.loaded_specs[name]
47
44
  end
48
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
+
49
58
  def mark_loaded(spec)
50
59
  if spec.respond_to?(:activated=)
51
60
  current = Gem.loaded_specs[spec.name]
@@ -110,7 +119,7 @@ module Bundler
110
119
  end
111
120
 
112
121
  def configuration
113
- require "bundler/psyched_yaml"
122
+ require_relative "psyched_yaml"
114
123
  Gem.configuration
115
124
  rescue Gem::SystemExitException, LoadError => e
116
125
  Bundler.ui.error "#{e.class}: #{e.message}"
@@ -130,10 +139,20 @@ module Bundler
130
139
  end
131
140
 
132
141
  def inflate(obj)
133
- if defined?(Gem::Util)
134
- 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]
135
154
  else
136
- Gem.inflate(obj)
155
+ path
137
156
  end
138
157
  end
139
158
 
@@ -194,14 +213,6 @@ module Bundler
194
213
  Gem::MARSHAL_SPEC_DIR
195
214
  end
196
215
 
197
- def config_map
198
- Gem::ConfigMap
199
- end
200
-
201
- def repository_subdirectories
202
- %w[cache doc gems specifications]
203
- end
204
-
205
216
  def clear_paths
206
217
  Gem.clear_paths
207
218
  end
@@ -210,26 +221,14 @@ module Bundler
210
221
  Gem.bin_path(gem, bin, ver)
211
222
  end
212
223
 
213
- def path_separator
214
- File::PATH_SEPARATOR
215
- end
216
-
217
224
  def preserve_paths
218
225
  # this is a no-op outside of RubyGems 1.8
219
226
  yield
220
227
  end
221
228
 
222
229
  def loaded_gem_paths
223
- # RubyGems 2.2+ can put binary extension into dedicated folders,
224
- # therefore use RubyGems facilities to obtain their load paths.
225
- if Gem::Specification.method_defined? :full_require_paths
226
- loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
227
- loaded_gem_paths.flatten
228
- else
229
- $LOAD_PATH.select do |p|
230
- Bundler.rubygems.gem_path.any? {|gp| p =~ /^#{Regexp.escape(gp)}/ }
231
- end
232
- end
230
+ loaded_gem_paths = Gem.loaded_specs.map {|_, s| s.full_require_paths }
231
+ loaded_gem_paths.flatten
233
232
  end
234
233
 
235
234
  def load_plugins
@@ -248,36 +247,12 @@ module Bundler
248
247
  EXT_LOCK
249
248
  end
250
249
 
251
- def fetch_specs(all, pre, &blk)
252
- require "rubygems/spec_fetcher"
253
- specs = Gem::SpecFetcher.new.list(all, pre)
254
- specs.each { yield } if block_given?
255
- specs
256
- end
257
-
258
250
  def fetch_prerelease_specs
259
251
  fetch_specs(false, true)
260
252
  rescue Gem::RemoteFetcher::FetchError
261
253
  {} # if we can't download them, there aren't any
262
254
  end
263
255
 
264
- # TODO: This is for older versions of RubyGems... should we support the
265
- # X-Gemfile-Source header on these old versions?
266
- # Maybe the newer implementation will work on older RubyGems?
267
- # It seems difficult to keep this implementation and still send the header.
268
- def fetch_all_remote_specs(remote)
269
- old_sources = Bundler.rubygems.sources
270
- Bundler.rubygems.sources = [remote.uri.to_s]
271
- # Fetch all specs, minus prerelease specs
272
- spec_list = fetch_specs(true, false)
273
- # Then fetch the prerelease specs
274
- fetch_prerelease_specs.each {|k, v| spec_list[k].concat(v) }
275
-
276
- spec_list.values.first
277
- ensure
278
- Bundler.rubygems.sources = old_sources
279
- end
280
-
281
256
  def with_build_args(args)
282
257
  ext_lock.synchronize do
283
258
  old_args = build_args
@@ -290,22 +265,13 @@ module Bundler
290
265
  end
291
266
  end
292
267
 
293
- def install_with_build_args(args)
294
- with_build_args(args) { yield }
295
- end
296
-
297
- def gem_from_path(path, policy = nil)
298
- require "rubygems/format"
299
- Gem::Format.from_file_by_path(path, policy)
300
- end
301
-
302
268
  def spec_from_gem(path, policy = nil)
303
269
  require "rubygems/security"
304
- require "bundler/psyched_yaml"
270
+ require_relative "psyched_yaml"
305
271
  gem_from_path(path, security_policies[policy]).spec
306
272
  rescue Gem::Package::FormatError
307
273
  raise GemspecError, "Could not read gem at #{path}. It may be corrupted."
308
- rescue Exception, Gem::Exception, Gem::Security::Exception => e
274
+ rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
309
275
  if e.is_a?(Gem::Security::Exception) ||
310
276
  e.message =~ /unknown trust policy|unsigned gem/i ||
311
277
  e.message =~ /couldn't verify (meta)?data signature/i
@@ -317,23 +283,10 @@ module Bundler
317
283
  end
318
284
  end
319
285
 
320
- def build(spec, skip_validation = false)
321
- require "rubygems/builder"
322
- Gem::Builder.new(spec).build
323
- end
324
-
325
286
  def build_gem(gem_dir, spec)
326
287
  build(spec)
327
288
  end
328
289
 
329
- def download_gem(spec, uri, path)
330
- uri = Bundler.settings.mirror_for(uri)
331
- fetcher = Gem::RemoteFetcher.new(configuration[:http_proxy])
332
- Bundler::Retry.new("download gem from #{uri}").attempts do
333
- fetcher.download(spec, uri, path)
334
- end
335
- end
336
-
337
290
  def security_policy_keys
338
291
  %w[High Medium Low AlmostNo No].map {|level| "#{level}Security" }
339
292
  end
@@ -357,14 +310,6 @@ module Bundler
357
310
  end
358
311
  end
359
312
 
360
- def binstubs_call_gem?
361
- true
362
- end
363
-
364
- def stubs_provide_full_functionality?
365
- false
366
- end
367
-
368
313
  def replace_gem(specs, specs_by_name)
369
314
  reverse_rubygems_kernel_mixin
370
315
 
@@ -373,7 +318,6 @@ module Bundler
373
318
  kernel = (class << ::Kernel; self; end)
374
319
  [kernel, ::Kernel].each do |kernel_class|
375
320
  redefine_method(kernel_class, :gem) do |dep, *reqs|
376
- executables ||= specs.map(&:executables).flatten if ::Bundler.rubygems.binstubs_call_gem?
377
321
  if executables && executables.include?(File.basename(caller.first.split(":").first))
378
322
  break
379
323
  end
@@ -411,63 +355,45 @@ module Bundler
411
355
  end
412
356
  end
413
357
 
414
- def stub_source_index(specs)
415
- Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
416
- redefine_method(Gem::SourceIndex, :initialize) do |*args|
417
- @gems = {}
418
- # You're looking at this thinking: Oh! This is how I make those
419
- # rubygems deprecations go away!
420
- #
421
- # You'd be correct BUT using of this method in production code
422
- # must be approved by the rubygems team itself!
423
- #
424
- # This is your warning. If you use this and don't have approval
425
- # we can't protect you.
426
- #
427
- Deprecate.skip_during do
428
- self.spec_dirs = *args
429
- add_specs(*specs)
430
- end
431
- end
432
- end
433
-
434
358
  # Used to make bin stubs that are not created by bundler work
435
359
  # under bundler. The new Gem.bin_path only considers gems in
436
360
  # +specs+
437
- def replace_bin_path(specs, specs_by_name)
361
+ def replace_bin_path(specs_by_name)
438
362
  gem_class = (class << Gem; self; end)
439
363
 
440
364
  redefine_method(gem_class, :find_spec_for_exe) do |gem_name, *args|
441
365
  exec_name = args.first
366
+ raise ArgumentError, "you must supply exec_name" unless exec_name
442
367
 
443
368
  spec_with_name = specs_by_name[gem_name]
444
- spec = if exec_name
445
- if spec_with_name && spec_with_name.executables.include?(exec_name)
446
- spec_with_name
447
- else
448
- specs.find {|s| s.executables.include?(exec_name) }
449
- end
450
- else
451
- spec_with_name
452
- end
369
+ matching_specs_by_exec_name = specs_by_name.values.select {|s| s.executables.include?(exec_name) }
370
+ spec = matching_specs_by_exec_name.delete(spec_with_name)
453
371
 
454
- unless spec
372
+ unless spec || !matching_specs_by_exec_name.empty?
455
373
  message = "can't find executable #{exec_name} for gem #{gem_name}"
456
- if !exec_name || spec_with_name.nil?
374
+ if spec_with_name.nil?
457
375
  message += ". #{gem_name} is not currently included in the bundle, " \
458
376
  "perhaps you meant to add it to your #{Bundler.default_gemfile.basename}?"
459
377
  end
460
378
  raise Gem::Exception, message
461
379
  end
462
380
 
463
- raise Gem::Exception, "no default executable for #{spec.full_name}" unless exec_name ||= spec.default_executable
464
-
465
- unless spec.name == gem_name
466
- Bundler::SharedHelpers.major_deprecation 3,
381
+ unless spec
382
+ spec = matching_specs_by_exec_name.shift
383
+ warn \
467
384
  "Bundler is using a binstub that was created for a different gem (#{spec.name}).\n" \
468
385
  "You should run `bundle binstub #{gem_name}` " \
469
386
  "to work around a system/bundle conflict."
470
387
  end
388
+
389
+ unless matching_specs_by_exec_name.empty?
390
+ conflicting_names = matching_specs_by_exec_name.map(&:name).join(", ")
391
+ warn \
392
+ "The `#{exec_name}` executable in the `#{spec.name}` gem is being loaded, but it's also present in other gems (#{conflicting_names}).\n" \
393
+ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \
394
+ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names."
395
+ end
396
+
471
397
  spec
472
398
  end
473
399
 
@@ -497,13 +423,6 @@ module Bundler
497
423
  end
498
424
  end
499
425
 
500
- # Because Bundler has a static view of what specs are available,
501
- # we don't #refresh, so stub it out.
502
- def replace_refresh
503
- gem_class = (class << Gem; self; end)
504
- redefine_method(gem_class, :refresh) {}
505
- end
506
-
507
426
  # Replace or hook into RubyGems to provide a bundlerized view
508
427
  # of the world.
509
428
  def replace_entrypoints(specs)
@@ -523,31 +442,11 @@ module Bundler
523
442
 
524
443
  replace_gem(specs, specs_by_name)
525
444
  stub_rubygems(specs)
526
- replace_bin_path(specs, specs_by_name)
527
- replace_refresh
445
+ replace_bin_path(specs_by_name)
528
446
 
529
447
  Gem.clear_paths
530
448
  end
531
449
 
532
- # This backports the correct segment generation code from RubyGems 1.4+
533
- # by monkeypatching it into the method in RubyGems 1.3.6 and 1.3.7.
534
- def backport_segment_generation
535
- redefine_method(Gem::Version, :segments) do
536
- @segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
537
- /^\d+$/ =~ s ? s.to_i : s
538
- end
539
- end
540
- end
541
-
542
- # This backport fixes the marshaling of @segments.
543
- def backport_yaml_initialize
544
- redefine_method(Gem::Version, :yaml_initialize) do |_, map|
545
- @version = map["version"]
546
- @segments = nil
547
- @hash = nil
548
- end
549
- end
550
-
551
450
  # This backports base_dir which replaces installation path
552
451
  # RubyGems 1.8+
553
452
  def backport_base_dir
@@ -620,296 +519,129 @@ module Bundler
620
519
  end
621
520
  end
622
521
 
623
- # RubyGems 1.4 through 1.6
624
- class Legacy < RubygemsIntegration
625
- def initialize
626
- super
627
- backport_base_dir
628
- backport_cache_file
629
- backport_spec_file
630
- backport_yaml_initialize
631
- end
522
+ def stub_rubygems(specs)
523
+ Gem::Specification.all = specs
632
524
 
633
- def stub_rubygems(specs)
634
- # RubyGems versions lower than 1.7 use SourceIndex#from_gems_in
635
- source_index_class = (class << Gem::SourceIndex; self; end)
636
- redefine_method(source_index_class, :from_gems_in) do |*args|
637
- Gem::SourceIndex.new.tap do |source_index|
638
- source_index.spec_dirs = *args
639
- source_index.add_specs(*specs)
640
- end
641
- end
525
+ Gem.post_reset do
526
+ Gem::Specification.all = specs
642
527
  end
643
528
 
644
- def all_specs
645
- Gem.source_index.gems.values
529
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
530
+ []
646
531
  end
532
+ end
647
533
 
648
- def find_name(name)
649
- Gem.source_index.find_name(name)
650
- end
534
+ def fetch_specs(source, remote, name)
535
+ path = source + "#{name}.#{Gem.marshal_version}.gz"
536
+ fetcher = gem_remote_fetcher
537
+ fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
538
+ string = fetcher.fetch_path(path)
539
+ Bundler.load_marshal(string)
540
+ rescue Gem::RemoteFetcher::FetchError => e
541
+ # it's okay for prerelease to fail
542
+ raise e unless name == "prerelease_specs"
543
+ end
651
544
 
652
- def validate(spec)
653
- # These versions of RubyGems always validate in "packaging" mode,
654
- # which is too strict for the kinds of checks we care about. As a
655
- # result, validation is disabled on versions of RubyGems below 1.7.
656
- end
545
+ def fetch_all_remote_specs(remote)
546
+ source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
657
547
 
658
- def post_reset_hooks
659
- []
660
- end
548
+ specs = fetch_specs(source, remote, "specs")
549
+ pres = fetch_specs(source, remote, "prerelease_specs") || []
661
550
 
662
- def reset
663
- end
551
+ specs.concat(pres)
664
552
  end
665
553
 
666
- # RubyGems versions 1.3.6 and 1.3.7
667
- class Ancient < Legacy
668
- def initialize
669
- super
670
- backport_segment_generation
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)
671
560
  end
672
561
  end
673
562
 
674
- # RubyGems 1.7
675
- class Transitional < Legacy
676
- def stub_rubygems(specs)
677
- stub_source_index(specs)
678
- end
679
-
680
- def validate(spec)
681
- # Missing summary is downgraded to a warning in later versions,
682
- # so we set it to an empty string to prevent an exception here.
683
- spec.summary ||= ""
684
- RubygemsIntegration.instance_method(:validate).bind(self).call(spec)
685
- end
563
+ def gem_remote_fetcher
564
+ require "resolv"
565
+ proxy = configuration[:http_proxy]
566
+ dns = Resolv::DNS.new
567
+ Bundler::GemRemoteFetcher.new(proxy, dns)
686
568
  end
687
569
 
688
- # RubyGems 1.8.5-1.8.19
689
- class Modern < RubygemsIntegration
690
- def stub_rubygems(specs)
691
- Gem::Specification.all = specs
692
-
693
- Gem.post_reset do
694
- Gem::Specification.all = specs
695
- 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
696
576
 
697
- stub_source_index(specs)
698
- end
577
+ def build(spec, skip_validation = false)
578
+ require "rubygems/package"
579
+ Gem::Package.build(spec, skip_validation)
580
+ end
699
581
 
700
- def all_specs
701
- Gem::Specification.to_a
702
- end
582
+ def repository_subdirectories
583
+ Gem::REPOSITORY_SUBDIRECTORIES
584
+ end
703
585
 
704
- def find_name(name)
705
- Gem::Specification.find_all_by_name name
706
- end
586
+ def install_with_build_args(args)
587
+ yield
707
588
  end
708
589
 
709
- # RubyGems 1.8.0 to 1.8.4
710
- class AlmostModern < Modern
711
- # RubyGems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
712
- # you call Gem::Installer#install with an :install_dir set. We have to
713
- # change it back for our sudo mode to work.
714
- def preserve_paths
715
- old_dir = gem_dir
716
- old_path = gem_path
717
- yield
718
- Gem.use_paths(old_dir, old_path)
719
- end
590
+ def path_separator
591
+ Gem.path_separator
720
592
  end
721
593
 
722
- # RubyGems 1.8.20+
723
- class MoreModern < Modern
724
- # RubyGems 1.8.20 and adds the skip_validation parameter, so that's
725
- # when we start passing it through.
726
- def build(spec, skip_validation = false)
727
- require "rubygems/builder"
728
- Gem::Builder.new(spec).build(skip_validation)
594
+ def all_specs
595
+ require_relative "remote_specification"
596
+ Gem::Specification.stubs.map do |stub|
597
+ StubSpecification.from_stub(stub)
729
598
  end
730
599
  end
731
600
 
732
- # RubyGems 2.0
733
- class Future < RubygemsIntegration
734
- def stub_rubygems(specs)
735
- Gem::Specification.all = specs
736
-
737
- Gem.post_reset do
738
- Gem::Specification.all = specs
739
- end
740
-
741
- redefine_method((class << Gem; self; end), :finish_resolve) do |*|
742
- []
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
743
605
  end
744
- end
745
-
746
- def all_specs
747
- Gem::Specification.to_a
748
- end
749
-
750
- def find_name(name)
751
- Gem::Specification.find_all_by_name name
752
- end
606
+ RB
753
607
 
754
- def fetch_specs(source, remote, name)
755
- path = source + "#{name}.#{Gem.marshal_version}.gz"
756
- fetcher = gem_remote_fetcher
757
- fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
758
- string = fetcher.fetch_path(path)
759
- Bundler.load_marshal(string)
760
- rescue Gem::RemoteFetcher::FetchError => e
761
- # it's okay for prerelease to fail
762
- raise e unless name == "prerelease_specs"
763
- end
764
-
765
- def fetch_all_remote_specs(remote)
766
- source = remote.uri.is_a?(URI) ? remote.uri : URI.parse(source.to_s)
767
-
768
- specs = fetch_specs(source, remote, "specs")
769
- pres = fetch_specs(source, remote, "prerelease_specs") || []
770
-
771
- specs.concat(pres)
772
- end
608
+ require "rubygems/ext/builder"
773
609
 
774
- def download_gem(spec, uri, path)
775
- uri = Bundler.settings.mirror_for(uri)
776
- fetcher = gem_remote_fetcher
777
- fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
778
- Bundler::Retry.new("download gem from #{uri}").attempts do
779
- fetcher.download(spec, uri, path)
610
+ Gem::Ext::Builder.class_eval do
611
+ unless const_defined?(:CHDIR_MONITOR)
612
+ const_set(:CHDIR_MONITOR, EXT_LOCK)
780
613
  end
781
- end
782
-
783
- def gem_remote_fetcher
784
- require "resolv"
785
- proxy = configuration[:http_proxy]
786
- dns = Resolv::DNS.new
787
- Bundler::GemRemoteFetcher.new(proxy, dns)
788
- end
789
-
790
- def gem_from_path(path, policy = nil)
791
- require "rubygems/package"
792
- p = Gem::Package.new(path)
793
- p.security_policy = policy if policy
794
- p
795
- end
796
-
797
- def build(spec, skip_validation = false)
798
- require "rubygems/package"
799
- Gem::Package.build(spec, skip_validation)
800
- end
801
-
802
- def repository_subdirectories
803
- Gem::REPOSITORY_SUBDIRECTORIES
804
- end
805
-
806
- def install_with_build_args(args)
807
- yield
808
- end
809
614
 
810
- def path_separator
811
- Gem.path_separator
615
+ remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
616
+ const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
812
617
  end
813
618
  end
814
619
 
815
- # RubyGems 2.1.0
816
- class MoreFuture < Future
817
- def initialize
818
- super
819
- backport_ext_builder_monitor
820
- end
821
-
822
- def all_specs
823
- require "bundler/remote_specification"
824
- Gem::Specification.stubs.map do |stub|
825
- StubSpecification.from_stub(stub)
826
- end
827
- end
828
-
829
- def backport_ext_builder_monitor
830
- # So we can avoid requiring "rubygems/ext" in its entirety
831
- Gem.module_eval <<-RB, __FILE__, __LINE__ + 1
832
- module Ext
833
- end
834
- RB
835
-
836
- require "rubygems/ext/builder"
837
-
838
- Gem::Ext::Builder.class_eval do
839
- unless const_defined?(:CHDIR_MONITOR)
840
- const_set(:CHDIR_MONITOR, EXT_LOCK)
841
- end
842
-
843
- remove_const(:CHDIR_MUTEX) if const_defined?(:CHDIR_MUTEX)
844
- const_set(:CHDIR_MUTEX, const_get(:CHDIR_MONITOR))
845
- end
846
- end
847
-
848
- if Gem::Specification.respond_to?(:stubs_for)
849
- def find_name(name)
850
- Gem::Specification.stubs_for(name).map(&:to_spec)
851
- end
852
- else
853
- def find_name(name)
854
- Gem::Specification.stubs.find_all do |spec|
855
- spec.name == name
856
- end.map(&:to_spec)
857
- end
858
- end
620
+ def find_name(name)
621
+ Gem::Specification.stubs_for(name).map(&:to_spec)
622
+ end
859
623
 
860
- if Gem::Specification.respond_to?(:default_stubs)
861
- def default_stubs
862
- Gem::Specification.default_stubs("*.gemspec")
863
- end
864
- else
865
- def default_stubs
866
- Gem::Specification.send(:default_stubs, "*.gemspec")
867
- end
624
+ if Gem::Specification.respond_to?(:default_stubs)
625
+ def default_stubs
626
+ Gem::Specification.default_stubs("*.gemspec")
868
627
  end
869
-
870
- def use_gemdeps(gemfile)
871
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
872
- require "bundler/gemdeps"
873
- runtime = Bundler.setup
874
- Bundler.ui = nil
875
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
876
- [Gemdeps.new(runtime), activated_spec_names]
628
+ else
629
+ def default_stubs
630
+ Gem::Specification.send(:default_stubs, "*.gemspec")
877
631
  end
632
+ end
878
633
 
879
- if provides?(">= 2.5.2")
880
- # RubyGems-generated binstubs call Kernel#gem
881
- def binstubs_call_gem?
882
- false
883
- end
884
-
885
- # only 2.5.2+ has all of the stub methods we want to use, and since this
886
- # is a performance optimization _only_,
887
- # we'll restrict ourselves to the most
888
- # recent RG versions instead of all versions that have stubs
889
- def stubs_provide_full_functionality?
890
- true
891
- end
892
- end
634
+ def use_gemdeps(gemfile)
635
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
636
+ require_relative "gemdeps"
637
+ runtime = Bundler.setup
638
+ Bundler.ui = nil
639
+ activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
640
+ [Gemdeps.new(runtime), activated_spec_names]
893
641
  end
894
642
  end
895
643
 
896
644
  def self.rubygems
897
- @rubygems ||= if RubygemsIntegration.provides?(">= 2.1.0")
898
- RubygemsIntegration::MoreFuture.new
899
- elsif RubygemsIntegration.provides?(">= 1.99.99")
900
- RubygemsIntegration::Future.new
901
- elsif RubygemsIntegration.provides?(">= 1.8.20")
902
- RubygemsIntegration::MoreModern.new
903
- elsif RubygemsIntegration.provides?(">= 1.8.5")
904
- RubygemsIntegration::Modern.new
905
- elsif RubygemsIntegration.provides?(">= 1.8.0")
906
- RubygemsIntegration::AlmostModern.new
907
- elsif RubygemsIntegration.provides?(">= 1.7.0")
908
- RubygemsIntegration::Transitional.new
909
- elsif RubygemsIntegration.provides?(">= 1.4.0")
910
- RubygemsIntegration::Legacy.new
911
- else # RubyGems 1.3.6 and 1.3.7
912
- RubygemsIntegration::Ancient.new
913
- end
645
+ @rubygems ||= RubygemsIntegration.new
914
646
  end
915
647
  end