bundler 2.2.26 → 2.3.4

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +166 -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/doctor.rb +3 -2
  9. data/lib/bundler/cli/gem.rb +88 -9
  10. data/lib/bundler/cli/info.rb +16 -4
  11. data/lib/bundler/cli/install.rb +2 -3
  12. data/lib/bundler/cli/issue.rb +4 -3
  13. data/lib/bundler/cli/remove.rb +1 -2
  14. data/lib/bundler/cli/update.rb +2 -2
  15. data/lib/bundler/cli.rb +10 -1
  16. data/lib/bundler/compact_index_client/updater.rb +0 -5
  17. data/lib/bundler/compact_index_client.rb +2 -2
  18. data/lib/bundler/definition.rb +77 -124
  19. data/lib/bundler/dependency.rb +5 -7
  20. data/lib/bundler/digest.rb +71 -0
  21. data/lib/bundler/dsl.rb +18 -30
  22. data/lib/bundler/endpoint_specification.rb +0 -8
  23. data/lib/bundler/environment_preserver.rb +4 -1
  24. data/lib/bundler/errors.rb +18 -2
  25. data/lib/bundler/fetcher/compact_index.rb +9 -4
  26. data/lib/bundler/fetcher.rb +4 -6
  27. data/lib/bundler/friendly_errors.rb +5 -30
  28. data/lib/bundler/gem_helper.rb +6 -17
  29. data/lib/bundler/injector.rb +10 -1
  30. data/lib/bundler/installer/gem_installer.rb +1 -6
  31. data/lib/bundler/installer.rb +1 -5
  32. data/lib/bundler/lazy_specification.rb +17 -1
  33. data/lib/bundler/lockfile_parser.rb +10 -12
  34. data/lib/bundler/man/bundle-add.1 +10 -2
  35. data/lib/bundler/man/bundle-add.1.ronn +7 -1
  36. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  37. data/lib/bundler/man/bundle-cache.1 +1 -1
  38. data/lib/bundler/man/bundle-check.1 +1 -1
  39. data/lib/bundler/man/bundle-clean.1 +1 -1
  40. data/lib/bundler/man/bundle-config.1 +5 -5
  41. data/lib/bundler/man/bundle-config.1.ronn +5 -5
  42. data/lib/bundler/man/bundle-doctor.1 +1 -1
  43. data/lib/bundler/man/bundle-exec.1 +1 -1
  44. data/lib/bundler/man/bundle-gem.1 +14 -1
  45. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  46. data/lib/bundler/man/bundle-info.1 +1 -1
  47. data/lib/bundler/man/bundle-init.1 +1 -1
  48. data/lib/bundler/man/bundle-inject.1 +1 -1
  49. data/lib/bundler/man/bundle-install.1 +2 -2
  50. data/lib/bundler/man/bundle-install.1.ronn +2 -2
  51. data/lib/bundler/man/bundle-list.1 +1 -1
  52. data/lib/bundler/man/bundle-lock.1 +1 -1
  53. data/lib/bundler/man/bundle-open.1 +1 -1
  54. data/lib/bundler/man/bundle-outdated.1 +1 -1
  55. data/lib/bundler/man/bundle-platform.1 +1 -1
  56. data/lib/bundler/man/bundle-pristine.1 +1 -1
  57. data/lib/bundler/man/bundle-remove.1 +1 -1
  58. data/lib/bundler/man/bundle-show.1 +1 -1
  59. data/lib/bundler/man/bundle-update.1 +2 -2
  60. data/lib/bundler/man/bundle-update.1.ronn +2 -1
  61. data/lib/bundler/man/bundle-viz.1 +1 -1
  62. data/lib/bundler/man/bundle.1 +1 -1
  63. data/lib/bundler/man/gemfile.5 +28 -2
  64. data/lib/bundler/man/gemfile.5.ronn +9 -1
  65. data/lib/bundler/plugin/api/source.rb +1 -0
  66. data/lib/bundler/plugin/installer.rb +3 -1
  67. data/lib/bundler/plugin.rb +23 -6
  68. data/lib/bundler/process_lock.rb +1 -1
  69. data/lib/bundler/psyched_yaml.rb +1 -13
  70. data/lib/bundler/resolver.rb +34 -31
  71. data/lib/bundler/ruby_version.rb +1 -1
  72. data/lib/bundler/rubygems_ext.rb +6 -0
  73. data/lib/bundler/rubygems_gem_installer.rb +21 -5
  74. data/lib/bundler/rubygems_integration.rb +39 -57
  75. data/lib/bundler/runtime.rb +2 -2
  76. data/lib/bundler/self_manager.rb +94 -0
  77. data/lib/bundler/settings.rb +10 -1
  78. data/lib/bundler/shared_helpers.rb +4 -12
  79. data/lib/bundler/source/git/git_proxy.rb +7 -4
  80. data/lib/bundler/source/git.rb +22 -4
  81. data/lib/bundler/source/metadata.rb +1 -1
  82. data/lib/bundler/source/rubygems.rb +60 -85
  83. data/lib/bundler/source/rubygems_aggregate.rb +1 -1
  84. data/lib/bundler/source.rb +3 -1
  85. data/lib/bundler/source_list.rb +11 -29
  86. data/lib/bundler/spec_set.rb +2 -2
  87. data/lib/bundler/templates/Executable.bundler +1 -1
  88. data/lib/bundler/templates/Gemfile +0 -2
  89. data/lib/bundler/templates/gems.rb +0 -3
  90. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  91. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  92. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +4 -3
  93. data/lib/bundler/templates/newgem/newgem.gemspec.tt +14 -14
  94. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  95. data/lib/bundler/templates/newgem/standard.yml.tt +2 -0
  96. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  97. data/lib/bundler/ui/shell.rb +1 -1
  98. data/lib/bundler/vendor/.document +1 -0
  99. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  101. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  102. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  103. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  104. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  105. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  107. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  108. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  109. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +6 -6
  110. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +5 -3
  111. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  112. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  113. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  114. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  115. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  116. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  117. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  118. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  119. data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
  120. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  121. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  122. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  123. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  124. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  125. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  126. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  127. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  128. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  129. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  130. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  131. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  132. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  133. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  134. data/lib/bundler/vendored_tsort.rb +4 -0
  135. data/lib/bundler/version.rb +1 -1
  136. data/lib/bundler/worker.rb +2 -2
  137. data/lib/bundler.rb +22 -21
  138. metadata +25 -9
  139. data/lib/bundler/gemdeps.rb +0 -29
  140. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-SHOW" "1" "June 2021" "" ""
