bundler 2.2.26 → 2.3.7

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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +206 -1
  3. data/README.md +1 -1
  4. data/exe/bundle +7 -8
  5. data/lib/bundler/.document +1 -0
  6. data/lib/bundler/build_metadata.rb +2 -2
  7. data/lib/bundler/cli/check.rb +1 -1
  8. data/lib/bundler/cli/config.rb +10 -1
  9. data/lib/bundler/cli/doctor.rb +12 -3
  10. data/lib/bundler/cli/gem.rb +98 -9
  11. data/lib/bundler/cli/info.rb +26 -5
  12. data/lib/bundler/cli/install.rb +8 -28
  13. data/lib/bundler/cli/issue.rb +4 -3
  14. data/lib/bundler/cli/platform.rb +1 -1
  15. data/lib/bundler/cli/remove.rb +1 -2
  16. data/lib/bundler/cli/update.rb +8 -4
  17. data/lib/bundler/cli.rb +13 -11
  18. data/lib/bundler/compact_index_client/cache.rb +0 -9
  19. data/lib/bundler/compact_index_client/updater.rb +0 -5
  20. data/lib/bundler/compact_index_client.rb +2 -8
  21. data/lib/bundler/definition.rb +79 -133
  22. data/lib/bundler/dependency.rb +5 -7
  23. data/lib/bundler/digest.rb +71 -0
  24. data/lib/bundler/dsl.rb +18 -30
  25. data/lib/bundler/endpoint_specification.rb +21 -11
  26. data/lib/bundler/env.rb +1 -1
  27. data/lib/bundler/environment_preserver.rb +4 -1
  28. data/lib/bundler/errors.rb +18 -2
  29. data/lib/bundler/fetcher/compact_index.rb +9 -14
  30. data/lib/bundler/fetcher/index.rb +0 -26
  31. data/lib/bundler/fetcher.rb +13 -20
  32. data/lib/bundler/friendly_errors.rb +5 -30
  33. data/lib/bundler/gem_helper.rb +7 -18
  34. data/lib/bundler/injector.rb +10 -1
  35. data/lib/bundler/installer/gem_installer.rb +1 -6
  36. data/lib/bundler/installer.rb +1 -5
  37. data/lib/bundler/lazy_specification.rb +19 -3
  38. data/lib/bundler/lockfile_generator.rb +1 -1
  39. data/lib/bundler/lockfile_parser.rb +10 -12
  40. data/lib/bundler/man/bundle-add.1 +10 -2
  41. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  42. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  43. data/lib/bundler/man/bundle-cache.1 +1 -1
  44. data/lib/bundler/man/bundle-check.1 +1 -1
  45. data/lib/bundler/man/bundle-clean.1 +1 -1
  46. data/lib/bundler/man/bundle-config.1 +5 -5
  47. data/lib/bundler/man/bundle-config.1.ronn +5 -5
  48. data/lib/bundler/man/bundle-doctor.1 +1 -1
  49. data/lib/bundler/man/bundle-exec.1 +1 -1
  50. data/lib/bundler/man/bundle-gem.1 +14 -1
  51. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  52. data/lib/bundler/man/bundle-info.1 +1 -1
  53. data/lib/bundler/man/bundle-init.1 +1 -1
  54. data/lib/bundler/man/bundle-inject.1 +1 -1
  55. data/lib/bundler/man/bundle-install.1 +2 -2
  56. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  57. data/lib/bundler/man/bundle-list.1 +1 -1
  58. data/lib/bundler/man/bundle-lock.1 +1 -1
  59. data/lib/bundler/man/bundle-open.1 +1 -1
  60. data/lib/bundler/man/bundle-outdated.1 +1 -1
  61. data/lib/bundler/man/bundle-platform.1 +1 -1
  62. data/lib/bundler/man/bundle-pristine.1 +1 -1
  63. data/lib/bundler/man/bundle-remove.1 +1 -1
  64. data/lib/bundler/man/bundle-show.1 +1 -1
  65. data/lib/bundler/man/bundle-update.1 +2 -2
  66. data/lib/bundler/man/bundle-update.1.ronn +2 -1
  67. data/lib/bundler/man/bundle-viz.1 +1 -1
  68. data/lib/bundler/man/bundle.1 +1 -1
  69. data/lib/bundler/man/gemfile.5 +28 -2
  70. data/lib/bundler/man/gemfile.5.ronn +9 -1
  71. data/lib/bundler/plugin/api/source.rb +1 -0
  72. data/lib/bundler/plugin/installer.rb +3 -1
  73. data/lib/bundler/plugin.rb +23 -6
  74. data/lib/bundler/process_lock.rb +1 -1
  75. data/lib/bundler/remote_specification.rb +7 -0
  76. data/lib/bundler/resolver/spec_group.rb +1 -1
  77. data/lib/bundler/resolver.rb +38 -40
  78. data/lib/bundler/ruby_version.rb +1 -1
  79. data/lib/bundler/rubygems_ext.rb +19 -10
  80. data/lib/bundler/rubygems_gem_installer.rb +21 -5
  81. data/lib/bundler/rubygems_integration.rb +40 -70
  82. data/lib/bundler/runtime.rb +2 -2
  83. data/lib/bundler/self_manager.rb +168 -0
  84. data/lib/bundler/settings.rb +11 -2
  85. data/lib/bundler/shared_helpers.rb +4 -12
  86. data/lib/bundler/source/git/git_proxy.rb +7 -4
  87. data/lib/bundler/source/git.rb +22 -4
  88. data/lib/bundler/source/metadata.rb +1 -1
  89. data/lib/bundler/source/rubygems.rb +60 -85
  90. data/lib/bundler/source/rubygems_aggregate.rb +1 -1
  91. data/lib/bundler/source.rb +3 -1
  92. data/lib/bundler/source_list.rb +11 -29
  93. data/lib/bundler/spec_set.rb +2 -2
  94. data/lib/bundler/templates/Executable.bundler +1 -1
  95. data/lib/bundler/templates/Gemfile +0 -2
  96. data/lib/bundler/templates/gems.rb +0 -3
  97. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  98. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  99. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +4 -3
  100. data/lib/bundler/templates/newgem/newgem.gemspec.tt +15 -15
  101. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  102. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  103. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  104. data/lib/bundler/ui/shell.rb +1 -1
  105. data/lib/bundler/vendor/.document +1 -0
  106. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  107. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  108. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  109. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  110. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  111. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  112. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  114. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  115. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  116. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +6 -6
  117. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  118. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  119. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  120. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  121. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  122. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  123. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  124. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  125. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  126. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  127. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  128. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  129. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  130. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  131. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  132. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  133. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  134. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  135. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  136. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  137. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  138. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  139. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  140. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  141. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  142. data/lib/bundler/vendored_tsort.rb +4 -0
  143. data/lib/bundler/version.rb +1 -1
  144. data/lib/bundler/worker.rb +2 -2
  145. data/lib/bundler.rb +23 -22
  146. metadata +25 -10
  147. data/lib/bundler/gemdeps.rb +0 -29
  148. data/lib/bundler/psyched_yaml.rb +0 -22
  149. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -13,6 +13,7 @@ module Bundler
