bundler 2.5.16 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +194 -0
  3. data/bundler.gemspec +2 -2
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/cli/add.rb +3 -1
  6. data/lib/bundler/cli/check.rb +3 -3
  7. data/lib/bundler/cli/console.rb +0 -4
  8. data/lib/bundler/cli/doctor.rb +4 -4
  9. data/lib/bundler/cli/exec.rb +1 -0
  10. data/lib/bundler/cli/gem.rb +6 -3
  11. data/lib/bundler/cli/info.rb +2 -2
  12. data/lib/bundler/cli/inject.rb +1 -1
  13. data/lib/bundler/cli/install.rb +13 -4
  14. data/lib/bundler/cli/lock.rb +25 -6
  15. data/lib/bundler/cli/outdated.rb +16 -18
  16. data/lib/bundler/cli/pristine.rb +1 -1
  17. data/lib/bundler/cli/show.rb +2 -2
  18. data/lib/bundler/cli.rb +38 -68
  19. data/lib/bundler/compact_index_client/cache_file.rb +0 -5
  20. data/lib/bundler/compact_index_client/updater.rb +0 -11
  21. data/lib/bundler/definition.rb +186 -119
  22. data/lib/bundler/dependency.rb +1 -1
  23. data/lib/bundler/dsl.rb +67 -52
  24. data/lib/bundler/endpoint_specification.rb +10 -1
  25. data/lib/bundler/errors.rb +17 -5
  26. data/lib/bundler/feature_flag.rb +1 -0
  27. data/lib/bundler/fetcher/compact_index.rb +1 -1
  28. data/lib/bundler/fetcher.rb +12 -5
  29. data/lib/bundler/force_platform.rb +0 -2
  30. data/lib/bundler/gem_helpers.rb +21 -5
  31. data/lib/bundler/injector.rb +2 -2
  32. data/lib/bundler/inline.rb +42 -17
  33. data/lib/bundler/installer/gem_installer.rb +4 -2
  34. data/lib/bundler/installer/parallel_installer.rb +3 -2
  35. data/lib/bundler/installer/standalone.rb +2 -2
  36. data/lib/bundler/installer.rb +11 -47
  37. data/lib/bundler/lazy_specification.rb +74 -26
  38. data/lib/bundler/lockfile_generator.rb +1 -1
  39. data/lib/bundler/lockfile_parser.rb +10 -2
  40. data/lib/bundler/man/bundle-add.1 +42 -25
  41. data/lib/bundler/man/bundle-add.1.ronn +52 -23
  42. data/lib/bundler/man/bundle-binstubs.1 +7 -4
  43. data/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
  44. data/lib/bundler/man/bundle-cache.1 +30 -2
  45. data/lib/bundler/man/bundle-cache.1.ronn +31 -2
  46. data/lib/bundler/man/bundle-check.1 +3 -3
  47. data/lib/bundler/man/bundle-check.1.ronn +4 -2
  48. data/lib/bundler/man/bundle-clean.1 +1 -1
  49. data/lib/bundler/man/bundle-config.1 +3 -5
  50. data/lib/bundler/man/bundle-config.1.ronn +2 -7
  51. data/lib/bundler/man/bundle-console.1 +2 -4
  52. data/lib/bundler/man/bundle-console.1.ronn +2 -7
  53. data/lib/bundler/man/bundle-doctor.1 +2 -2
  54. data/lib/bundler/man/bundle-doctor.1.ronn +1 -1
  55. data/lib/bundler/man/bundle-env.1 +9 -0
  56. data/lib/bundler/man/bundle-env.1.ronn +10 -0
  57. data/lib/bundler/man/bundle-exec.1 +5 -2
  58. data/lib/bundler/man/bundle-exec.1.ronn +4 -1
  59. data/lib/bundler/man/bundle-fund.1 +22 -0
  60. data/lib/bundler/man/bundle-fund.1.ronn +25 -0
  61. data/lib/bundler/man/bundle-gem.1 +17 -5
  62. data/lib/bundler/man/bundle-gem.1.ronn +27 -6
  63. data/lib/bundler/man/bundle-help.1 +1 -1
  64. data/lib/bundler/man/bundle-info.1 +5 -2
  65. data/lib/bundler/man/bundle-info.1.ronn +6 -2
  66. data/lib/bundler/man/bundle-init.1 +3 -3
  67. data/lib/bundler/man/bundle-init.1.ronn +3 -2
  68. data/lib/bundler/man/bundle-inject.1 +10 -2
  69. data/lib/bundler/man/bundle-inject.1.ronn +9 -1
  70. data/lib/bundler/man/bundle-install.1 +15 -12
  71. data/lib/bundler/man/bundle-install.1.ronn +22 -18
  72. data/lib/bundler/man/bundle-issue.1 +45 -0
  73. data/lib/bundler/man/bundle-issue.1.ronn +37 -0
  74. data/lib/bundler/man/bundle-licenses.1 +9 -0
  75. data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
  76. data/lib/bundler/man/bundle-list.1 +1 -1
  77. data/lib/bundler/man/bundle-list.1.ronn +4 -1
  78. data/lib/bundler/man/bundle-lock.1 +21 -6
  79. data/lib/bundler/man/bundle-lock.1.ronn +25 -4
  80. data/lib/bundler/man/bundle-open.1 +2 -2
  81. data/lib/bundler/man/bundle-open.1.ronn +2 -1
  82. data/lib/bundler/man/bundle-outdated.1 +8 -5
  83. data/lib/bundler/man/bundle-outdated.1.ronn +8 -4
  84. data/lib/bundler/man/bundle-platform.1 +1 -1
  85. data/lib/bundler/man/bundle-plugin.1 +1 -1
  86. data/lib/bundler/man/bundle-pristine.1 +1 -1
  87. data/lib/bundler/man/bundle-pristine.1.ronn +1 -1
  88. data/lib/bundler/man/bundle-remove.1 +1 -1
  89. data/lib/bundler/man/bundle-remove.1.ronn +1 -1
  90. data/lib/bundler/man/bundle-show.1 +5 -2
  91. data/lib/bundler/man/bundle-show.1.ronn +4 -0
  92. data/lib/bundler/man/bundle-update.1 +13 -7
  93. data/lib/bundler/man/bundle-update.1.ronn +14 -6
  94. data/lib/bundler/man/bundle-version.1 +1 -1
  95. data/lib/bundler/man/bundle-viz.1 +4 -4
  96. data/lib/bundler/man/bundle-viz.1.ronn +7 -3
  97. data/lib/bundler/man/bundle.1 +1 -1
  98. data/lib/bundler/man/gemfile.5 +3 -1
  99. data/lib/bundler/man/gemfile.5.ronn +6 -0
  100. data/lib/bundler/man/index.txt +4 -0
  101. data/lib/bundler/materialization.rb +59 -0
  102. data/lib/bundler/plugin/api/source.rb +2 -1
  103. data/lib/bundler/plugin/events.rb +24 -0
  104. data/lib/bundler/plugin/installer.rb +1 -1
  105. data/lib/bundler/plugin.rb +20 -1
  106. data/lib/bundler/process_lock.rb +10 -14
  107. data/lib/bundler/remote_specification.rb +6 -1
  108. data/lib/bundler/resolver/base.rb +12 -6
  109. data/lib/bundler/resolver/candidate.rb +2 -2
  110. data/lib/bundler/resolver/package.rb +10 -1
  111. data/lib/bundler/resolver/spec_group.rb +4 -3
  112. data/lib/bundler/resolver.rb +36 -14
  113. data/lib/bundler/retry.rb +1 -1
  114. data/lib/bundler/ruby_version.rb +7 -1
  115. data/lib/bundler/rubygems_ext.rb +104 -51
  116. data/lib/bundler/rubygems_gem_installer.rb +7 -5
  117. data/lib/bundler/rubygems_integration.rb +23 -62
  118. data/lib/bundler/runtime.rb +22 -7
  119. data/lib/bundler/self_manager.rb +7 -7
  120. data/lib/bundler/settings.rb +6 -1
  121. data/lib/bundler/shared_helpers.rb +29 -17
  122. data/lib/bundler/source/git/git_proxy.rb +0 -2
  123. data/lib/bundler/source/git.rb +93 -40
  124. data/lib/bundler/source/metadata.rb +2 -3
  125. data/lib/bundler/source/path.rb +5 -3
  126. data/lib/bundler/source/rubygems.rb +6 -16
  127. data/lib/bundler/source_list.rb +1 -1
  128. data/lib/bundler/spec_set.rb +82 -57
  129. data/lib/bundler/stub_specification.rb +21 -2
  130. data/lib/bundler/templates/newgem/Gemfile.tt +0 -3
  131. data/lib/bundler/templates/newgem/README.md.tt +7 -3
  132. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -15
  133. data/lib/bundler/templates/newgem/newgem.gemspec.tt +4 -4
  134. data/lib/bundler/ui/shell.rb +24 -2
  135. data/lib/bundler/ui/silent.rb +12 -1
  136. data/lib/bundler/uri_credentials_filter.rb +1 -1
  137. data/lib/bundler/vendor/fileutils/COPYING +56 -0
  138. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +15 -13
  139. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +46 -8
  140. data/lib/bundler/vendor/securerandom/.document +1 -0
  141. data/lib/bundler/vendor/securerandom/COPYING +56 -0
  142. data/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
  143. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +3 -5
  144. data/lib/bundler/vendor/thor/lib/thor/group.rb +11 -0
  145. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +1 -4
  146. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +2 -2
  147. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +2 -1
  148. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +9 -9
  149. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
  150. data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +5 -21
  151. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  152. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  153. data/lib/bundler/vendor/thor/lib/thor.rb +11 -0
  154. data/lib/bundler/vendor/uri/COPYING +56 -0
  155. data/lib/bundler/vendor/uri/lib/uri/common.rb +37 -14
  156. data/lib/bundler/vendor/uri/lib/uri/file.rb +3 -3
  157. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +1 -1
  158. data/lib/bundler/vendor/uri/lib/uri/generic.rb +16 -26
  159. data/lib/bundler/vendor/uri/lib/uri/http.rb +2 -2
  160. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +10 -3
  161. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +26 -3
  162. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  163. data/lib/bundler/vendor/uri/lib/uri.rb +9 -9
  164. data/lib/bundler/vendored_securerandom.rb +12 -0
  165. data/lib/bundler/version.rb +1 -1
  166. data/lib/bundler/yaml_serializer.rb +1 -1
  167. data/lib/bundler.rb +68 -36
  168. metadata +20 -10
  169. data/lib/bundler/vendor/fileutils/LICENSE.txt +0 -22
  170. data/lib/bundler/vendor/uri/LICENSE.txt +0 -22