4
+ .TH "BUNDLE\-SHOW" "1" "December 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-UPDATE" "1" "June 2021" "" ""
4
+ .TH "BUNDLE\-UPDATE" "1" "December 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-update\fR \- Update your gems to the latest available versions
@@ -47,7 +47,7 @@ Fall back to using the single\-file index of all gems\.
47
47
  .
48
48
  .TP
49
49
  \fB\-\-jobs=[<number>]\fR, \fB\-j[<number>]\fR
50
- Specify the number of jobs to run in parallel\. The default is \fB1\fR\.
50
+ Specify the number of jobs to run in parallel\. The default is the number of available processors\.
51
51
  .
52
52
  .TP
53
53
  \fB\-\-retry=[<number>]\fR
@@ -56,7 +56,8 @@ gem.
56
56
  Fall back to using the single-file index of all gems.
57
57
 
58
58
  * `--jobs=[<number>]`, `-j[<number>]`:
59
- Specify the number of jobs to run in parallel. The default is `1`.
59
+ Specify the number of jobs to run in parallel. The default is the number of
60
+ available processors.
60
61
 
61
62
  * `--retry=[<number>]`:
62
63
  Retry failed network or git requests for <number> times.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE\-VIZ" "1" "June 2021" "" ""
4
+ .TH "BUNDLE\-VIZ" "1" "December 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "BUNDLE" "1" "June 2021" "" ""
4
+ .TH "BUNDLE" "1" "December 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBbundle\fR \- Ruby Dependency Management
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "GEMFILE" "5" "June 2021" "" ""
4
+ .TH "GEMFILE" "5" "December 2021" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
@@ -506,8 +506,34 @@ gem "rails", :git => "git://github\.com/rails/rails\.git"
506
506
  .P