13
13
  class MalformattedPlugin < PluginError; end
14
14
  class UndefinedCommandError < PluginError; end
15
15
  class UnknownSourceError < PluginError; end
16
+ class PluginInstallError < PluginError; end
16
17
 
17
18
  PLUGIN_FILE_NAME = "plugins.rb".freeze
18
19
 
@@ -38,12 +39,11 @@ module Bundler
38
39
  specs = Installer.new.install(names, options)
39
40
 
40
41
  save_plugins names, specs
41
- rescue PluginError => e
42
+ rescue PluginError
42
43
  specs_to_delete = specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }
43
44
  specs_to_delete.each_value {|spec| Bundler.rm_rf(spec.full_gem_path) }
44
45
 
45
- names_list = names.map {|name| "`#{name}`" }.join(", ")
46
- Bundler.ui.error "Failed to install the following plugins: #{names_list}. The underlying error was: #{e.message}.\n #{e.backtrace.join("\n ")}"
46
+ raise
47
47
  end
48
48
 
49
49
  # Uninstalls plugins by the given names
@@ -245,10 +245,11 @@ module Bundler
245
245
  # @param [Array<String>] names of inferred source plugins that can be ignored
246
246
  def save_plugins(plugins, specs, optional_plugins = [])
247
247
  plugins.each do |name|
248
+ next if index.installed?(name)
249
+
248
250
  spec = specs[name]
