bundler 2.2.11 → 2.3.26

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -32,12 +32,12 @@ module Bundler
32
32
  @engine = engine && engine.to_s || "ruby"
33
33
  @engine_versions = (engine_version && Array(engine_version)) || @versions
34
34
  @engine_gem_version = Gem::Requirement.create(@engine_versions.first).requirements.first.last
35
- @patchlevel = patchlevel
35
+ @patchlevel = patchlevel || (@gem_version.prerelease? ? "-1" : nil)
36
36
  end
37
37
 
38
38
  def to_s(versions = self.versions)
39
39
  output = String.new("ruby #{versions_string(versions)}")
40
- output << "p#{patchlevel}" if patchlevel
40
+ output << "p#{patchlevel}" if patchlevel && patchlevel != "-1"
41
41
  output << " (#{engine} #{versions_string(engine_versions)})" unless engine == "ruby"
42
42
 
43
43
  output
@@ -46,7 +46,7 @@ module Bundler
46
46
  # @private
47
47
  PATTERN = /
48
48
  ruby\s
49
- ([\d.]+) # ruby version
49
+ (\d+\.\d+\.\d+(?:\.\S+)?) # ruby version
50
50
  (?:p(-?\d+))? # optional patchlevel
51
51
  (?:\s\((\S+)\s(.+)\))? # optional engine info
52
52
  /xo.freeze
@@ -103,26 +103,13 @@ 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
107
- ruby_engine_version = RUBY_ENGINE_VERSION.dup
106
+ ruby_version = Gem.ruby_version.to_s
107
+ ruby_engine_version = RUBY_ENGINE == "ruby" ? ruby_version : RUBY_ENGINE_VERSION.dup
108
108
  patchlevel = RUBY_PATCHLEVEL.to_s
109
109
 
110
110
  @ruby_version ||= RubyVersion.new(ruby_version, patchlevel, ruby_engine, ruby_engine_version)
111
111
  end
112
112
 
113
- def to_gem_version_with_patchlevel
114
- @gem_version_with_patch ||= begin
115
- Gem::Version.create("#{@gem_version}.#{@patchlevel}")
116
- rescue ArgumentError
117
- @gem_version
118
- end
119
- end
120
-
121
- def exact?
122
- return @exact if defined?(@exact)
123
- @exact = versions.all? {|v| Gem::Requirement.create(v).exact? }
124
- end
125
-
126
113
  private
127
114
 
128
115
  def matches?(requirements, version)
@@ -4,14 +4,34 @@ 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.
7
+ # We can't let `Gem::Source` be autoloaded in the `Gem::Specification#source`
8
+ # redefinition below, so we need to load it upfront. The reason is that if
9
+ # Bundler monkeypatches are loaded before RubyGems activates an executable (for
10
+ # example, through `ruby -rbundler -S irb`), gem activation might end up calling
11
+ # the redefined `Gem::Specification#source` and triggering the `Gem::Source`
12
+ # autoload. That would result in requiring "rubygems/source" inside another
13
+ # require, which would trigger a monitor error and cause the `autoload` to
14
+ # eventually fail. A better solution is probably to completely avoid autoloading
15
+ # `Gem::Source` from the redefined `Gem::Specification#source`.
9
16
  require "rubygems/source"
10
17
 
18
+ require_relative "match_metadata"
11
19
  require_relative "match_platform"
12
20
 
21
+ # Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
22
+ # versions and ignore patchlevels
23
+ # (https://github.com/rubygems/rubygems/pull/5472,
24
+ # https://github.com/rubygems/rubygems/pull/5486). May be removed once RubyGems
25
+ # 3.3.12 support is dropped.
26
+ unless Gem.ruby_version.to_s == RUBY_VERSION || RUBY_PATCHLEVEL == -1
27
+ Gem.instance_variable_set(:@ruby_version, Gem::Version.new(RUBY_VERSION))
28
+ end
29
+
13
30
  module Gem