507
507
  Since the \fBgithub\fR method is a specialization of \fBgit_source\fR, it accepts a \fB:branch\fR named argument\.
508
508
  .
509
+ .P
510
+ You can also directly pass a pull request URL:
511
+ .
512
+ .IP "" 4
513
+ .
514
+ .nf
515
+
516
+ gem "rails", :github => "https://github\.com/rails/rails/pull/43753"
517
+ .
518
+ .fi
519
+ .
520
+ .IP "" 0
521
+ .
522
+ .P
523
+ Which is equivalent to:
524
+ .
525
+ .IP "" 4
526
+ .
527
+ .nf
528
+
529
+ gem "rails", :github => "rails/rails", branch: "refs/pull/43753/head"
530
+ .
531
+ .fi
532
+ .
533
+ .IP "" 0
534
+ .
509
535
  .SS "GIST"
510
- If the git repository you want to use is hosted as a Github Gist and is public, you can use the :gist shorthand to specify the gist identifier (without the trailing "\.git")\.
536
+ If the git repository you want to use is hosted as a GitHub Gist and is public, you can use the :gist shorthand to specify the gist identifier (without the trailing "\.git")\.
511
537
  .
512
538
  .IP "" 4
513
539
  .
@@ -372,9 +372,17 @@ Are both equivalent to
372
372
 
373
373
  Since the `github` method is a specialization of `git_source`, it accepts a `:branch` named argument.
374
374
 
375
+ You can also directly pass a pull request URL:
376
+
377
+ gem "rails", :github => "https://github.com/rails/rails/pull/43753"
378
+
379
+ Which is equivalent to:
380
+
381
+ gem "rails", :github => "rails/rails", branch: "refs/pull/43753/head"
382
+
375
383
  ### GIST
376
384
 
377
- If the git repository you want to use is hosted as a Github Gist and is public, you can use
385
+ If the git repository you want to use is hosted as a GitHub Gist and is public, you can use
378
386
  the :gist shorthand to specify the gist identifier (without the trailing ".git").
379
387
 
380
388
  gem "the_hatch", :gist => "4815162342"
@@ -283,6 +283,7 @@ module Bundler
283
283
  def to_s
284
284
  "plugin source for #{@type} with uri #{@uri}"
285
285
  end
286
+ alias_method :identifier, :to_s
286
287
 
287
288
  # Note: Do not override if you don't know what you are doing.
288
289
  def include?(other)
@@ -21,7 +21,7 @@ module Bundler
21
21
  elsif options[:local_git]
22
22
  install_local_git(names, version, options)
23
23
  else
24
- sources = options[:source] || Bundler.rubygems.sources
24
+ sources = options[:source] || Gem.sources
25
25
  install_rubygems(names, version, sources)
26
26
  end
27
27
  end
@@ -81,6 +81,8 @@ module Bundler
81
81
 
82
82
  deps = names.map {|name| Dependency.new name, version }
83
83
 
84
+ Bundler.configure_gem_home_and_path(Plugin.root)
85
+
84
86
  definition = Definition.new(nil, deps, source_list, true)
85
87
  install_definition(definition)
86
88
  end
@@ -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.
@@ -1,22 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Psych could be in the stdlib
4
- # but it's too late if Syck is already loaded
5
3
  begin
6
- require "psych" unless defined?(Syck)
4
+ require "psych"
7
5
  rescue LoadError
8
6
  # Apparently Psych wasn't available. Oh well.