249
- validate_plugin! Pathname.new(spec.full_gem_path)
250
- installed = register_plugin(name, spec, optional_plugins.include?(name))
251
- Bundler.ui.info "Installed plugin #{name}" if installed
251
+
252
+ save_plugin(name, spec, optional_plugins.include?(name))
252
253
  end
253
254
  end
254
255
 
@@ -263,6 +264,22 @@ module Bundler
263
264
  raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file?
264
265
  end
265
266
 
267
+ # Validates and registers a plugin.
268
+ #
269
+ # @param [String] name the name of the plugin
270
+ # @param [Specification] spec of installed plugin
271
+ # @param [Boolean] optional_plugin, removed if there is conflict with any
272
+ # other plugin (used for default source plugins)
273
+ #
274
+ # @raise [PluginInstallError] if validation or registration raises any error
275
+ def save_plugin(name, spec, optional_plugin = false)
276
+ validate_plugin! Pathname.new(spec.full_gem_path)
277
+ installed = register_plugin(name, spec, optional_plugin)
278
+ Bundler.ui.info "Installed plugin #{name}" if installed
279
+ rescue PluginError => e
280
+ raise PluginInstallError, "Failed to install plugin `#{spec.name}`, due to #{e.class} (#{e.message})"
281
+ end
282
+
266
283
  # Runs the plugins.rb file in an isolated namespace, records the plugin
267
284
  # actions it registers for and then passes the data to index to be stored.
268
285
  #
@@ -12,7 +12,7 @@ module Bundler
12
12
  yield
13
13
  f.flock(File::LOCK_UN)
14
14
  end
15
- rescue Errno::EACCES, Errno::ENOLCK, *[SharedHelpers.const_get_safely(:ENOTSUP, Errno)].compact
15
+ rescue Errno::EACCES, Errno::ENOLCK, Errno::ENOTSUP
16
16
  # In the case the user does not have access to
17
17
  # create the lock file or is using NFS where
18
18
  # locks are not available we skip locking.
@@ -27,6 +27,13 @@ module Bundler
27
27
  @platform = _remote_specification.platform
28
28
  end
29
29
 
30
+ # A fallback is included because the original version of the specification
31
+ # API didn't include that field, so some marshalled specs in the index have it
32
+ # set to +nil+.
33
+ def required_rubygems_version
34
+ @required_rubygems_version ||= _remote_specification.required_rubygems_version || Gem::Requirement.default
35
+ end
36
+
30
37
  def full_name
31
38
  if platform == Gem::Platform::RUBY || platform.nil?
32
39
  "#{@name}-#{@version}"
@@ -95,7 +95,7 @@ module Bundler
95
95
 
96
96
  def metadata_dependencies(platform)
97
97
  spec = @specs[platform].first
98
- return [] unless spec.is_a?(Gem::Specification)
98
+ return [] if spec.is_a?(LazySpecification)
99
99
  dependencies = []
100
100
  if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
101
101
  dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
@@ -30,10 +30,8 @@ module Bundler
30
30
  @resolver = Molinillo::Resolver.new(self, self)
31
31
  @search_for = {}
32
32
  @base_dg = Molinillo::DependencyGraph.new
33
- aggregate_global_source = @source_requirements[:default].is_a?(Source::RubygemsAggregate)
34
33
  @base.each do |ls|
35
34
  dep = Dependency.new(ls.name, ls.version)
36
- ls.source = source_for(ls.name) unless aggregate_global_source
37
35
  @base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
38
36
  end
39
37
  additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@@ -136,6 +134,7 @@ module Bundler
136
134
  end
137
135
  nested.reduce([]) do |groups, (version, specs)|
138
136
  next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
137
+ next groups unless specs.any? {|spec| spec.match_platform(platform) }
139
138
 
140
139
  specs_by_platform = Hash.new do |current_specs, current_platform|
141
140
  current_specs[current_platform] = select_best_platform_match(specs, current_platform)
@@ -147,7 +146,7 @@ module Bundler
147
146
  next groups if @resolving_only_for_ruby
148
147
 
149
148
  spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
150
- groups << spec_group if spec_group
149
+ groups << spec_group
151
150
 
152
151
  groups
153
152
  end
@@ -250,10 +249,11 @@ module Bundler
250
249
  end
