bundler 2.2.11 → 2.3.26

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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +721 -5
  3. data/README.md +1 -1
  4. data/bundler.gemspec +8 -11
  5. data/exe/bundle +7 -8
  6. data/exe/bundler +1 -1
  7. data/lib/bundler/.document +1 -0
  8. data/lib/bundler/build_metadata.rb +3 -3
  9. data/lib/bundler/cli/cache.rb +1 -1
  10. data/lib/bundler/cli/check.rb +4 -2
  11. data/lib/bundler/cli/common.rb +17 -3
  12. data/lib/bundler/cli/config.rb +10 -1
  13. data/lib/bundler/cli/doctor.rb +24 -5
  14. data/lib/bundler/cli/exec.rb +1 -6
  15. data/lib/bundler/cli/gem.rb +130 -26
  16. data/lib/bundler/cli/info.rb +27 -6
  17. data/lib/bundler/cli/init.rb +5 -1
  18. data/lib/bundler/cli/install.rb +23 -54
  19. data/lib/bundler/cli/issue.rb +4 -3
  20. data/lib/bundler/cli/list.rb +7 -1
  21. data/lib/bundler/cli/lock.rb +5 -1
  22. data/lib/bundler/cli/open.rb +1 -2
  23. data/lib/bundler/cli/outdated.rb +22 -14
  24. data/lib/bundler/cli/platform.rb +2 -2
  25. data/lib/bundler/cli/remove.rb +1 -2
  26. data/lib/bundler/cli/show.rb +1 -1
  27. data/lib/bundler/cli/update.rb +17 -8
  28. data/lib/bundler/cli.rb +51 -63
  29. data/lib/bundler/compact_index_client/cache.rb +0 -9
  30. data/lib/bundler/compact_index_client/updater.rb +26 -14
  31. data/lib/bundler/compact_index_client.rb +2 -8
  32. data/lib/bundler/current_ruby.rb +17 -6
  33. data/lib/bundler/definition.rb +260 -362
  34. data/lib/bundler/dependency.rb +23 -71
  35. data/lib/bundler/digest.rb +71 -0
  36. data/lib/bundler/dsl.rb +72 -76
  37. data/lib/bundler/endpoint_specification.rb +19 -13
  38. data/lib/bundler/env.rb +1 -1
  39. data/lib/bundler/environment_preserver.rb +4 -1
  40. data/lib/bundler/errors.rb +29 -3
  41. data/lib/bundler/feature_flag.rb +0 -5
  42. data/lib/bundler/fetcher/base.rb +6 -8
  43. data/lib/bundler/fetcher/compact_index.rb +10 -15
  44. data/lib/bundler/fetcher/downloader.rb +9 -6
  45. data/lib/bundler/fetcher/index.rb +0 -27
  46. data/lib/bundler/fetcher.rb +22 -23
  47. data/lib/bundler/friendly_errors.rb +26 -36
  48. data/lib/bundler/gem_helper.rb +21 -16
  49. data/lib/bundler/gem_helpers.rb +9 -2
  50. data/lib/bundler/gem_version_promoter.rb +14 -25
  51. data/lib/bundler/index.rb +11 -46
  52. data/lib/bundler/injector.rb +18 -4
  53. data/lib/bundler/inline.rb +4 -13
  54. data/lib/bundler/installer/gem_installer.rb +16 -21
  55. data/lib/bundler/installer/parallel_installer.rb +36 -15
  56. data/lib/bundler/installer/standalone.rb +42 -10
  57. data/lib/bundler/installer.rb +25 -41
  58. data/lib/bundler/lazy_specification.rb +52 -30
  59. data/lib/bundler/lockfile_generator.rb +2 -2
  60. data/lib/bundler/lockfile_parser.rb +18 -43
  61. data/lib/bundler/man/bundle-add.1 +21 -5
  62. data/lib/bundler/man/bundle-add.1.ronn +16 -4
  63. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  64. data/lib/bundler/man/bundle-cache.1 +7 -1
  65. data/lib/bundler/man/bundle-cache.1.ronn +7 -0
  66. data/lib/bundler/man/bundle-check.1 +1 -1
  67. data/lib/bundler/man/bundle-clean.1 +2 -2
  68. data/lib/bundler/man/bundle-clean.1.ronn +1 -1
  69. data/lib/bundler/man/bundle-config.1 +49 -22
  70. data/lib/bundler/man/bundle-config.1.ronn +49 -30
  71. data/lib/bundler/man/bundle-console.1 +53 -0
  72. data/lib/bundler/man/bundle-console.1.ronn +44 -0
  73. data/lib/bundler/man/bundle-doctor.1 +1 -1
  74. data/lib/bundler/man/bundle-exec.1 +2 -2
  75. data/lib/bundler/man/bundle-exec.1.ronn +1 -1
  76. data/lib/bundler/man/bundle-gem.1 +14 -1
  77. data/lib/bundler/man/bundle-gem.1.ronn +16 -0
  78. data/lib/bundler/man/bundle-help.1 +13 -0
  79. data/lib/bundler/man/bundle-help.1.ronn +12 -0
  80. data/lib/bundler/man/bundle-info.1 +1 -1
  81. data/lib/bundler/man/bundle-init.1 +1 -1
  82. data/lib/bundler/man/bundle-inject.1 +5 -2
  83. data/lib/bundler/man/bundle-inject.1.ronn +3 -1
  84. data/lib/bundler/man/bundle-install.1 +6 -2
  85. data/lib/bundler/man/bundle-install.1.ronn +8 -2
  86. data/lib/bundler/man/bundle-list.1 +1 -1
  87. data/lib/bundler/man/bundle-lock.1 +1 -1
  88. data/lib/bundler/man/bundle-open.1 +1 -1
  89. data/lib/bundler/man/bundle-outdated.1 +3 -10
  90. data/lib/bundler/man/bundle-outdated.1.ronn +1 -10
  91. data/lib/bundler/man/bundle-platform.1 +16 -6
  92. data/lib/bundler/man/bundle-platform.1.ronn +14 -7
  93. data/lib/bundler/man/bundle-plugin.1 +81 -0
  94. data/lib/bundler/man/bundle-plugin.1.ronn +59 -0
  95. data/lib/bundler/man/bundle-pristine.1 +1 -1
  96. data/lib/bundler/man/bundle-remove.1 +1 -1
  97. data/lib/bundler/man/bundle-show.1 +1 -1
  98. data/lib/bundler/man/bundle-update.1 +5 -5
  99. data/lib/bundler/man/bundle-update.1.ronn +5 -4
  100. data/lib/bundler/man/bundle-version.1 +35 -0
  101. data/lib/bundler/man/bundle-version.1.ronn +24 -0
  102. data/lib/bundler/man/bundle-viz.1 +4 -1
  103. data/lib/bundler/man/bundle-viz.1.ronn +2 -0
  104. data/lib/bundler/man/bundle.1 +15 -10
  105. data/lib/bundler/man/bundle.1.ronn +12 -7
  106. data/lib/bundler/man/gemfile.5 +117 -80
  107. data/lib/bundler/man/gemfile.5.ronn +105 -84
  108. data/lib/bundler/man/index.txt +4 -0
  109. data/lib/bundler/match_metadata.rb +13 -0
  110. data/lib/bundler/match_platform.rb +0 -1
  111. data/lib/bundler/match_remote_metadata.rb +29 -0
  112. data/lib/bundler/plugin/api/source.rb +24 -8
  113. data/lib/bundler/plugin/index.rb +4 -1
  114. data/lib/bundler/plugin/installer/git.rb +0 -4
  115. data/lib/bundler/plugin/installer/rubygems.rb +0 -4
  116. data/lib/bundler/plugin/installer.rb +10 -10
  117. data/lib/bundler/plugin/source_list.rb +4 -0
  118. data/lib/bundler/plugin.rb +30 -8
  119. data/lib/bundler/process_lock.rb +1 -1
  120. data/lib/bundler/remote_specification.rb +10 -4
  121. data/lib/bundler/resolver/base.rb +50 -0
  122. data/lib/bundler/resolver/spec_group.rb +31 -73
  123. data/lib/bundler/resolver.rb +193 -292
  124. data/lib/bundler/retry.rb +1 -1
  125. data/lib/bundler/ruby_dsl.rb +1 -1
  126. data/lib/bundler/ruby_version.rb +5 -18
  127. data/lib/bundler/rubygems_ext.rb +160 -26
  128. data/lib/bundler/rubygems_gem_installer.rb +86 -9
  129. data/lib/bundler/rubygems_integration.rb +46 -93
  130. data/lib/bundler/runtime.rb +18 -12
  131. data/lib/bundler/self_manager.rb +168 -0
  132. data/lib/bundler/settings.rb +98 -22
  133. data/lib/bundler/setup.rb +2 -2
  134. data/lib/bundler/shared_helpers.rb +15 -31
  135. data/lib/bundler/source/git/git_proxy.rb +8 -6
  136. data/lib/bundler/source/git.rb +29 -13
  137. data/lib/bundler/source/metadata.rb +3 -7
  138. data/lib/bundler/source/path/installer.rb +1 -1
  139. data/lib/bundler/source/path.rb +3 -1
  140. data/lib/bundler/source/rubygems.rb +199 -182
  141. data/lib/bundler/source/rubygems_aggregate.rb +68 -0
  142. data/lib/bundler/source.rb +24 -4
  143. data/lib/bundler/source_list.rb +104 -60
  144. data/lib/bundler/source_map.rb +71 -0
  145. data/lib/bundler/spec_set.rb +58 -52
  146. data/lib/bundler/stub_specification.rb +13 -3
  147. data/lib/bundler/templates/Executable +2 -4
  148. data/lib/bundler/templates/Executable.bundler +8 -8
  149. data/lib/bundler/templates/Executable.standalone +2 -4
  150. data/lib/bundler/templates/Gemfile +0 -2
  151. data/lib/bundler/templates/gems.rb +0 -3
  152. data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
  153. data/lib/bundler/templates/newgem/README.md.tt +8 -12
  154. data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
  155. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +16 -7
  156. data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +5 -4
  157. data/lib/bundler/templates/newgem/newgem.gemspec.tt +19 -17
  158. data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
  159. data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
  160. data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
  161. data/lib/bundler/ui/shell.rb +1 -1
  162. data/lib/bundler/vendor/.document +1 -0
  163. data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
  164. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
  165. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  166. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
  167. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
  168. data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
  169. data/lib/bundler/vendor/molinillo/LICENSE +9 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +3 -3
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +32 -26
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
  174. data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
  175. data/lib/bundler/vendor/thor/LICENSE.md +20 -0
  176. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
  177. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
  178. data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
  179. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
  180. data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
  181. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
  182. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
  183. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  184. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  185. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  186. data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
  187. data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
  188. data/lib/bundler/vendor/tsort/lib/tsort.rb +452 -0
  189. data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
  190. data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
  191. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
  192. data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
  193. data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
  194. data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
  195. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
  196. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
  197. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
  198. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
  199. data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  200. data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
  201. data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
  202. data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
  203. data/lib/bundler/vendored_tsort.rb +4 -0
  204. data/lib/bundler/version.rb +1 -1
  205. data/lib/bundler/worker.rb +19 -4
  206. data/lib/bundler.rb +46 -39
  207. metadata +39 -12
  208. data/lib/bundler/dep_proxy.rb +0 -55
  209. data/lib/bundler/gemdeps.rb +0 -29
  210. data/lib/bundler/psyched_yaml.rb +0 -22
  211. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