14
31
  class Specification
32
+ include ::Bundler::MatchMetadata
33
+ include ::Bundler::MatchPlatform
34
+
15
35
  attr_accessor :remote, :location, :relative_loaded_from
16
36
 
17
37
  remove_method :source
@@ -24,12 +44,8 @@ module Gem
24
44
  alias_method :rg_loaded_from, :loaded_from
25
45
 
26
46
  def full_gem_path
27
- # this cannot check source.is_a?(Bundler::Plugin::API::Source)
28
- # because that _could_ trip the autoload, and if there are unresolved
29
- # gems at that time, this method could be called inside another require,
30
- # thus raising with that constant being undefined. Better to check a method
31
- if source.respond_to?(:path) || (source.respond_to?(:bundler_plugin_api_source?) && source.bundler_plugin_api_source?)
32
- Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap{|x| x.untaint if RUBY_VERSION < "2.7" }
47
+ if source.respond_to?(:root)
48
+ Pathname.new(loaded_from).dirname.expand_path(source.root).to_s.tap {|x| x.untaint if RUBY_VERSION < "2.7" }
33
49
  else
34
50
  rg_full_gem_path
35
51
  end
@@ -62,6 +78,23 @@ module Gem
62
78
  full_gem_path
63
79
  end
64
80
 
81
+ unless const_defined?(:LATEST_RUBY_WITHOUT_PATCH_VERSIONS)
82
+ LATEST_RUBY_WITHOUT_PATCH_VERSIONS = Gem::Version.new("2.1")
83
+
84
+ alias_method :rg_required_ruby_version=, :required_ruby_version=
85
+ def required_ruby_version=(req)
86
+ self.rg_required_ruby_version = req
87
+
88
+ @required_ruby_version.requirements.map! do |op, v|
89
+ if v >= LATEST_RUBY_WITHOUT_PATCH_VERSIONS && v.release.segments.size == 4
90
+ [op == "~>" ? "=" : op, Gem::Version.new(v.segments.tap {|s| s.delete_at(3) }.join("."))]
91
+ else
92
+ [op, v]
93
+ end
94
+ end
95
+ end
96
+ end
97
+
65
98
  def groups
66
99
  @groups ||= []
67
100
  end
@@ -81,10 +114,25 @@ module Gem
81
114
  gemfile
82
115
  end
83
116
 
117
+ # Backfill missing YAML require when not defined. Fixed since 3.1.0.pre1.
118
+ module YamlBackfiller
119
+ def to_yaml(opts = {})
120
+ Gem.load_yaml unless defined?(::YAML)
121
+
122
+ super(opts)
123
+ end
124
+ end
125
+
126
+ prepend YamlBackfiller
127
+
84
128
  def nondevelopment_dependencies
85
129
  dependencies - development_dependencies
86
130
  end
87
131
 
132
+ def deleted_gem?
133
+ !default_gem? && !File.directory?(full_gem_path)
134
+ end
135
+
88
136
  private
89
137
 
90
138
  def dependencies_to_gemfile(dependencies, group = nil)
@@ -105,10 +153,14 @@ module Gem
105
153
  end
106
154
 
107
155
  class Dependency
108
- attr_accessor :source, :groups, :all_sources
156
+ attr_accessor :source, :groups
109
157
 
110
158
  alias_method :eql?, :==
111
159
 
160
+ def force_ruby_platform
161
+ false
162
+ end
163
+
112
164
  def encode_with(coder)
113
165
  to_yaml_properties.each do |ivar|
114
166
  coder[ivar.to_s.sub(/^@/, "")] = instance_variable_get(ivar)
@@ -116,7 +168,7 @@ module Gem
116
168
  end
117
169
 
118
170
  def to_yaml_properties
119
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
171
+ instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
120
172
  end
121
173
 
122
174
  def to_lock
@@ -134,6 +186,8 @@ module Gem
134
186
  class Requirement