251
250
 
252
251
  def verify_gemfile_dependencies_are_found!(requirements)
253
- requirements.each do |requirement|
252
+ requirements.map! do |requirement|
254
253
  name = requirement.name
255
- next if name == "bundler"
256
- next unless search_for(requirement).empty?
254
+ next requirement if name == "bundler"
255
+ next requirement unless search_for(requirement).empty?
256
+ next unless requirement.current_platform?
257
257
 
258
258
  if (base = @base[name]) && !base.empty?
259
259
  version = base.first.version
@@ -264,30 +264,37 @@ module Bundler
264
264
  "If you are updating multiple gems in your Gemfile at once,\n" \
265
265
  "try passing them all to `bundle update`"
266
266
  else
267
- source = source_for(name)
268
- specs = source.specs.search(name)
269
- versions_with_platforms = specs.map {|s| [s.version, s.platform] }
270
- cache_message = begin
271
- " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
272
- rescue GemfileNotFound
273
- nil
274
- end
275
- message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source.to_err}#{cache_message}.\n")
276
- message << "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}" if versions_with_platforms.any?
267
+ message = gem_not_found_message(name, requirement, source_for(name))
277
268
  end
278
269
  raise GemNotFound, message
279
- end
270
+ end.compact!
280
271
  end
281
272
 
282
- def formatted_versions_with_platforms(versions_with_platforms)
283
- version_platform_strs = versions_with_platforms.map do |vwp|
284
- version = vwp.first
285
- platform = vwp.last
286
- version_platform_str = String.new(version.to_s)
287
- version_platform_str << " #{platform}" unless platform.nil? || platform == Gem::Platform::RUBY
288
- version_platform_str
273
+ def gem_not_found_message(name, requirement, source, extra_message = "")
274
+ specs = source.specs.search(name)
275
+ matching_part = name
276
+ requirement_label = SharedHelpers.pretty_dependency(requirement)
277
+ cache_message = begin
278
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
279
+ rescue GemfileNotFound
280
+ nil
281
+ end
282
+ specs_matching_requirement = specs.select {| spec| requirement.matches_spec?(spec) }
283
+
284
+ if specs_matching_requirement.any?
285
+ specs = specs_matching_requirement
286
+ matching_part = requirement_label
287
+ requirement_label = "#{requirement_label} #{requirement.__platform}"
289
288
  end
290
- version_platform_strs.join(", ")
289
+
290
+ message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")
291
+
292
+ if specs.any?
293
+ message << "\nThe source contains the following gems matching '#{matching_part}':\n"
294
+ message << specs.map {|s| " * #{s.full_name}" }.join("\n")
295
+ end
296
+
297
+ message
291
298
  end
292
299
 
293
300
  def version_conflict_message(e)
@@ -352,27 +359,18 @@ module Bundler
352
359
  o << "\n"
353
360
  o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
354
361
  o << %(the gems in your Gemfile, which may resolve the conflict.\n)
355
- elsif !conflict.existing
362
+ elsif !conflict.existing && !name.end_with?("\0")
356
363
  o << "\n"
357
364
 
358
365
  relevant_source = conflict.requirement.source || source_for(name)
359
366
 
360
- metadata_requirement = name.end_with?("\0")
361
-
362
- o << "Could not find gem '" unless metadata_requirement
363
- o << SharedHelpers.pretty_dependency(conflict.requirement)
364
- o << "'" unless metadata_requirement
365
- if conflict.requirement_trees.first.size > 1
366
- o << ", which is required by "
367
- o << "gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
368
- end
369
- o << " "
370
-
371
- o << if metadata_requirement
372
- "is not available in #{relevant_source}"
367
+ extra_message = if conflict.requirement_trees.first.size > 1
368
+ ", which is required by gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
373
369
  else
374
- "in #{relevant_source.to_err}.\n"
370
+ ""
375
371
  end
372
+
373
+ o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
376
374
  end
377
375
  end,
378
376
  :version_for_spec => lambda {|spec| spec.version },
@@ -103,7 +103,7 @@ module Bundler
103
103
 
104
104
  def self.system
105
105
  ruby_engine = RUBY_ENGINE.dup
106
- ruby_version = ENV.fetch("BUNDLER_SPEC_RUBY_VERSION") { RUBY_VERSION }.dup
106
+ ruby_version = RUBY_VERSION.dup
107
107
  ruby_engine_version = RUBY_ENGINE_VERSION.dup