@@ -57,22 +57,17 @@ module Bundler
57
57
  gem_info
58
58
  end
59
59
 
60
- def fetch_spec(spec)
61
- spec -= [nil, "ruby", ""]
62
- contents = compact_index_client.spec(*spec)
63
- return nil if contents.nil?
64
- contents.unshift(spec.first)
65
- contents[3].map! {|d| Gem::Dependency.new(*d) }
66
- EndpointSpecification.new(*contents)
67
- end
68
- compact_index_request :fetch_spec
69
-
70
60
  def available?
71
- return nil unless SharedHelpers.md5_available?
72
- user_home = Bundler.user_home
73
- return nil unless user_home.directory? && user_home.writable?
61
+ unless SharedHelpers.md5_available?
62
+ Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API")
63
+ return nil
64
+ end
65
+ if fetch_uri.scheme == "file"
66
+ Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
67
+ return false
68
+ end
74
69
  # Read info file checksums out of /versions, so we can know if gems are up to date
75
- fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
70
+ compact_index_client.update_and_parse_checksums!
76
71
  rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
77
72
  Bundler.ui.debug(e.message)
78
73
  nil
@@ -111,7 +106,7 @@ module Bundler
111
106
  def bundle_worker(func = nil)
112
107
  @bundle_worker ||= begin