@@ -70,13 +70,13 @@ module Bundler
70
70
  end
71
71
 
72
72
  def hash
73
- [self.class, uri, ref, branch, name, version, glob, submodules].hash
73
+ [self.class, uri, ref, branch, name, glob, submodules].hash
74
74
  end
75
75
 
76
76
  def eql?(other)
77
77
  other.is_a?(Git) && uri == other.uri && ref == other.ref &&
78
78
  branch == other.branch && name == other.name &&
79
- version == other.version && glob == other.glob &&
79
+ glob == other.glob &&
80
80
  submodules == other.submodules
81
81
  end
82
82
 
@@ -102,7 +102,7 @@ module Bundler
102
102
  end
103
103
 
104
104
  def identifier
105
- uri_with_specifiers([humanized_ref, cached_revision, glob_for_display])
105
+ uri_with_specifiers([humanized_ref, locked_revision, glob_for_display])
106
106
  end
107
107
 
108
108
  def uri_with_specifiers(specifiers)
@@ -164,7 +164,8 @@ module Bundler
164
164
  "does not exist. Run `bundle config unset local.#{override_for(original_path)}` to remove the local override"
165
165
  end
166
166
 
167
- set_local!(path)
167
+ @local = true
168
+ set_paths!(path)
168
169
 