108
108
  patchlevel = RUBY_PATCHLEVEL.to_s
109
109
 
@@ -4,14 +4,12 @@ require "pathname"
4
4
 
5
5
  require "rubygems/specification"
6
6
 
7
- # Possible use in Gem::Specification#source below and require
8
- # shouldn't be deferred.
9
- require "rubygems/source"
10
-
11
7
  require_relative "match_platform"
12
8
 
13
9
  module Gem
14
10
  class Specification
11
+ include ::Bundler::MatchPlatform
12
+
15
13
  attr_accessor :remote, :location, :relative_loaded_from
16
14
 
17
15
  remove_method :source
@@ -81,10 +79,25 @@ module Gem
81
79
  gemfile
82
80
  end
83
81
 
82
+ # Backfill missing YAML require when not defined. Fixed since 3.1.0.pre1.
83
+ module YamlBackfiller
84
+ def to_yaml(opts = {})
85
+ Gem.load_yaml unless defined?(::YAML)
86
+
87
+ super(opts)
88
+ end
89
+ end
90
+
91
+ prepend YamlBackfiller
92
+
84
93
  def nondevelopment_dependencies
85
94
  dependencies - development_dependencies
86
95
  end
87
96
 
97
+ def deleted_gem?
98
+ !default_gem? && !File.directory?(full_gem_path)
99
+ end
100
+
88
101
  private
89
102
 
90
103
  def dependencies_to_gemfile(dependencies, group = nil)
@@ -134,6 +147,8 @@ module Gem
134
147
  class Requirement
135
148
  module OrderIndependentComparison
136
149
  def ==(other)
150
+ return unless Gem::Requirement === other
151
+
137
152
  if _requirements_sorted? && other._requirements_sorted?
138
153
  super
139
154
  else
@@ -222,9 +237,3 @@ module Gem
222
237
  end
223
238
  end
224
239
  end
225
-
226
- module Gem
227
- class Specification
228
- include ::Bundler::MatchPlatform
229
- end
230
- end
@@ -16,10 +16,12 @@ module Bundler
16
16
  spec.loaded_from = spec_file
17
17
 
18
18
  # Completely remove any previous gem files
19
- FileUtils.rm_rf gem_dir
20
- FileUtils.rm_rf spec.extension_dir
19
+ strict_rm_rf gem_dir
20
+ strict_rm_rf spec.extension_dir
21
21
 
22
- FileUtils.mkdir_p gem_dir, :mode => 0o755
22
+ SharedHelpers.filesystem_access(gem_dir, :create) do
23
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
24
+ end
23
25
 
24
26
  extract_files
25
27
 
@@ -31,7 +33,10 @@ module Bundler
31
33
  generate_plugins
32
34
 
33
35
  write_spec
34
- write_cache_file
36
+
37
+ SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do
38
+ write_cache_file
39
+ end
35
40
 
36
41
  say spec.post_install_message unless spec.post_install_message.nil?
37
42
 
@@ -62,7 +67,7 @@ module Bundler
62
67
  def build_extensions
63
68
  extension_cache_path = options[:bundler_extension_cache_path]
64
69
  unless extension_cache_path && extension_dir = spec.extension_dir
65
- require "shellwords" # compensate missing require in rubygems before version 3.2.25
70
+ require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25")
66
71
  return super
67
72
  end
68
73
 
@@ -87,6 +92,17 @@ module Bundler
87
92
 
88
93
  private
89
94
 
95
+ def strict_rm_rf(dir)
96
+ # FileUtils.rm_rf should probably rise in case of permission issues like
97
+ # `rm -rf` does. However, it fails to delete the folder silently due to
98
+ # https://github.com/ruby/fileutils/issues/57. It should probably be fixed
99
+ # inside `fileutils` but for now I`m checking whether the folder was
100
+ # removed after it completes, and raising otherwise.
101
+ FileUtils.rm_rf dir
102
+
103
+ raise PermissionError.new(dir, :delete) if File.directory?(dir)
104
+ end
105
+
90
106
  def validate_bundler_checksum(checksum)
91
107
  return true if Bundler.settings[:disable_checksum_validation]
92
108
  return true unless checksum