113
108
  worker_name = "Compact Index (#{display_uri.host})"
114
- Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
109
+ Bundler::Worker.new(Bundler.settings.processor_count, worker_name, func)
115
110
  end
116
111
  @bundle_worker.tap do |worker|
117
112
  worker.instance_variable_set(:@func, func) if func
@@ -14,8 +14,10 @@ module Bundler
14
14
  def fetch(uri, headers = {}, counter = 0)
15
15
  raise HTTPError, "Too many redirects" if counter >= redirect_limit
16
16
 
17
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
18
+
17
19
  response = request(uri, headers)
18
- Bundler.ui.debug("HTTP #{response.code} #{response.message} #{uri}")
20
+ Bundler.ui.debug("HTTP #{response.code} #{response.message} #{filtered_uri}")
19
21
 
20
22
  case response
21
23
  when Net::HTTPSuccess, Net::HTTPNotModified
@@ -40,7 +42,7 @@ module Bundler
40
42
  raise BadAuthenticationError, uri.host if uri.userinfo
41
43
  raise AuthenticationRequiredError, uri.host
42
44
  when Net::HTTPNotFound
43
- raise FallbackError, "Net::HTTPNotFound: #{URICredentialsFilter.credential_filtered_uri(uri)}"
45
+ raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}"
44
46
  else