135
187
  module OrderIndependentComparison
136
188
  def ==(other)
189
+ return unless Gem::Requirement === other
190
+
137
191
  if _requirements_sorted? && other._requirements_sorted?
138
192
  super
139
193
  else
@@ -174,20 +228,106 @@ module Gem
174
228
  end
175
229
  end
176
230
 
231
+ require "rubygems/platform"
232
+
177
233
  class Platform
178
- JAVA = Gem::Platform.new("java") unless defined?(JAVA)
179
- MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
180
- MSWIN64 = Gem::Platform.new("mswin64") unless defined?(MSWIN64)
181
- MINGW = Gem::Platform.new("x86-mingw32") unless defined?(MINGW)
182
- X64_MINGW = Gem::Platform.new("x64-mingw32") unless defined?(X64_MINGW)
234
+ JAVA = Gem::Platform.new("java")
235
+ MSWIN = Gem::Platform.new("mswin32")
236
+ MSWIN64 = Gem::Platform.new("mswin64")
237
+ MINGW = Gem::Platform.new("x86-mingw32")
238
+ X64_MINGW = [Gem::Platform.new("x64-mingw32"),
239
+ Gem::Platform.new("x64-mingw-ucrt")].freeze
240
+ WINDOWS = [MSWIN, MSWIN64, MINGW, X64_MINGW].flatten.freeze
241
+ X64_LINUX = Gem::Platform.new("x86_64-linux")
242
+ X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl")
243
+
244
+ if X64_LINUX === X64_LINUX_MUSL
245
+ remove_method :===
246
+
247
+ def ===(other)
248
+ return nil unless Gem::Platform === other
249
+
250
+ # universal-mingw32 matches x64-mingw-ucrt
251
+ return true if (@cpu == "universal" || other.cpu == "universal") &&
252
+ @os.start_with?("mingw") && other.os.start_with?("mingw")
253
+
254
+ # cpu
255
+ ([nil,"universal"].include?(@cpu) || [nil, "universal"].include?(other.cpu) || @cpu == other.cpu ||
256
+ (@cpu == "arm" && other.cpu.start_with?("arm"))) &&
257
+
258
+ # os
259
+ @os == other.os &&
260
+
261
+ # version
262
+ (
263
+ (@os != "linux" && (@version.nil? || other.version.nil?)) ||
264
+ (@os == "linux" && (normalized_linux_version_ext == other.normalized_linux_version_ext || ["musl#{@version}", "musleabi#{@version}", "musleabihf#{@version}"].include?(other.version))) ||
265
+ @version == other.version
266
+ )
267
+ end
268
+
269
+ # This is a copy of RubyGems 3.3.23 or higher `normalized_linux_method`.
270
+ # Once only 3.3.23 is supported, we can use the method in RubyGems.
271
+ def normalized_linux_version_ext
272
+ return nil unless @version
183
273
 
184
- undef_method :hash if method_defined? :hash
185
- def hash
186
- @cpu.hash ^ @os.hash ^ @version.hash
274
+ without_gnu_nor_abi_modifiers = @version.sub(/\Agnu/, "").sub(/eabi(hf)?\Z/, "")
275
+ return nil if without_gnu_nor_abi_modifiers.empty?
276
+
277
+ without_gnu_nor_abi_modifiers
278
+ end
187
279
  end
280
+ end
188
281
 