@@ -12,32 +12,30 @@ module Bundler
12
12
  EXT_LOCK = Monitor.new
13
13
  end
14
14
 
15
- def self.version
16
- @version ||= Gem::Version.new(Gem::VERSION)
17
- end
18
-
19
- def self.provides?(req_str)
20
- Gem::Requirement.new(req_str).satisfied_by?(version)
21
- end
22
-
23
15
  def initialize
24
16
  @replaced_methods = {}
25
17
  backport_ext_builder_monitor
26
18
  end
27
19
 
28
20
  def version
29
- self.class.version
21
+ @version ||= Gem.rubygems_version
30
22
  end
31
23
 
32
24
  def provides?(req_str)
33
- self.class.provides?(req_str)
25
+ Gem::Requirement.new(req_str).satisfied_by?(version)
26
+ end
27
+
28
+ def supports_bundler_trampolining?
29
+ provides?(">= 3.3.0.a")
34
30
  end
35
31
 
36
32
  def build_args
33
+ require "rubygems/command"
37
34
  Gem::Command.build_args
38
35
  end
39
36
 
40
37
  def build_args=(args)
38
+ require "rubygems/command"
41
39
  Gem::Command.build_args = args
42
40
  end
43
41
 
@@ -84,16 +82,12 @@ module Bundler
84
82
  def spec_missing_extensions?(spec, default = true)
85
83
  return spec.missing_extensions? if spec.respond_to?(:missing_extensions?)
86
84
 
87
- return false if spec_default_gem?(spec)
85
+ return false if spec.default_gem?
88
86
  return false if spec.extensions.empty?
89
87
 
90
88
  default
91
89
  end
92
90
 
93
- def spec_default_gem?(spec)
94
- spec.respond_to?(:default_gem?) && spec.default_gem?
95
- end
96
-
97
91
  def spec_matches_for_glob(spec, glob)
98
92
  return spec.matches_for_glob(glob) if spec.respond_to?(:matches_for_glob)
99
93
 
@@ -110,18 +104,6 @@ module Bundler
110
104
  obj.to_s
111
105
  end
112
106
 
113
- def configuration
114
- require_relative "psyched_yaml"
115
- Gem.configuration
116
- rescue Gem::SystemExitException, LoadError => e
117
- Bundler.ui.error "#{e.class}: #{e.message}"
118
- Bundler.ui.trace e
119
- raise
120
- rescue YamlLibrarySyntaxError => e
121
- raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
122
- "usually located in ~/.gemrc, contains invalid YAML syntax.")
123
- end
124
-
125
107
  def ruby_engine
126
108
  Gem.ruby_engine
127
109
  end
@@ -144,19 +126,6 @@ module Bundler
144
126
  end
145
127
  end
146
128
 
147
- def sources=(val)
148
- # Gem.configuration creates a new Gem::ConfigFile, which by default will read ~/.gemrc
149
- # If that file exists, its settings (including sources) will overwrite the values we
150
- # are about to set here. In order to avoid that, we force memoizing the config file now.
151
- configuration
152
-
153
- Gem.sources = val
154
- end
155
-
156
- def sources
157
- Gem.sources
158
- end
159
-
160
129
  def gem_dir
161
130
  Gem.dir
162
131
  end
@@ -234,21 +203,9 @@ module Bundler
234
203
  EXT_LOCK
235
204
  end
236
205
 
237
- def with_build_args(args)
238
- ext_lock.synchronize do
239
- old_args = build_args
240
- begin
241
- self.build_args = args
242
- yield
243
- ensure
244
- self.build_args = old_args
245
- end
246
- end
247
- end
248
-
249
206
  def spec_from_gem(path, policy = nil)
250
207
  require "rubygems/security"
251
- require_relative "psyched_yaml"
208
+ require "psych"
252
209
  gem_from_path(path, security_policies[policy]).spec
253
210
  rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
254
211
  if e.is_a?(Gem::Security::Exception) ||
@@ -502,14 +459,15 @@ module Bundler
502
459
  end
503
460
 
504
461
  def fetch_specs(remote, name)
462
+ require "rubygems/remote_fetcher"
505
463
  path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
506
464
  fetcher = gem_remote_fetcher
507
465
  fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
508
466
  string = fetcher.fetch_path(path)
509
467
  Bundler.load_marshal(string)