169
170
  # Create a new git proxy without the cached revision
170
171
  # so the Gemfile.lock always picks up the new revision.
@@ -175,10 +176,10 @@ module Bundler
175
176
  "#{current_branch} but Gemfile specifies #{branch}"
176
177
  end
177
178
 
178
- changed = cached_revision && cached_revision != revision
179
+ changed = locked_revision && locked_revision != revision
179
180
 
180
- if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
181
- raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
181
+ if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(locked_revision)
182
+ raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(locked_revision)} " \
182
183
  "but the current branch in your local override for #{name} does not contain such commit. " \
183
184
  "Please make sure your branch is up to date."
184
185
  end
@@ -187,13 +188,11 @@ module Bundler
187
188
  end
188
189
 
189
190
  def specs(*)
190
- set_local!(app_cache_path) if has_app_cache? && !local?
191
+ set_cache_path!(app_cache_path) if use_app_cache?
191
192
 
192
193
  if requires_checkout? && !@copied
193
- fetch
194
- git_proxy.copy_to(install_path, submodules)
195
- serialize_gemspecs_in(install_path)
196
- @copied = true
194
+ fetch unless use_app_cache?
195
+ checkout
197
196
  end
198
197
 
199
198
  local_specs
@@ -206,27 +205,25 @@ module Bundler
206
205
  print_using_message "Using #{version_message(spec, options[:previous_spec])} from #{self}"