45
47
  raise HTTPError, "#{response.class}#{": #{response.body}" unless response.body.empty?}"
46
48
  end
@@ -49,7 +51,9 @@ module Bundler
49
51
  def request(uri, headers)
50
52
  validate_uri_scheme!(uri)
51
53
 
52
- Bundler.ui.debug "HTTP GET #{uri}"
54
+ filtered_uri = URICredentialsFilter.credential_filtered_uri(uri)
55
+
56
+ Bundler.ui.debug "HTTP GET #{filtered_uri}"
53
57
  req = Net::HTTP::Get.new uri.request_uri, headers
54
58
  if uri.user
55
59
  user = CGI.unescape(uri.user)
@@ -64,12 +68,11 @@ module Bundler
64
68
  raise CertificateFailureError.new(uri)
65
69
  rescue *HTTP_ERRORS => e
66
70
  Bundler.ui.trace e
67
- case e.message
68
- when /host down:/, /getaddrinfo: nodename nor servname provided/
71
+ if e.is_a?(SocketError) || e.message =~ /host down:/
69
72
  raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
70
73
  "connection and try again."
71
74
  else
72
- raise HTTPError, "Network error while fetching #{URICredentialsFilter.credential_filtered_uri(uri)}" \
75
+ raise HTTPError, "Network error while fetching #{filtered_uri}" \
73
76
  " (#{e})"
74
77
  end
75
78
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "base"
4
- require "rubygems/remote_fetcher"
5
4
 
6
5
  module Bundler
7
6
  class Fetcher
@@ -22,32 +21,6 @@ module Bundler
22
21
  raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>"
23
22
  end
24
23
  end
25
-
26
- def fetch_spec(spec)
27
- spec -= [nil, "ruby", ""]
28
- spec_file_name = "#{spec.join "-"}.gemspec"
29
-
30
- uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
31
- if uri.scheme == "file"
32
- path = Bundler.rubygems.correct_for_windows_path(uri.path)
33
- Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(path))
34
- elsif cached_spec_path = gemspec_cached_path(spec_file_name)
35
- Bundler.load_gemspec(cached_spec_path)
36
- else
37
- Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
38
- end
39
- rescue MarshalError
40
- raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
41
- "Your network or your gem server is probably having issues right now."
42
- end
43
-
44
- private
45
-
46
- # cached gem specification path, if one exists
47
- def gemspec_cached_path(spec_file_name)
48
- paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
49
- paths.find {|path| File.file? path }
50
- end
51
24
  end
52
25
  end
53
26
  end
@@ -20,6 +20,7 @@ module Bundler
20
20
  class TooManyRequestsError < HTTPError; end
21
21
  # This error is raised if the API returns a 413 (only printed in verbose)
22
22
  class FallbackError < HTTPError; end
23
+
23
24
  # This is the error raised if OpenSSL fails the cert verification
24
25
  class CertificateFailureError < HTTPError
25
26
  def initialize(remote_uri)
@@ -28,10 +29,12 @@ module Bundler
28
29
  " is a chance you are experiencing a man-in-the-middle attack, but" \
29
30
  " most likely your system doesn't have the CA certificates needed" \
30
31
  " for verification. For information about OpenSSL certificates, see" \
31
- " http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
32
+ " https://railsapps.github.io/openssl-certificate-verify-failed.html." \
33
+ " To connect without using SSL, edit your Gemfile" \
32
34
  " sources and change 'https' to 'http'."
33
35
  end
34
36
  end
37
+
35
38
  # This is the error raised when a source is HTTPS and OpenSSL didn't load
36
39
  class SSLError < HTTPError
37
40
  def initialize(msg = nil)
@@ -41,15 +44,18 @@ module Bundler
41
44
  "using RVM are available at rvm.io/packages/openssl."
42
45
  end
43
46
  end
47
+
44
48
  # This error is raised if HTTP authentication is required, but not provided.
45
49
  class AuthenticationRequiredError < HTTPError
46
50
  def initialize(remote_uri)
47
51
  remote_uri = filter_uri(remote_uri)
48
52
  super "Authentication is required for #{remote_uri}.\n" \
49
53
  "Please supply credentials for this source. You can do this by running:\n" \
50
- " bundle config set --global #{remote_uri} username:password"
54
+ "`bundle config set --global #{remote_uri} username:password`\n" \
55
+ "or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable"
51
56
  end