510
- rescue Gem::RemoteFetcher::FetchError => e
468
+ rescue Gem::RemoteFetcher::FetchError
511
469
  # it's okay for prerelease to fail
512
- raise e unless name == "prerelease_specs"
470
+ raise unless name == "prerelease_specs"
513
471
  end
514
472
 
515
473
  def fetch_all_remote_specs(remote)
@@ -519,12 +477,32 @@ module Bundler
519
477
  specs.concat(pres)
520
478
  end
521
479
 
522
- def download_gem(spec, uri, path)
480
+ def download_gem(spec, uri, cache_dir)
481
+ require "rubygems/remote_fetcher"
523
482
  uri = Bundler.settings.mirror_for(uri)
524
483
  fetcher = gem_remote_fetcher
525
484
  fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
526
485
  Bundler::Retry.new("download gem from #{uri}").attempts do
527
- fetcher.download(spec, uri, path)
486
+ gem_file_name = spec.file_name
487
+ local_gem_path = File.join cache_dir, gem_file_name
488
+ return if File.exist? local_gem_path
489
+
490
+ begin
491
+ remote_gem_path = uri + "gems/#{gem_file_name}"
492
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
493
+
494
+ SharedHelpers.filesystem_access(local_gem_path) do
495
+ fetcher.cache_update_path remote_gem_path, local_gem_path
496
+ end
497
+ rescue Gem::RemoteFetcher::FetchError
498
+ raise if spec.original_platform == spec.platform
499
+
500
+ original_gem_file_name = "#{spec.original_name}.gem"
501
+ raise if gem_file_name == original_gem_file_name
502
+
503
+ gem_file_name = original_gem_file_name
504
+ retry
505
+ end
528
506
  end
529
507
  rescue Gem::RemoteFetcher::FetchError => e
530
508
  raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
@@ -532,7 +510,7 @@ module Bundler
532
510
 
533
511
  def gem_remote_fetcher
534
512
  require "rubygems/remote_fetcher"
535
- proxy = configuration[:http_proxy]
513
+ proxy = Gem.configuration[:http_proxy]
536
514
  Gem::RemoteFetcher.new(proxy)
537
515
  end
538
516
 
@@ -552,10 +530,6 @@ module Bundler
552
530
  Gem::REPOSITORY_SUBDIRECTORIES
553
531
  end
554
532
 
555
- def install_with_build_args(args)
556
- yield
557
- end
558
-
559
533
  def path_separator
560
534
  Gem.path_separator
561
535
  end
@@ -585,6 +559,10 @@ module Bundler
585
559
  end
586
560
  end
587
561
 
562
+ def find_bundler(version)
563
+ find_name("bundler").find {|s| s.version.to_s == version }
564
+ end
565
+
588
566
  def find_name(name)
589
567
  Gem::Specification.stubs_for(name).map(&:to_spec)
590
568
  end
@@ -598,14 +576,6 @@ module Bundler
598
576
  Gem::Specification.send(:default_stubs, "*.gemspec")
599
577
  end
600
578
  end
601
-
602
- def use_gemdeps(gemfile)
603
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
604
- require_relative "gemdeps"
605
- runtime = Bundler.setup
606
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
607
- [Gemdeps.new(runtime), activated_spec_names]
608
- end
609
579
  end
610
580
 
611
581
  def self.rubygems
@@ -265,7 +265,7 @@ module Bundler
265
265
 
266
266
  return if manuals.empty?
267
267
  Bundler::SharedHelpers.set_env "MANPATH", manuals.concat(
268
- ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR)
268
+ ENV["MANPATH"] ? ENV["MANPATH"].to_s.split(File::PATH_SEPARATOR) : [""]
269
269
  ).uniq.join(File::PATH_SEPARATOR)
270
270
  end
271
271
 
@@ -291,7 +291,7 @@ module Bundler
291
291
  return unless activated_spec = Bundler.rubygems.loaded_specs(spec.name)
292
292
  return if activated_spec.version == spec.version
293
293
 
294
- suggestion = if Bundler.rubygems.spec_default_gem?(activated_spec)
294
+ suggestion = if activated_spec.default_gem?
295
295
  "Since #{spec.name} is a default gem, you can either remove your dependency on it" \
296
296
  " or try updating to a newer version of bundler that supports #{spec.name} as a default gem."
297
297
  else