207
206
 
208
207
  if (requires_checkout? && !@copied) || force
209
- Bundler.ui.debug " * Checking out revision: #{ref}"
210
- git_proxy.copy_to(install_path, submodules)
211
- serialize_gemspecs_in(install_path)
212
- @copied = true
208
+ checkout
213
209
  end
214
210
 
215
- generate_bin_options = { disable_extensions: !Bundler.rubygems.spec_missing_extensions?(spec), build_args: options[:build_args] }
211
+ generate_bin_options = { disable_extensions: !spec.missing_extensions?, build_args: options[:build_args] }
216
212
  generate_bin(spec, generate_bin_options)
217
213
 
218
214
  requires_checkout? ? spec.post_install_message : nil
219
215
  end
220
216
 
217
+ def migrate_cache(custom_path = nil, local: false)
218
+ if local
219
+ cache_to(custom_path, try_migrate: false)
220
+ else
221
+ cache_to(custom_path, try_migrate: true)
222
+ end
223
+ end
224
+
221
225
  def cache(spec, custom_path = nil)
222
- app_cache_path = app_cache_path(custom_path)
223
- return unless Bundler.feature_flag.cache_all?
224
- return if path == app_cache_path
225
- cached!
226
- FileUtils.rm_rf(app_cache_path)
227
- git_proxy.checkout if requires_checkout?
228
- git_proxy.copy_to(app_cache_path, @submodules)
229
- serialize_gemspecs_in(app_cache_path)
226
+ cache_to(custom_path, try_migrate: false)
230
227
  end
231
228
 
232
229
  def load_spec_files
@@ -249,7 +246,7 @@ module Bundler
249
246
  end
250
247
 
251
248
  def app_cache_dirname
252
- "#{base_name}-#{shortref_for_path(cached_revision || revision)}"
249
+ "#{base_name}-#{shortref_for_path(locked_revision || revision)}"
253
250
  end
254
251
 
255
252
  def revision
@@ -270,6 +267,42 @@ module Bundler
270
267
 
271
268
  private
272
269
 
270
+ def cache_to(custom_path, try_migrate: false)
271
+ return unless Bundler.feature_flag.cache_all?
272
+
273
+ app_cache_path = app_cache_path(custom_path)
274
+
275
+ migrate = try_migrate ? bare_repo?(app_cache_path) : false
276
+
277
+ set_cache_path!(nil) if migrate
278
+
279
+ return if cache_path == app_cache_path
280
+
281
+ cached!
282
+ FileUtils.rm_rf(app_cache_path)
283
+ git_proxy.checkout if migrate || requires_checkout?
284
+ git_proxy.copy_to(app_cache_path, @submodules)
285
+ end
286
+
287
+ def checkout
288
+ Bundler.ui.debug " * Checking out revision: #{ref}"
289
+ if use_app_cache? && !bare_repo?(app_cache_path)
290
+ SharedHelpers.filesystem_access(install_path.dirname) do |p|
291
+ FileUtils.mkdir_p(p)
292
+ end
293
+ FileUtils.cp_r("#{app_cache_path}/.", install_path)
294
+ else
295
+ if use_app_cache? && bare_repo?(app_cache_path)
296
+ Bundler.ui.warn "Installing from cache in old \"bare repository\" format for compatibility. " \
297
+ "Please run `bundle cache` and commit the updated cache to migrate to the new format and get rid of this warning."
298
+ end
299
+
300
+ git_proxy.copy_to(install_path, submodules)
301
+ end
302
+ serialize_gemspecs_in(install_path)
303
+ @copied = true
304
+ end
305
+
273
306
  def humanized_ref
274
307
  if local?
275
308
  path
@@ -292,28 +325,41 @@ module Bundler
292
325
  # The gemspecs we cache should already be evaluated.
293
326
  spec = Bundler.load_gemspec(spec_path)
294
327
  next unless spec