9
7
  end
10
8
 
11
9
  # At least load the YAML stdlib, whatever that may be
12
10
  require "yaml" unless defined?(YAML.dump)
13
-
14
- module Bundler
15
- # On encountering invalid YAML,
16
- # Psych raises Psych::SyntaxError
17
- if defined?(::Psych::SyntaxError)
18
- YamlLibrarySyntaxError = ::Psych::SyntaxError
19
- else # Syck raises ArgumentError
20
- YamlLibrarySyntaxError = ::ArgumentError
21
- end
22
- end
@@ -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
@@ -264,30 +263,37 @@ module Bundler
264
263
  "If you are updating multiple gems in your Gemfile at once,\n" \
265
264
  "try passing them all to `bundle update`"
266
265
  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?
266
+ message = gem_not_found_message(name, requirement, source_for(name))
277
267
  end
278
268
  raise GemNotFound, message
279
269
  end
280
270
  end
281
271
 
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
272
+ def gem_not_found_message(name, requirement, source, extra_message = "")
273
+ specs = source.specs.search(name)
274
+ matching_part = name
275
+ requirement_label = SharedHelpers.pretty_dependency(requirement)
276
+ cache_message = begin
277
+ " or in gems cached in #{Bundler.settings.app_cache_path}" if Bundler.app_cache.exist?
278
+ rescue GemfileNotFound
279
+ nil
280
+ end
281
+ specs_matching_requirement = specs.select {| spec| requirement.matches_spec?(spec) }
282
+
283
+ if specs_matching_requirement.any?
284
+ specs = specs_matching_requirement
285
+ matching_part = requirement_label
286
+ requirement_label = "#{requirement_label} #{requirement.__platform}"
289
287
  end
290
- version_platform_strs.join(", ")
288
+
289
+ message = String.new("Could not find gem '#{requirement_label}'#{extra_message} in #{source}#{cache_message}.\n")
290
+
291
+ if specs.any?
292
+ message << "\nThe source contains the following gems matching '#{matching_part}':\n"
293
+ message << specs.map {|s| " * #{s.full_name}" }.join("\n")
294
+ end
295
+
296
+ message
291
297
  end
292
298
 
293
299
  def version_conflict_message(e)
@@ -359,19 +365,16 @@ module Bundler
359
365
 
360
366
  metadata_requirement = name.end_with?("\0")
361
367
 
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
+ extra_message = if conflict.requirement_trees.first.size > 1
369
+ ", which is required by gem '#{SharedHelpers.pretty_dependency(conflict.requirement_trees.first[-2])}',"
370
+ else
371
+ ""
368
372
  end
369
- o << " "
370
373
 
371
- o << if metadata_requirement
372
- "is not available in #{relevant_source}"
374
+ if metadata_requirement
375
+ o << "#{SharedHelpers.pretty_dependency(conflict.requirement)}#{extra_message} is not available in #{relevant_source}"
373
376
  else
374
- "in #{relevant_source.to_err}.\n"
377
+ o << gem_not_found_message(name, conflict.requirement, relevant_source, extra_message)
375
378
  end
376
379
  end
377
380
  end,
@@ -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
 
@@ -85,6 +85,10 @@ module Gem
85
85
  dependencies - development_dependencies
86
86
  end
87
87
 
88
+ def deleted_gem?
89
+ !default_gem? && !File.directory?(full_gem_path)
90
+ end
91
+
88
92
  private
89
93
 
90
94
  def dependencies_to_gemfile(dependencies, group = nil)
@@ -134,6 +138,8 @@ module Gem
134
138
  class Requirement
135
139
  module OrderIndependentComparison
136
140
  def ==(other)
141
+ return unless Gem::Requirement === other
142
+
137
143
  if _requirements_sorted? && other._requirements_sorted?
138
144
  super
139
145
  else
@@ -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
 
@@ -117,7 +111,7 @@ module Bundler
117
111
  Bundler.ui.error "#{e.class}: #{e.message}"