52
57
  end
58
+
53
59
  # This error is raised if HTTP authentication is provided, but incorrect.
54
60
  class BadAuthenticationError < HTTPError
55
61
  def initialize(remote_uri)
@@ -69,8 +75,8 @@ module Bundler
69
75
  :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
70
76
  FAIL_ERRORS = begin
71
77
  fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
72
- fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
73
- fail_errors.concat(NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
78
+ fail_errors << Gem::Requirement::BadRequirementError
79
+ fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) })
74
80
  end.freeze
75
81
 
76
82
  class << self
@@ -120,7 +126,6 @@ module Bundler
120
126
 
121
127
  # return the specs in the bundler format as an index
122
128
  def specs(gem_names, source)
123
- old = Bundler.rubygems.sources
124
129
  index = Bundler::Index.new
125
130
 
126
131
  if Bundler::Fetcher.disable_endpoint
@@ -128,17 +133,15 @@ module Bundler
128
133
  specs = fetchers.last.specs(gem_names)
129
134
  else
130
135
  specs = []
131
- fetchers.shift until fetchers.first.available? || fetchers.empty?
132
- fetchers.dup.each do |f|
133
- break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
134
- fetchers.delete(f)
136
+ @fetchers = fetchers.drop_while do |f|
137
+ !f.available? || (f.api_fetcher? && !gem_names) || !specs = f.specs(gem_names)
135
138
  end
136
139
  @use_api = false if fetchers.none?(&:api_fetcher?)
137
140
  end
138
141
 
139
142
  specs.each do |name, version, platform, dependencies, metadata|
140
143
  spec = if dependencies
141
- EndpointSpecification.new(name, version, platform, dependencies, metadata)
144
+ EndpointSpecification.new(name, version, platform, self, dependencies, metadata)
142
145
  else
143
146
  RemoteSpecification.new(name, version, platform, self)
144
147
  end
@@ -151,8 +154,6 @@ module Bundler
151
154
  rescue CertificateFailureError
152
155
  Bundler.ui.info "" if gem_names && use_api # newline after dots
153
156
  raise
154
- ensure
155
- Bundler.rubygems.sources = old
156
157
  end
157
158
 
158
159
  def use_api
@@ -229,6 +230,7 @@ module Bundler
229
230
  "GO_SERVER_URL" => "go",
230
231
  "SNAP_CI" => "snap",
231
232
  "GITLAB_CI" => "gitlab",
233
+ "GITHUB_ACTIONS" => "github",
232
234
  "CI_NAME" => ENV["CI_NAME"],
233
235
  "CI" => "ci",
234
236
  }
@@ -238,12 +240,12 @@ module Bundler
238
240
  def connection
239
241
  @connection ||= begin
240
242
  needs_ssl = remote_uri.scheme == "https" ||
241
- Bundler.settings[:ssl_verify_mode] ||
242
- Bundler.settings[:ssl_client_cert]
243
+ Bundler.settings[:ssl_verify_mode] ||
244
+ Bundler.settings[:ssl_client_cert]
243
245
  raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
244
246
 
245
247
  con = PersistentHTTP.new :name => "bundler", :proxy => :ENV
246
- if gem_proxy = Bundler.rubygems.configuration[:http_proxy]
248
+ if gem_proxy = Gem.configuration[:http_proxy]
247
249
  con.proxy = Bundler::URI.parse(gem_proxy) if gem_proxy != :no_proxy
248
250
  end
249
251
 
@@ -254,8 +256,8 @@ module Bundler
254
256
  end
255
257
 
256
258
  ssl_client_cert = Bundler.settings[:ssl_client_cert] ||
257
- (Bundler.rubygems.configuration.ssl_client_cert if
258
- Bundler.rubygems.configuration.respond_to?(:ssl_client_cert))
259
+ (Gem.configuration.ssl_client_cert if
260
+ Gem.configuration.respond_to?(:ssl_client_cert))
259
261
  if ssl_client_cert
260
262
  pem = File.read(ssl_client_cert)
261
263
  con.cert = OpenSSL::X509::Certificate.new(pem)
@@ -273,8 +275,7 @@ module Bundler
273
275
  # cached gem specification path, if one exists
274
276
  def gemspec_cached_path(spec_file_name)
275
277
  paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
276
- paths = paths.select {|path| File.file? path }
277
- paths.first
278
+ paths.find {|path| File.file? path }
278
279
  end
279
280
 