295
- Bundler.rubygems.set_installed_by_version(spec)
328
+ spec.installed_by_version = Gem::VERSION
296
329
  Bundler.rubygems.validate(spec)
297
330
  File.open(spec_path, "wb") {|file| file.write(spec.to_ruby) }
298
331
  end
299
332
  end
300
333
 
301
- def set_local!(path)
302
- @local = true
303
- @local_specs = @git_proxy = nil
304
- @cache_path = @install_path = path
334
+ def set_paths!(path)
335
+ set_cache_path!(path)
336
+ set_install_path!(path)
337
+ end
338
+
339
+ def set_cache_path!(path)
340
+ @git_proxy = nil
341
+ @cache_path = path
342
+ end
343
+
344
+ def set_install_path!(path)
345
+ @local_specs = nil
346
+ @install_path = path
305
347
  end
306
348
 
307
349
  def has_app_cache?
308
- cached_revision && super
350
+ locked_revision && super
351
+ end
352
+
353
+ def use_app_cache?
354
+ has_app_cache? && !local?
309
355
  end
310
356
 
311
357
  def requires_checkout?
312
- allow_git_ops? && !local? && !cached_revision_checked_out?
358
+ allow_git_ops? && !local? && !locked_revision_checked_out?
313
359
  end
314
360
 
315
- def cached_revision_checked_out?
316
- cached_revision && cached_revision == revision && install_path.exist?
361
+ def locked_revision_checked_out?
362
+ locked_revision && locked_revision == revision && install_path.exist?
317
363
  end
318
364
 
319
365
  def base_name
@@ -350,7 +396,7 @@ module Bundler
350
396
  Bundler::Digest.sha1(input)
351
397
  end
352
398
 
353
- def cached_revision
399
+ def locked_revision
354
400
  options["revision"]
355
401
  end
356
402
 
@@ -359,7 +405,7 @@ module Bundler
359
405
  end
360
406
 
361
407
  def git_proxy
362
- @git_proxy ||= GitProxy.new(cache_path, uri, options, cached_revision, self)
408
+ @git_proxy ||= GitProxy.new(cache_path, uri, options, locked_revision, self)
363
409
  end
364
410
 
365
411
  def fetch
@@ -373,9 +419,12 @@ module Bundler
373
419
  def validate_spec(_spec); end
374
420
 
375
421
  def load_gemspec(file)
376
- stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
377
- stub.full_gem_path = Pathname.new(file).dirname.expand_path(root).to_s
378
- StubSpecification.from_stub(stub)
422
+ dirname = Pathname.new(file).dirname
423
+ SharedHelpers.chdir(dirname.to_s) do
424
+ stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
425
+ stub.full_gem_path = dirname.expand_path(root).to_s
426
+ StubSpecification.from_stub(stub)
427
+ end
379
428
  end
380
429
 
381
430
  def git_scope
@@ -389,6 +438,10 @@ module Bundler
389
438
  def override_for(path)
390
439
  Bundler.settings.local_overrides.key(path)
391
440
  end
441
+
442
+ def bare_repo?(path)
443
+ File.exist?(path.join("objects")) && File.exist?(path.join("HEAD"))
444
+ end
392
445
  end
393
446
  end
394
447
  end
@@ -24,9 +24,8 @@ module Bundler
24
24
  s.bindir = "exe"
25
25
  s.homepage = "https://bundler.io"
26
26
  s.summary = "The best way to manage your application's dependencies"
27
- s.executables = %w[bundle]
28
- # can't point to the actual gemspec or else the require paths will be wrong
29
- s.loaded_from = __dir__
27
+ s.executables = %w[bundle bundler]
28
+ s.loaded_from = SharedHelpers.gemspec_path
30
29
  end
31
30
  end
32
31
 
@@ -53,6 +53,8 @@ module Bundler
53
53
  "source at `#{@path}`"
54
54
  end
55
55
 
56
+ alias_method :to_gemfile, :path
57
+
56
58
  def hash
57
59
  [self.class, expanded_path, version].hash
58
60
  end
@@ -148,7 +150,7 @@ module Bundler
148
150
 
149
151
  def load_gemspec(file)
150
152
  return unless spec = Bundler.load_gemspec(file)
151
- Bundler.rubygems.set_installed_by_version(spec)
153
+ spec.installed_by_version = Gem::VERSION
152
154
  spec
153
155
  end
154
156
 
@@ -212,7 +214,7 @@ module Bundler
212
214
 