118
112
  Bundler.ui.trace e
119
113
  raise
120
- rescue YamlLibrarySyntaxError => e
114
+ rescue ::Psych::SyntaxError => e
121
115
  raise YamlSyntaxError.new(e, "Your RubyGems configuration, which is " \
122
116
  "usually located in ~/.gemrc, contains invalid YAML syntax.")
123
117
  end
@@ -144,19 +138,6 @@ module Bundler
144
138
  end
145
139
  end
146
140
 
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
141
  def gem_dir
161
142
  Gem.dir
162
143
  end
@@ -234,18 +215,6 @@ module Bundler
234
215
  EXT_LOCK
235
216
  end
236
217
 
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
218
  def spec_from_gem(path, policy = nil)
250
219
  require "rubygems/security"
251
220
  require_relative "psyched_yaml"
@@ -502,14 +471,15 @@ module Bundler
502
471
  end
503
472
 
504
473
  def fetch_specs(remote, name)
474
+ require "rubygems/remote_fetcher"
505
475
  path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
506
476
  fetcher = gem_remote_fetcher
507
477
  fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
508
478
  string = fetcher.fetch_path(path)
509
479
  Bundler.load_marshal(string)
510
- rescue Gem::RemoteFetcher::FetchError => e
480
+ rescue Gem::RemoteFetcher::FetchError
511
481
  # it's okay for prerelease to fail
512
- raise e unless name == "prerelease_specs"
482
+ raise unless name == "prerelease_specs"
513
483
  end
514
484
 
515
485
  def fetch_all_remote_specs(remote)
@@ -519,12 +489,32 @@ module Bundler
519
489
  specs.concat(pres)
520
490
  end
521
491
 
522
- def download_gem(spec, uri, path)
492
+ def download_gem(spec, uri, cache_dir)
493
+ require "rubygems/remote_fetcher"
523
494
  uri = Bundler.settings.mirror_for(uri)
524
495
  fetcher = gem_remote_fetcher
525
496
  fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
526
497
  Bundler::Retry.new("download gem from #{uri}").attempts do
527
- fetcher.download(spec, uri, path)
498
+ gem_file_name = spec.file_name
499
+ local_gem_path = File.join cache_dir, gem_file_name
500
+ return if File.exist? local_gem_path
501
+
502
+ begin
503
+ remote_gem_path = uri + "gems/#{gem_file_name}"
504
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
505
+
506
+ SharedHelpers.filesystem_access(local_gem_path) do
507
+ fetcher.cache_update_path remote_gem_path, local_gem_path
508
+ end
509
+ rescue Gem::RemoteFetcher::FetchError
510
+ raise if spec.original_platform == spec.platform
511
+
512
+ original_gem_file_name = "#{spec.original_name}.gem"
513
+ raise if gem_file_name == original_gem_file_name
514
+
515
+ gem_file_name = original_gem_file_name
516
+ retry
517
+ end
528
518
  end
529
519
  rescue Gem::RemoteFetcher::FetchError => e
530
520
  raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
@@ -552,10 +542,6 @@ module Bundler
552
542
  Gem::REPOSITORY_SUBDIRECTORIES
553
543
  end
554
544
 
555
- def install_with_build_args(args)
556
- yield
557
- end
558
-
559
545
  def path_separator
560
546
  Gem.path_separator
561
547
  end
@@ -585,6 +571,10 @@ module Bundler
585
571
  end
586
572
  end
587
573
 
574
+ def find_bundler(version)
575
+ find_name("bundler").find {|s| s.version.to_s == version }
576
+ end
577
+
588
578
  def find_name(name)
589
579
  Gem::Specification.stubs_for(name).map(&:to_spec)
590
580
  end
@@ -598,14 +588,6 @@ module Bundler
598
588
  Gem::Specification.send(:default_stubs, "*.gemspec")
599
589
  end
600
590
  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
591
  end
610
592
 
611
593
  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