280
281
  HTTP_ERRORS = [
@@ -287,8 +288,8 @@ module Bundler
287
288
  def bundler_cert_store
288
289
  store = OpenSSL::X509::Store.new
289
290
  ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
290
- (Bundler.rubygems.configuration.ssl_ca_cert if
291
- Bundler.rubygems.configuration.respond_to?(:ssl_ca_cert))
291
+ (Gem.configuration.ssl_ca_cert if
292
+ Gem.configuration.respond_to?(:ssl_ca_cert))
292
293
  if ssl_ca_cert
293
294
  if File.directory? ssl_ca_cert
294
295
  store.add_path ssl_ca_cert
@@ -302,8 +303,6 @@ module Bundler
302
303
  store
303
304
  end
304
305
 
305
- private
306
-
307
306
  def remote_uri
308
307
  @remote.uri
309
308
  end
@@ -29,8 +29,11 @@ module Bundler
29
29
  Bundler.ui.error error.message
30
30
  Bundler.ui.trace error.orig_exception
31
31
  when BundlerError
32
- Bundler.ui.error error.message, :wrap => true
33
- Bundler.ui.trace error
32
+ if Bundler.ui.debug?
33
+ Bundler.ui.trace error
34
+ else
35
+ Bundler.ui.error error.message, :wrap => true
36
+ end
34
37
  when Thor::Error
35
38
  Bundler.ui.error error.message
36
39
  when LoadError
@@ -49,8 +52,6 @@ module Bundler
49
52
  "Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)."
50
53
  else request_issue_report_for(error)
51
54
  end
52
- rescue StandardError
53
- raise error
54
55
  end
55
56
 
56
57
  def exit_status(error)
@@ -65,38 +66,9 @@ module Bundler
65
66
  def request_issue_report_for(e)
66
67
  Bundler.ui.error <<-EOS.gsub(/^ {8}/, ""), nil, nil
67
68
  --- ERROR REPORT TEMPLATE -------------------------------------------------------
68
- # Error Report
69
-
70
- ## Questions
71
-
72
- Please fill out answers to these questions, it'll help us figure out
73
- why things are going wrong.
74
-
75
- - **What did you do?**
76
-
77
- I ran the command `#{$PROGRAM_NAME} #{ARGV.join(" ")}`
78
-
79
- - **What did you expect to happen?**
80
-
81
- I expected Bundler to...
82
-
83
- - **What happened instead?**
84
-
85
- Instead, what happened was...
86
-
87
- - **Have you tried any solutions posted on similar issues in our issue tracker, stack overflow, or google?**
88
-
89
- I tried...
90
-
91
- - **Have you read our issues document, https://github.com/rubygems/rubygems/blob/master/bundler/doc/contributing/ISSUES.md?**
92
-
93
- ...
94
-
95
- ## Backtrace
96
69
 
97
70
  ```
98
- #{e.class}: #{e.message}
99
- #{e.backtrace && e.backtrace.join("\n ").chomp}
71
+ #{exception_message(e)}
100
72
  ```
101
73
 
102
74
  #{Bundler::Env.report}
@@ -111,8 +83,22 @@ module Bundler
111
83
  First, try this link to see if there are any existing issue reports for this error:
112
84
  #{issues_url(e)}
113
85
 
114
- If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
115
- https://github.com/rubygems/rubygems/issues/new?labels=Bundler
86
+ If there aren't any reports for this error yet, please fill in the new issue form located at #{new_issue_url}, and copy and paste the report template above in there.
87
+ EOS
88
+ end
89
+
90
+ def exception_message(error)
91
+ message = serialized_exception_for(error)
92
+ cause = error.cause
93
+ return message unless cause
94
+
95
+ message + serialized_exception_for(cause)
96
+ end
97
+
98
+ def serialized_exception_for(e)
99
+ <<-EOS.gsub(/^ {8}/, "")
100
+ #{e.class}: #{e.message}
101
+ #{e.backtrace && e.backtrace.join("\n ").chomp}
116
102
  EOS
117
103
  end
118
104
 
@@ -123,6 +109,10 @@ module Bundler
123
109
  "https://github.com/rubygems/rubygems/search?q=" \
124
110
  "#{CGI.escape(message)}&type=Issues"
125
111
  end
112
+
113
+ def new_issue_url
114
+ "https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md"
115
+ end
126
116
  end
127
117
 
128
118
  def self.with_friendly_errors
@@ -47,6 +47,11 @@ module Bundler
47
47
  built_gem_path = build_gem
48
48
  end
49
49
 
50
+ desc "Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."
51
+ task "build:checksum" => "build" do
52
+ build_checksum(built_gem_path)
53
+ end
54
+
50
55
  desc "Build and install #{name}-#{version}.gem into system gems."
51
56
  task "install" => "build" do
52
57
  install_gem(built_gem_path)
@@ -71,7 +76,7 @@ module Bundler
71
76
  tag_version { git_push(args[:remote]) } unless already_tagged?
72
77
  end
73
78
 
74
- task "release:rubygem_push" do
79
+ task "release:rubygem_push" => "build" do
75
80
  rubygem_push(built_gem_path) if gem_push?
76
81
  end
77
82
 
@@ -93,13 +98,21 @@ module Bundler
93
98
  built_gem_path ||= build_gem
94
99
  cmd = [*gem_command, "install", built_gem_path.to_s]
95
100
  cmd << "--local" if local
96
- _, status = sh_with_status(cmd)
97
- unless status.success?
98
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output"
99
- end
101
+ sh(cmd)
100
102
  Bundler.ui.confirm "#{name} (#{version}) installed."
101
103
  end
102
104
 
105
+ def build_checksum(built_gem_path = nil)
106
+ built_gem_path ||= build_gem
107
+ SharedHelpers.filesystem_access(File.join(base, "checksums")) {|p| FileUtils.mkdir_p(p) }
108
+ file_name = "#{File.basename(built_gem_path)}.sha512"
109
+ require "digest/sha2"
110
+ checksum = ::Digest::SHA512.file(built_gem_path).hexdigest
111
+ target = File.join(base, "checksums", file_name)
112
+ File.write(target, checksum + "\n")
113
+ Bundler.ui.confirm "#{name} #{version} checksum written to checksums/#{file_name}."
114
+ end
115
+
103
116
  protected
104
117
 
105
118
  def rubygem_push(path)
@@ -116,8 +129,8 @@ module Bundler
116
129
 
117
130
  def git_push(remote = nil)
118
131
  remote ||= default_remote
119
- perform_git_push "#{remote} refs/heads/#{current_branch}"
120
- perform_git_push "#{remote} refs/tags/#{version_tag}"
132
+ sh("git push #{remote} refs/heads/#{current_branch}".shellsplit)
133
+ sh("git push #{remote} refs/tags/#{version_tag}".shellsplit)
121
134
  Bundler.ui.confirm "Pushed git commits and release tag."
122
135
  end
123
136
 
@@ -145,13 +158,6 @@ module Bundler
145
158
  allowed_push_host || env_rubygems_host || "rubygems.org"
146
159
  end
147
160
 
148
- def perform_git_push(options = "")
149
- cmd = "git push #{options}"
150
- out, status = sh_with_status(cmd.shellsplit)
151
- return if status.success?
152
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n"
153
- end
154
-
155
161
  def already_tagged?
156
162
  return false unless sh(%w[git tag]).split(/\n/).include?(version_tag)
157
163
  Bundler.ui.confirm "Tag #{version_tag} has already been created."
@@ -202,8 +208,7 @@ module Bundler
202
208
  def sh(cmd, &block)
203
209
  out, status = sh_with_status(cmd, &block)
204
210
  unless status.success?
205
- cmd = cmd.shelljoin if cmd.respond_to?(:shelljoin)
206
- raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
211
+ raise("Running `#{cmd.shelljoin}` failed with the following output:\n\n#{out}\n")
207
212
  end
208
213
  out
209
214
  end
@@ -10,6 +10,7 @@ module Bundler
10
10
  [Gem::Platform.new("universal-mingw32"), Gem::Platform.new("universal-mingw32")],
11
11
  [Gem::Platform.new("x64-mingw32"), Gem::Platform.new("x64-mingw32")],
12
12
  [Gem::Platform.new("x86_64-mingw32"), Gem::Platform.new("x64-mingw32")],
13
+ [Gem::Platform.new("x64-mingw-ucrt"), Gem::Platform.new("x64-mingw-ucrt")],
13
14
  [Gem::Platform.new("mingw32"), Gem::Platform.new("x86-mingw32")],
14
15
  ].freeze