213
215
  # Some gem authors put absolute paths in their gemspec
214
216
  # and we have to save them from themselves
215
- spec.files = spec.files.map do |path|
217
+ spec.files = spec.files.filter_map do |path|
216
218
  next path unless /\A#{Pathname::SEPARATOR_PAT}/o.match?(path)
217
219
  next if File.directory?(path)
218
220
  begin
@@ -220,7 +222,7 @@ module Bundler
220
222
  rescue ArgumentError
221
223
  path
222
224
  end
223
- end.compact
225
+ end
224
226
 
225
227
  installer = Path::Installer.new(
226
228
  spec,
@@ -148,7 +148,7 @@ module Bundler
148
148
  end
149
149
 
150
150
  def install(spec, options = {})
151
- if (spec.default_gem? && !cached_built_in_gem(spec)) || (installed?(spec) && !options[:force])
151
+ if (spec.default_gem? && !cached_built_in_gem(spec, local: options[:local])) || (installed?(spec) && !options[:force])
152
152
  print_using_message "Using #{version_message(spec, options[:previous_spec])}"
153
153
  return nil # no post-install message
154
154
  end
@@ -222,12 +222,13 @@ module Bundler
222
222
  raise InstallError, e.message
223
223
  end
224
224
 
225
- def cached_built_in_gem(spec)
226
- cached_path = cached_path(spec)
227
- if cached_path.nil?
225
+ def cached_built_in_gem(spec, local: false)
226
+ cached_path = cached_gem(spec)
227
+ if cached_path.nil? && !local
228
228
  remote_spec = remote_specs.search(spec).first
229
229
  if remote_spec
230
230
  cached_path = fetch_gem(remote_spec)
231
+ spec.remote = remote_spec.remote
231
232
  else
232
233
  Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it."
233
234
  end
@@ -324,14 +325,6 @@ module Bundler
324
325
  end
325
326
 
326
327
  def cached_gem(spec)
327
- if spec.default_gem?
328
- cached_built_in_gem(spec)
329
- else
330
- cached_path(spec)
331
- end
332
- end
333
-
334
- def cached_path(spec)
335
328
  global_cache_path = download_cache_path(spec)
336
329
  caches << global_cache_path if global_cache_path
337
330
 
@@ -364,10 +357,7 @@ module Bundler
364
357
  @installed_specs ||= Index.build do |idx|
365
358
  Bundler.rubygems.installed_specs.reverse_each do |spec|
366
359
  spec.source = self
367
- if Bundler.rubygems.spec_missing_extensions?(spec, false)
368
- Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
369
- next
370
- end
360
+ next if spec.ignored?
371
361
  idx << spec
372
362
  end
373
363
  end
@@ -91,7 +91,7 @@ module Bundler
91
91
  end
92
92
 
93
93
  def rubygems_remotes
94
- rubygems_sources.map(&:remotes).flatten.uniq
94
+ rubygems_sources.flat_map(&:remotes).uniq
95
95
  end
96
96
 
97
97
  def all_sources
@@ -7,49 +7,44 @@ module Bundler
7
7
  include Enumerable
8
8
  include TSort
9
9
 
10
- attr_reader :incomplete_specs
11
-
12
- def initialize(specs, incomplete_specs = [])
10
+ def initialize(specs)
13
11
  @specs = specs
14
- @incomplete_specs = incomplete_specs
15
12
  end
16
13
 
17
- def for(dependencies, check = false, platforms = [nil])
18
- handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h
19
- deps = dependencies.product(platforms)
20
- specs = []
14
+ def for(dependencies, platforms_or_legacy_check = [nil], legacy_platforms = [nil], skips: [])
15
+ platforms = if [true, false].include?(platforms_or_legacy_check)
16
+ Bundler::SharedHelpers.major_deprecation 2,
17
+ "SpecSet#for received a `check` parameter, but that's no longer used and deprecated. " \
18
+ "SpecSet#for always implicitly performs validation. Please remove this parameter",
19
+ print_caller_location: true
21
20
 
22
- loop do
23
- break unless dep = deps.shift
21
+ legacy_platforms
22
+ else
23
+ platforms_or_legacy_check
24
+ end
24
25
 
25
- name = dep[0].name
26
- platform = dep[1]
27
- incomplete = false
26
+ materialize_dependencies(dependencies, platforms, skips: skips)
28
27
 
29
- key = [name, platform]
30
- next if handled.key?(key)
28
+ @materializations.flat_map(&:specs).uniq
29
+ end
31
30
 
32
- handled[key] = true
31
+ def normalize_platforms!(deps, platforms)
32
+ complete_platforms = add_extra_platforms!(platforms)
33
33
 
34
- specs_for_dep = specs_for_dependency(*dep)
35
- if specs_for_dep.any?
36
- specs.concat(specs_for_dep)
34
+ complete_platforms.map do |platform|
35
+ next platform if platform == Gem::Platform::RUBY
37
36
 
38
- specs_for_dep.first.dependencies.each do |d|
39
- next if d.type == :development
40
- incomplete = true if d.name != "bundler" && lookup[d.name].nil?
41
- deps << [d, dep[1]]
42
- end
43
- else
44
- incomplete = true
37
+ begin
38
+ Integer(platform.version)
39
+ rescue ArgumentError, TypeError
40
+ next platform
45
41
  end
46
42
 
47
- if incomplete && check
48
- @incomplete_specs += lookup[name] || [LazySpecification.new(name, nil, nil)]
49
- end
50
- end
43
+ less_specific_platform = Gem::Platform.new([platform.cpu, platform.os, nil])
44
+ next platform if incomplete_for_platform?(deps, less_specific_platform)
51
45
 
52
- specs.uniq
46
+ less_specific_platform
47
+ end.uniq
53
48
  end
54
49
 
55
50
  def add_extra_platforms!(platforms)
@@ -94,7 +89,7 @@ module Bundler
94
89
  end
95
90
 
96
91
  def delete(specs)
97
- specs.each {|spec| @specs.delete(spec) }
92
+ Array(specs).each {|spec| @specs.delete(spec) }
98
93
 
99
94
  reset!
100
95
  end
@@ -112,19 +107,18 @@ module Bundler
112
107
  end
113
108
 
114
109
  def materialize(deps)
115
- materialized = self.for(deps, true)
110
+ materialize_dependencies(deps)
116
111
 
117
- SpecSet.new(materialized, incomplete_specs)
112
+ SpecSet.new(materialized_specs)
118
113
  end
119
114
 
120
115
  # Materialize for all the specs in the spec set, regardless of what platform they're for
121
- # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform)
122
116
  # @return [Array<Gem::Specification>]
123
117
  def materialized_for_all_platforms
124
118
  @specs.map do |s|
125
119
  next s unless s.is_a?(LazySpecification)
126
120
  s.source.remote!
127
- spec = s.materialize_for_installation
121
+ spec = s.materialize_strictly
128
122
  raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
129
123
  spec
130
124
  end
@@ -133,15 +127,32 @@ module Bundler
133
127
  def incomplete_for_platform?(deps, platform)
134
128
  return false if @specs.empty?
135
129
 
136
- @incomplete_specs = []
130
+ validation_set = self.class.new(@specs)
131
+ validation_set.for(deps, [platform])
132
+
133
+ validation_set.incomplete_specs.any?
134
+ end
137
135
 
138
- self.for(deps, true, [platform])
136
+ def missing_specs_for(dependencies)
137
+ materialize_dependencies(dependencies)
139
138
 
140
- @incomplete_specs.any?
139
+ missing_specs
141
140
  end
142
141
 
143
142
  def missing_specs
144
- @specs.select {|s| s.is_a?(LazySpecification) }
143
+ @materializations.flat_map(&:completely_missing_specs)
144
+ end
145
+
146
+ def partially_missing_specs
147
+ @materializations.flat_map(&:partially_missing_specs)
148
+ end
149
+
150
+ def incomplete_specs
151
+ @materializations.flat_map(&:incomplete_specs)
152
+ end
153
+
154
+ def insecurely_materialized_specs
155
+ materialized_specs.select(&:insecurely_materialized?)
145
156
  end
146
157
 
147
158
  def -(other)
@@ -152,12 +163,6 @@ module Bundler
152
163
  @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
153
164
  end
154
165
 
155
- def specs_compatible_with(other)
156
- select do |spec|
157
- other.valid?(spec)
158
- end
159
- end
160
-
161
166
  def delete_by_name(name)
162
167
  @specs.reject! {|spec| spec.name == name }
163
168
 
@@ -201,6 +206,37 @@ module Bundler
201
206
 
202
207
  private
203
208
 
209
+ def materialize_dependencies(dependencies, platforms = [nil], skips: [])
210
+ handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h
211
+ deps = dependencies.product(platforms)
212
+ @materializations = []
213
+
214
+ loop do
215
+ break unless dep = deps.shift
216
+
217
+ dependency = dep[0]
218
+ platform = dep[1]
219
+ name = dependency.name
220
+
221
+ key = [name, platform]
222
+ next if handled.key?(key)
223
+
224
+ handled[key] = true
225
+
226
+ materialization = Materialization.new(dependency, platform, candidates: lookup[name])
227
+
228
+ deps.concat(materialization.dependencies) if materialization.complete?
229
+
230
+ @materializations << materialization unless skips.include?(name)
231
+ end
232
+
233
+ @materializations
234
+ end
235
+
236
+ def materialized_specs
237
+ @materializations.filter_map(&:materialized_spec)
238
+ end
239
+
204
240
  def reset!
205
241
  @sorted = nil
206
242
  @lookup = nil
@@ -273,17 +309,6 @@ module Bundler
273
309
  @specs.sort_by(&:name).each {|s| yield s }
274
310
  end
275
311
 
276
- def specs_for_dependency(dep, platform)
277
- specs_for_name = lookup[dep.name]
278
- return [] unless specs_for_name
279
-
280
- if platform
281
- GemHelpers.select_best_platform_match(specs_for_name, platform, force_ruby: dep.force_ruby_platform)
282
- else
283
- GemHelpers.select_best_local_platform_match(specs_for_name, force_ruby: dep.force_ruby_platform)
284
- end
285
- end
286
-
287
312
  def tsort_each_child(s)
288
313
  s.dependencies.sort_by(&:name).each do |d|
289
314
  next if d.type == :development
@@ -9,6 +9,10 @@ module Bundler
9
9
  spec
10
10
  end
11
11
 
12
+ def insecurely_materialized?
13
+ false
14
+ end
15
+
12
16
  attr_reader :checksum
13
17
  attr_accessor :stub, :ignored
14
18
 
@@ -28,6 +32,17 @@ module Bundler
28
32
 
29
33
  # @!group Stub Delegates
30
34
 
35
+ def ignored?
36
+ return @ignored unless @ignored.nil?
37
+
38
+ @ignored = missing_extensions?
39
+ return false unless @ignored
40
+
41
+ warn "Source #{source} is ignoring #{self} because it is missing extensions"
42
+
43
+ true
44
+ end
45
+
31
46
  def manually_installed?
32
47
  # This is for manually installed gems which are gems that were fixed in place after a
33
48
  # failed installation. Once the issue was resolved, the user then manually created
@@ -45,8 +60,8 @@ module Bundler
45
60
  true
46
61
  end
47
62
 
48
- def activated
49
- stub.activated
63
+ def activated?
64
+ stub.activated?
50
65
  end
51
66
 
52
67
  def activated=(activated)
@@ -101,6 +116,10 @@ module Bundler
101
116
  stub.raw_require_paths
102
117
  end
103
118
 
119
+ def inspect
120
+ "#<#{self.class} @name=\"#{name}\" (#{full_name.delete_prefix("#{name}-")})>"
121
+ end
122
+
104
123
  private
105
124
 
106
125
  def _remote_specification
@@ -9,9 +9,6 @@ gem "rake", "~> 13.0"
9
9
  <%- if config[:ext] -%>
10
10
 
11
11
  gem "rake-compiler"
12
- <%- if config[:ext] == 'rust' -%>
13
- gem "rb_sys", "~> 0.9.63"
14
- <%- end -%>
15
12
  <%- end -%>
16
13
  <%- if config[:test] -%>
17
14
 
@@ -10,11 +10,15 @@ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_O
10
10
 
11
11
  Install the gem and add to the application's Gemfile by executing:
12
12
 
13
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
13
+ ```bash
14
+ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
15
+ ```
14
16
 
15
17
  If bundler is not being used to manage dependencies, install the gem by executing:
16
18
 
17
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
19
+ ```bash
20
+ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
21
+ ```
18
22
 
19
23
  ## Usage
20
24
 
@@ -22,7 +26,7 @@ TODO: Write usage instructions here
22
26
 
23
27
  ## Development
24
28
 
25
- After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
29
+ After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test_task] %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
26
30
 
27
31
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
32
  <% if config[:git] -%>