189
- undef_method :eql? if method_defined? :eql?
190
- alias_method :eql?, :==
282
+ Platform.singleton_class.module_eval do
283
+ unless Platform.singleton_methods.include?(:match_spec?)
284
+ def match_spec?(spec)
285
+ match_gem?(spec.platform, spec.name)
286
+ end
287
+
288
+ def match_gem?(platform, gem_name)
289
+ match_platforms?(platform, Gem.platforms)
290
+ end
291
+ end
292
+
293
+ match_platforms_defined = Gem::Platform.respond_to?(:match_platforms?, true)
294
+
295
+ if !match_platforms_defined || Gem::Platform.send(:match_platforms?, Gem::Platform::X64_LINUX_MUSL, [Gem::Platform::X64_LINUX])
296
+
297
+ private
298
+
299
+ remove_method :match_platforms? if match_platforms_defined
300
+
301
+ def match_platforms?(platform, platforms)
302
+ platforms.any? do |local_platform|
303
+ platform.nil? ||
304
+ local_platform == platform ||
305
+ (local_platform != Gem::Platform::RUBY && platform =~ local_platform)
306
+ end
307
+ end
308
+ end
309
+ end
310
+
311
+ # On universal Rubies, resolve the "universal" arch to the real CPU arch, without changing the extension directory.
312
+ class Specification
313
+ if /^universal\.(?<arch>.*?)-/ =~ (CROSS_COMPILING || RUBY_PLATFORM)
314
+ local_platform = Platform.local
315
+ if local_platform.cpu == "universal"
316
+ ORIGINAL_LOCAL_PLATFORM = local_platform.to_s.freeze
317
+
318
+ local_platform.cpu = if arch == "arm64e" # arm64e is only permitted for Apple system binaries
319
+ "arm64"
320
+ else
321
+ arch
322
+ end
323
+
324
+ def extensions_dir
325
+ Gem.default_ext_dir_for(base_dir) ||
326
+ File.join(base_dir, "extensions", ORIGINAL_LOCAL_PLATFORM,
327
+ Gem.extension_api_version)
328
+ end
329
+ end
330
+ end
191
331
  end
192
332
 
193
333
  require "rubygems/util"
@@ -206,9 +346,3 @@ module Gem
206
346
  end
207
347
  end
208
348
  end
209
-
210
- module Gem
211
- class Specification
212
- include ::Bundler::MatchPlatform
213
- end
214
- end
@@ -8,34 +8,111 @@ module Bundler
8
8
  # Bundler needs to install gems regardless of binstub overwriting
9
9
  end
10
10
 
11
+ def install
12
+ pre_install_checks
13
+
14
+ run_pre_install_hooks
15
+
16
+ spec.loaded_from = spec_file
17
+
18
+ # Completely remove any previous gem files
19
+ strict_rm_rf gem_dir
20
+ strict_rm_rf spec.extension_dir
21
+
22
+ SharedHelpers.filesystem_access(gem_dir, :create) do
23
+ FileUtils.mkdir_p gem_dir, :mode => 0o755
24
+ end
25
+
26
+ extract_files
27
+
28
+ build_extensions if spec.extensions.any?
29
+ write_build_info_file
30
+ run_post_build_hooks
31
+
32
+ generate_bin
33
+ generate_plugins
34
+
35
+ write_spec
36
+
37
+ SharedHelpers.filesystem_access("#{gem_home}/cache", :write) do
38
+ write_cache_file
39
+ end
40
+
41
+ say spec.post_install_message unless spec.post_install_message.nil?
42
+
43
+ run_post_install_hooks
44
+
45
+ spec
46
+ end
47
+
48
+ def generate_plugins
49
+ return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
50
+
51
+ latest = Gem::Specification.stubs_for(spec.name).first
52
+ return if latest && latest.version > spec.version
53
+
54
+ ensure_writable_dir @plugins_dir
55
+
56
+ if spec.plugins.empty?
57
+ remove_plugins_for(spec, @plugins_dir)
58
+ else
59
+ regenerate_plugins_for(spec, @plugins_dir)
60
+ end
61
+ end
62
+
11
63
  def pre_install_checks
12
64
  super && validate_bundler_checksum(options[:bundler_expected_checksum])
13
65
  end
14
66
 
15
67
  def build_extensions
16
68
  extension_cache_path = options[:bundler_extension_cache_path]