15
16
 
@@ -42,15 +43,21 @@ module Bundler
42
43
 
43
44
  def select_best_platform_match(specs, platform)
44
45
  matching = specs.select {|spec| spec.match_platform(platform) }
46
+
47
+ sort_best_platform_match(matching, platform)
48
+ end
49
+ module_function :select_best_platform_match
50
+
51
+ def sort_best_platform_match(matching, platform)
45
52
  exact = matching.select {|spec| spec.platform == platform }
46
53
  return exact if exact.any?
47
54
 
48
55
  sorted_matching = matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) }
49
56
  exemplary_spec = sorted_matching.first
50
57
 
51
- sorted_matching.take_while{|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
58
+ sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
52
59
  end
53
- module_function :select_best_platform_match
60
+ module_function :sort_best_platform_match
54
61
 
55
62
  class PlatformMatch
56
63
  def self.specificity_score(spec_platform, user_platform)
@@ -55,19 +55,17 @@ module Bundler
55
55
  @level = v
56
56
  end
57
57
 
58
- # Given a Dependency and an Array of SpecGroups of available versions for a
59
- # gem, this method will return the Array of SpecGroups sorted (and possibly
58
+ # Given a Dependency and an Array of Specifications of available versions for a
59
+ # gem, this method will return the Array of Specifications sorted (and possibly
60
60
  # truncated if strict is true) in an order to give preference to the current
61
61
  # level (:major, :minor or :patch) when resolution is deciding what versions
62
62
  # best resolve all dependencies in the bundle.
63
63
  # @param dep [Dependency] The Dependency of the gem.
64
- # @param spec_groups [SpecGroup] An array of SpecGroups for the same gem
64
+ # @param spec_groups [Specification] An array of Specifications for the same gem
65
65
  # named in the @dep param.
66
- # @return [SpecGroup] A new instance of the SpecGroup Array sorted and
66
+ # @return [Specification] A new instance of the Specification Array sorted and
67
67
  # possibly filtered.
68
68
  def sort_versions(dep, spec_groups)
69
- before_result = "before sort_versions: #{debug_format_result(dep, spec_groups).inspect}" if DEBUG
70
-
71
69
  @sort_versions[dep] ||= begin
72
70
  gem_name = dep.name
73
71
 
@@ -79,15 +77,14 @@ module Bundler
79
77
  filter_dep_specs(spec_groups, locked_spec)
80
78
  else
81
79
  sort_dep_specs(spec_groups, locked_spec)
82
- end.tap do |specs|
83
- if DEBUG
84
- puts before_result
85
- puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
86
- end
87
80
  end
88
81
  end
89
82
  end
90
83
 
84
+ def reset
85
+ @sort_versions = {}
86
+ end
87
+
91
88
  # @return [bool] Convenience method for testing value of level variable.
92
89
  def major?
93
90
  level == :major
@@ -119,15 +116,14 @@ module Bundler
119
116
  end
120
117
 
121
118
  def sort_dep_specs(spec_groups, locked_spec)
122
- return spec_groups unless locked_spec
123
- @gem_name = locked_spec.name
124
- @locked_version = locked_spec.version
119
+ @locked_version = locked_spec&.version
120
+ @gem_name = locked_spec&.name
125
121
 
126
122
  result = spec_groups.sort do |a, b|
127
123
  @a_ver = a.version
128
124
  @b_ver = b.version
129
125
 
130
- unless @prerelease_specified[@gem_name]
126
+ unless @gem_name && @prerelease_specified[@gem_name]
131
127
  a_pre = @a_ver.prerelease?
132
128
  b_pre = @b_ver.prerelease?
133
129
 
@@ -151,7 +147,7 @@ module Bundler
151
147
  end
152
148
 
153
149
  def either_version_older_than_locked
154
- @a_ver < @locked_version || @b_ver < @locked_version
150
+ @locked_version && (@a_ver < @locked_version || @b_ver < @locked_version)
155
151
  end
156
152
 
157
153
  def segments_do_not_match(level)
@@ -160,7 +156,7 @@ module Bundler
160
156
  end
161
157
 
162
158
  def unlocking_gem?
163
- unlock_gems.empty? || unlock_gems.include?(@gem_name)
159
+ unlock_gems.empty? || (@gem_name && unlock_gems.include?(@gem_name))
164
160
  end
165
161
 
166
162
  # Specific version moves can't always reliably be done during sorting
@@ -168,7 +164,7 @@ module Bundler
168
164
  def post_sort(result)
169
165
  # default :major behavior in Bundler does not do this
170
166
  return result if major?
171
- if unlocking_gem?
167
+ if unlocking_gem? || @locked_version.nil?
172
168
  result
173
169
  else
174
170
  move_version_to_end(result, @locked_version)
@@ -179,12 +175,5 @@ module Bundler
179
175
  move, keep = result.partition {|s| s.version.to_s == version.to_s }
180
176
  keep.concat(move)
181
177
  end
182
-
183
- def debug_format_result(dep, spec_groups)
184
- a = [dep.to_s,
185
- spec_groups.map {|sg| [sg.version, sg.dependencies_for_activated_platforms.map {|dp| [dp.name, dp.requirement.to_s] }] }]
186
- last_map = a.last.map {|sg_data| [sg_data.first.version, sg_data.last.map {|aa| aa.join(" ") }] }
187
- [a.first, last_map, level, strict ? :strict : :not_strict]
188
- end
189
178
  end
190
179
  end