17
- return super unless extension_cache_path && extension_dir = spec.extension_dir
69
+ extension_dir = spec.extension_dir
70
+ unless extension_cache_path && extension_dir
71
+ prepare_extension_build(extension_dir)
72
+ return super
73
+ end
18
74
 
19
- extension_dir = Pathname.new(extension_dir)
20
75
  build_complete = SharedHelpers.filesystem_access(extension_cache_path.join("gem.build_complete"), :read, &:file?)
21
76
  if build_complete && !options[:force]
22
- SharedHelpers.filesystem_access(extension_dir.parent, &:mkpath)
77
+ SharedHelpers.filesystem_access(File.dirname(extension_dir)) do |p|
78
+ FileUtils.mkpath p
79
+ end
23
80
  SharedHelpers.filesystem_access(extension_cache_path) do
24
- FileUtils.cp_r extension_cache_path, spec.extension_dir
81
+ FileUtils.cp_r extension_cache_path, extension_dir
25
82
  end
26
83
  else
84
+ prepare_extension_build(extension_dir)
27
85
  super
28
- if extension_dir.directory? # not made for gems without extensions
29
- SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
30
- SharedHelpers.filesystem_access(extension_cache_path) do
31
- FileUtils.cp_r extension_dir, extension_cache_path
32
- end
86
+ SharedHelpers.filesystem_access(extension_cache_path.parent, &:mkpath)
87
+ SharedHelpers.filesystem_access(extension_cache_path) do
88
+ FileUtils.cp_r extension_dir, extension_cache_path
33
89
  end
34
90
  end
35
91
  end
36
92
 
93
+ def spec
94
+ if Bundler.rubygems.provides?("< 3.3.12") # RubyGems implementation rescues and re-raises errors before 3.3.12 and we don't want that
95
+ @package.spec
96
+ else
97
+ super
98
+ end
99
+ end
100
+
37
101
  private
38
102
 
103
+ def prepare_extension_build(extension_dir)
104
+ SharedHelpers.filesystem_access(extension_dir, :create) do
105
+ FileUtils.mkdir_p extension_dir
106
+ end
107
+ require "shellwords" unless Bundler.rubygems.provides?(">= 3.2.25")
108
+ end
109
+
110
+ def strict_rm_rf(dir)
111
+ Bundler.rm_rf dir
112
+ rescue Errno::ENOTEMPTY => e
113
+ raise DirectoryRemovalError.new(e.cause, "Could not delete previous installation of `#{dir}`")
114
+ end
115
+
39
116
  def validate_bundler_checksum(checksum)
40
117
  return true if Bundler.settings[:disable_checksum_validation]
41
118
  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,32 +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
- def spec_from_gem(path, policy = nil)
250
- require "rubygems/security"
251
- require_relative "psyched_yaml"
252
- gem_from_path(path, security_policies[policy]).spec
253
- rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException
254
- if e.is_a?(Gem::Security::Exception) ||
255
- e.message =~ /unknown trust policy|unsigned gem/i ||
256
- e.message =~ /couldn't verify (meta)?data signature/i
257
- raise SecurityError,
258
- "The gem #{File.basename(path, ".gem")} can't be installed because " \
259
- "the security policy didn't allow it, with the message: #{e.message}"
260
- else
261
- raise e
262
- end
206
+ def spec_from_gem(path)
207
+ require "rubygems/package"
208
+ Gem::Package.new(path).spec
263
209
  end
264
210
 
265
211
  def build_gem(gem_dir, spec)
@@ -502,14 +448,15 @@ module Bundler
502
448
  end
503
449
 
504
450
  def fetch_specs(remote, name)
451
+ require "rubygems/remote_fetcher"
505
452
  path = remote.uri.to_s + "#{name}.#{Gem.marshal_version}.gz"
506
453
  fetcher = gem_remote_fetcher
507
454
  fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri
508
455
  string = fetcher.fetch_path(path)
509
456
  Bundler.load_marshal(string)
510
- rescue Gem::RemoteFetcher::FetchError => e
457
+ rescue Gem::RemoteFetcher::FetchError
511
458
  # it's okay for prerelease to fail
512
- raise e unless name == "prerelease_specs"
459
+ raise unless name == "prerelease_specs"
513
460
  end
514
461
 
515
462
  def fetch_all_remote_specs(remote)
@@ -519,27 +466,41 @@ module Bundler
519
466
  specs.concat(pres)
520
467
  end
521
468
 
522
- def download_gem(spec, uri, path)
469
+ def download_gem(spec, uri, cache_dir)
470
+ require "rubygems/remote_fetcher"
523
471
  uri = Bundler.settings.mirror_for(uri)
524
472
  fetcher = gem_remote_fetcher
525
473
  fetcher.headers = { "X-Gemfile-Source" => spec.remote.original_uri.to_s } if spec.remote.original_uri
526
474
  Bundler::Retry.new("download gem from #{uri}").attempts do
527
- fetcher.download(spec, uri, path)
475
+ gem_file_name = spec.file_name
476
+ local_gem_path = File.join cache_dir, gem_file_name
477
+ return if File.exist? local_gem_path
478
+
479
+ begin
480
+ remote_gem_path = uri + "gems/#{gem_file_name}"
481
+ remote_gem_path = remote_gem_path.to_s if provides?("< 3.2.0.rc.1")
482
+
483
+ SharedHelpers.filesystem_access(local_gem_path) do
484
+ fetcher.cache_update_path remote_gem_path, local_gem_path
485
+ end
486
+ rescue Gem::RemoteFetcher::FetchError
487
+ raise if spec.original_platform == spec.platform
488
+
489
+ original_gem_file_name = "#{spec.original_name}.gem"
490
+ raise if gem_file_name == original_gem_file_name
491
+
492
+ gem_file_name = original_gem_file_name
493
+ retry
494
+ end
528
495
  end
496
+ rescue Gem::RemoteFetcher::FetchError => e
497
+ raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
529
498
  end
530
499
 
531
500
  def gem_remote_fetcher
532
- require "resolv"
533
- proxy = configuration[:http_proxy]
534
- dns = Resolv::DNS.new
535
- Gem::RemoteFetcher.new(proxy, dns)
536
- end
537
-
538
- def gem_from_path(path, policy = nil)
539
- require "rubygems/package"
540
- p = Gem::Package.new(path)
541
- p.security_policy = policy if policy
542
- p
501
+ require "rubygems/remote_fetcher"
502
+ proxy = Gem.configuration[:http_proxy]
503
+ Gem::RemoteFetcher.new(proxy)
543
504
  end
544
505
 
545
506
  def build(spec, skip_validation = false)
@@ -551,10 +512,6 @@ module Bundler
551
512
  Gem::REPOSITORY_SUBDIRECTORIES
552
513
  end
553
514
 
554
- def install_with_build_args(args)
555
- yield
556
- end
557
-
558
515
  def path_separator
559
516
  Gem.path_separator
560
517
  end
@@ -584,6 +541,10 @@ module Bundler
584
541
  end
585
542
  end
586
543
 
544
+ def find_bundler(version)
545
+ find_name("bundler").find {|s| s.version.to_s == version }
546
+ end
547
+
587
548
  def find_name(name)
588
549
  Gem::Specification.stubs_for(name).map(&:to_spec)
589
550
  end
@@ -597,14 +558,6 @@ module Bundler
597
558
  Gem::Specification.send(:default_stubs, "*.gemspec")
598
559
  end
599
560
  end
600
-
601
- def use_gemdeps(gemfile)
602
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
603
- require_relative "gemdeps"
604
- runtime = Bundler.setup
605
- activated_spec_names = runtime.requested_specs.map(&:to_spec).sort_by(&:name)
606
- [Gemdeps.new(runtime), activated_spec_names]
607
- end
608
561
  end
609
562
 
610
563
  def self.rubygems