rubygems-update 3.6.8 → 3.7.0

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 (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +874 -787
  3. data/CONTRIBUTING.md +9 -0
  4. data/Manifest.txt +6 -22
  5. data/README.md +1 -1
  6. data/SECURITY.md +7 -0
  7. data/bundler/CHANGELOG.md +1103 -1030
  8. data/bundler/README.md +7 -7
  9. data/bundler/bundler.gemspec +2 -2
  10. data/bundler/lib/bundler/build_metadata.rb +10 -11
  11. data/bundler/lib/bundler/cli/common.rb +1 -1
  12. data/bundler/lib/bundler/cli/config.rb +2 -2
  13. data/bundler/lib/bundler/cli/doctor/diagnose.rb +167 -0
  14. data/bundler/lib/bundler/cli/doctor/ssl.rb +249 -0
  15. data/bundler/lib/bundler/cli/doctor.rb +27 -155
  16. data/bundler/lib/bundler/cli/gem.rb +62 -30
  17. data/bundler/lib/bundler/cli/install.rb +4 -4
  18. data/bundler/lib/bundler/cli/issue.rb +2 -2
  19. data/bundler/lib/bundler/cli/outdated.rb +1 -1
  20. data/bundler/lib/bundler/cli/update.rb +2 -2
  21. data/bundler/lib/bundler/cli.rb +12 -25
  22. data/bundler/lib/bundler/compact_index_client.rb +1 -5
  23. data/bundler/lib/bundler/current_ruby.rb +27 -3
  24. data/bundler/lib/bundler/definition.rb +55 -58
  25. data/bundler/lib/bundler/dependency.rb +1 -1
  26. data/bundler/lib/bundler/dsl.rb +33 -23
  27. data/bundler/lib/bundler/feature_flag.rb +15 -12
  28. data/bundler/lib/bundler/fetcher/dependency.rb +2 -1
  29. data/bundler/lib/bundler/fetcher/downloader.rb +33 -7
  30. data/bundler/lib/bundler/fetcher.rb +49 -19
  31. data/bundler/lib/bundler/friendly_errors.rb +2 -1
  32. data/bundler/lib/bundler/index.rb +7 -2
  33. data/bundler/lib/bundler/installer.rb +5 -4
  34. data/bundler/lib/bundler/lazy_specification.rb +29 -18
  35. data/bundler/lib/bundler/lockfile_parser.rb +21 -5
  36. data/bundler/lib/bundler/man/bundle-add.1 +1 -1
  37. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  38. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  39. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  40. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  41. data/bundler/lib/bundler/man/bundle-config.1 +172 -126
  42. data/bundler/lib/bundler/man/bundle-config.1.ronn +91 -91
  43. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  44. data/bundler/lib/bundler/man/bundle-doctor.1 +43 -4
  45. data/bundler/lib/bundler/man/bundle-doctor.1.ronn +48 -4
  46. data/bundler/lib/bundler/man/bundle-env.1 +1 -1
  47. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  48. data/bundler/lib/bundler/man/bundle-fund.1 +1 -1
  49. data/bundler/lib/bundler/man/bundle-gem.1 +67 -44
  50. data/bundler/lib/bundler/man/bundle-gem.1.ronn +8 -4
  51. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  52. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  53. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  54. data/bundler/lib/bundler/man/bundle-inject.1 +2 -2
  55. data/bundler/lib/bundler/man/bundle-inject.1.ronn +1 -1
  56. data/bundler/lib/bundler/man/bundle-install.1 +1 -1
  57. data/bundler/lib/bundler/man/bundle-issue.1 +1 -1
  58. data/bundler/lib/bundler/man/bundle-licenses.1 +1 -1
  59. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  60. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  61. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  62. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  63. data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
  64. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  65. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  66. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  67. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  68. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  69. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  70. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  71. data/bundler/lib/bundler/man/bundle.1 +1 -1
  72. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  73. data/bundler/lib/bundler/match_platform.rb +31 -12
  74. data/bundler/lib/bundler/materialization.rb +2 -2
  75. data/bundler/lib/bundler/resolver/package.rb +1 -1
  76. data/bundler/lib/bundler/resolver.rb +11 -9
  77. data/bundler/lib/bundler/rubygems_ext.rb +116 -120
  78. data/bundler/lib/bundler/rubygems_integration.rb +11 -6
  79. data/bundler/lib/bundler/runtime.rb +1 -1
  80. data/bundler/lib/bundler/self_manager.rb +32 -42
  81. data/bundler/lib/bundler/settings/validator.rb +0 -23
  82. data/bundler/lib/bundler/settings.rb +4 -6
  83. data/bundler/lib/bundler/shared_helpers.rb +6 -4
  84. data/bundler/lib/bundler/source/git/git_proxy.rb +3 -3
  85. data/bundler/lib/bundler/source/path.rb +7 -0
  86. data/bundler/lib/bundler/source_list.rb +1 -5
  87. data/bundler/lib/bundler/source_map.rb +1 -1
  88. data/bundler/lib/bundler/spec_set.rb +28 -6
  89. data/bundler/lib/bundler/templates/Executable +0 -11
  90. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +2 -0
  91. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -5
  92. data/bundler/lib/bundler/ui/shell.rb +2 -2
  93. data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
  94. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +2 -1
  95. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +81 -42
  96. data/bundler/lib/bundler/version.rb +10 -2
  97. data/bundler/lib/bundler/worker.rb +1 -1
  98. data/bundler/lib/bundler.rb +14 -12
  99. data/doc/bundler/UPGRADING.md +137 -127
  100. data/doc/rubygems/CONTRIBUTING.md +1 -1
  101. data/lib/rubygems/basic_specification.rb +7 -0
  102. data/lib/rubygems/commands/pristine_command.rb +9 -12
  103. data/lib/rubygems/commands/push_command.rb +2 -1
  104. data/lib/rubygems/commands/setup_command.rb +2 -2
  105. data/lib/rubygems/core_ext/kernel_require.rb +5 -2
  106. data/lib/rubygems/ext/builder.rb +15 -4
  107. data/lib/rubygems/ext/cargo_builder.rb +7 -5
  108. data/lib/rubygems/ext/rake_builder.rb +1 -3
  109. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +10 -3
  110. data/lib/rubygems/gemcutter_utilities.rb +5 -2
  111. data/lib/rubygems/installer.rb +45 -50
  112. data/lib/rubygems/package/tar_writer.rb +5 -4
  113. data/lib/rubygems/platform.rb +142 -39
  114. data/lib/rubygems/remote_fetcher.rb +3 -3
  115. data/lib/rubygems/request_set.rb +3 -6
  116. data/lib/rubygems/resolver/best_set.rb +1 -1
  117. data/lib/rubygems/resolver/source_set.rb +1 -1
  118. data/lib/rubygems/resolver.rb +1 -1
  119. data/lib/rubygems/s3_uri_signer.rb +5 -3
  120. data/lib/rubygems/source.rb +28 -22
  121. data/lib/rubygems/specification.rb +2 -2
  122. data/lib/rubygems/uri_formatter.rb +2 -1
  123. data/lib/rubygems/util/licenses.rb +21 -0
  124. data/lib/rubygems/vendor/net-http/lib/net/http.rb +14 -19
  125. data/lib/rubygems/vendor/resolv/lib/resolv.rb +50 -22
  126. data/lib/rubygems.rb +65 -7
  127. data/rubygems-update.gemspec +2 -2
  128. data/setup.rb +1 -1
  129. metadata +9 -25
  130. data/bundler/lib/bundler/gem_helpers.rb +0 -144
  131. data/bundler/lib/bundler/templates/Executable.bundler +0 -109
  132. data/bundler/lib/bundler/vendor/fileutils/.document +0 -1
  133. data/bundler/lib/bundler/vendor/net-http-persistent/.document +0 -1
  134. data/bundler/lib/bundler/vendor/pub_grub/.document +0 -1
  135. data/bundler/lib/bundler/vendor/securerandom/.document +0 -1
  136. data/bundler/lib/bundler/vendor/thor/.document +0 -1
  137. data/bundler/lib/bundler/vendor/tsort/.document +0 -1
  138. data/bundler/lib/bundler/vendor/uri/.document +0 -1
  139. data/lib/rubygems/shellwords.rb +0 -3
  140. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem +0 -21
  141. data/lib/rubygems/vendor/molinillo/.document +0 -1
  142. data/lib/rubygems/vendor/net-http/.document +0 -1
  143. data/lib/rubygems/vendor/net-protocol/.document +0 -1
  144. data/lib/rubygems/vendor/optparse/.document +0 -1
  145. data/lib/rubygems/vendor/resolv/.document +0 -1
  146. data/lib/rubygems/vendor/securerandom/.document +0 -1
  147. data/lib/rubygems/vendor/timeout/.document +0 -1
  148. data/lib/rubygems/vendor/tsort/.document +0 -1
  149. data/lib/rubygems/vendor/uri/.document +0 -1
  150. /data/lib/rubygems/ssl_certs/rubygems.org/{GlobalSignRootCA_R3.pem → GlobalSign.pem} +0 -0
  151. /data/{bundler/lib/bundler/vendor/connection_pool → lib/rubygems/vendor}/.document +0 -0
@@ -256,6 +256,13 @@ class Gem::BasicSpecification
256
256
  raise NotImplementedError
257
257
  end
258
258
 
259
+ def installable_on_platform?(target_platform) # :nodoc:
260
+ return true if [Gem::Platform::RUBY, nil, target_platform].include?(platform)
261
+ return true if Gem::Platform.new(platform) === target_platform
262
+
263
+ false
264
+ end
265
+
259
266
  def raw_require_paths # :nodoc:
260
267
  raise NotImplementedError
261
268
  end
@@ -137,11 +137,14 @@ extensions will be restored.
137
137
  specs.group_by(&:full_name_with_location).values.each do |grouped_specs|
138
138
  spec = grouped_specs.find {|s| !s.default_gem? } || grouped_specs.first
139
139
 
140
- unless only_executables_or_plugins?
140
+ only_executables = options[:only_executables]
141
+ only_plugins = options[:only_plugins]
142
+
143
+ unless only_executables || only_plugins
141
144
  # Default gemspecs include changes provided by ruby-core installer that
142
145
  # can't currently be pristined (inclusion of compiled extension targets in
143
146
  # the file list). So stick to resetting executables if it's a default gem.
144
- options[:only_executables] = true if spec.default_gem?
147
+ only_executables = true if spec.default_gem?
145
148
  end
146
149
 
147
150
  if options.key? :skip
@@ -151,14 +154,14 @@ extensions will be restored.
151
154
  end
152
155
  end
153
156
 
154
- unless spec.extensions.empty? || options[:extensions] || only_executables_or_plugins?
157
+ unless spec.extensions.empty? || options[:extensions] || only_executables || only_plugins
155
158
  say "Skipped #{spec.full_name_with_location}, it needs to compile an extension"
156
159
  next
157
160
  end
158
161
 
159
162
  gem = spec.cache_file
160
163
 
161
- unless File.exist?(gem) || only_executables_or_plugins?
164
+ unless File.exist?(gem) || only_executables || only_plugins
162
165
  require_relative "../remote_fetcher"
163
166
 
164
167
  say "Cached gem for #{spec.full_name_with_location} not found, attempting to fetch..."
@@ -194,10 +197,10 @@ extensions will be restored.
194
197
  bin_dir: bin_dir,
195
198
  }
196
199
 
197
- if options[:only_executables]
200
+ if only_executables
198
201
  installer = Gem::Installer.for_spec(spec, installer_options)
199
202
  installer.generate_bin
200
- elsif options[:only_plugins]
203
+ elsif only_plugins
201
204
  installer = Gem::Installer.for_spec(spec, installer_options)
202
205
  installer.generate_plugins
203
206
  else
@@ -208,10 +211,4 @@ extensions will be restored.
208
211
  say "Restored #{spec.full_name_with_location}"
209
212
  end
210
213
  end
211
-
212
- private
213
-
214
- def only_executables_or_plugins?
215
- options[:only_executables] || options[:only_plugins]
216
- end
217
214
  end
@@ -92,7 +92,8 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
92
92
  private
93
93
 
94
94
  def send_push_request(name, args)
95
- rubygems_api_request(*args, scope: get_push_scope) do |request|
95
+ scope = get_push_scope
96
+ rubygems_api_request(*args, scope: scope) do |request|
96
97
  body = Gem.read_binary name
97
98
  if options[:attestations].any?
98
99
  request.set_form([
@@ -7,8 +7,8 @@ require_relative "../command"
7
7
  # RubyGems checkout or tarball.
8
8
 
9
9
  class Gem::Commands::SetupCommand < Gem::Command
10
- HISTORY_HEADER = %r{^#\s*[\d.a-zA-Z]+\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
11
- VERSION_MATCHER = %r{^#\s*([\d.a-zA-Z]+)\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
10
+ HISTORY_HEADER = %r{^##\s*[\d.a-zA-Z]+\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
11
+ VERSION_MATCHER = %r{^##\s*([\d.a-zA-Z]+)\s*/\s*\d{4}-\d{2}-\d{2}\s*$}
12
12
 
13
13
  ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
14
14
 
@@ -64,8 +64,11 @@ module Kernel
64
64
  rp
65
65
  end
66
66
 
67
- Kernel.send(:gem, name, Gem::Requirement.default_prerelease) unless
68
- resolved_path
67
+ next if resolved_path
68
+
69
+ Kernel.send(:gem, name, Gem::Requirement.default_prerelease)
70
+
71
+ Gem.load_bundler_extensions(Gem.loaded_specs[name].version) if name == "bundler"
69
72
 
70
73
  next
71
74
  end
@@ -7,7 +7,6 @@
7
7
  #++
8
8
 
9
9
  require_relative "../user_interaction"
10
- require_relative "../shellwords"
11
10
 
12
11
  class Gem::Ext::Builder
13
12
  include Gem::UserInteraction
@@ -29,7 +28,7 @@ class Gem::Ext::Builder
29
28
  target_rbconfig["configure_args"] =~ /with-make-prog\=(\w+)/
30
29
  make_program_name = ENV["MAKE"] || ENV["make"] || $1
31
30
  make_program_name ||= RUBY_PLATFORM.include?("mswin") ? "nmake" : "make"
32
- make_program = Shellwords.split(make_program_name)
31
+ make_program = shellsplit(make_program_name)
33
32
 
34
33
  # The installation of the bundled gems is failed when DESTDIR is empty in mswin platform.
35
34
  destdir = /\bnmake/i !~ make_program_name || ENV["DESTDIR"] && ENV["DESTDIR"] != "" ? format("DESTDIR=%s", ENV["DESTDIR"]) : ""
@@ -58,7 +57,7 @@ class Gem::Ext::Builder
58
57
 
59
58
  def self.ruby
60
59
  # Gem.ruby is quoted if it contains whitespace
61
- cmd = Shellwords.split(Gem.ruby)
60
+ cmd = shellsplit(Gem.ruby)
62
61
 
63
62
  # This load_path is only needed when running rubygems test without a proper installation.
64
63
  # Prepending it in a normal installation will cause problem with order of $LOAD_PATH.
@@ -83,7 +82,7 @@ class Gem::Ext::Builder
83
82
  p(command)
84
83
  end
85
84
  results << "current directory: #{dir}"
86
- results << Shellwords.join(command)
85
+ results << shelljoin(command)
87
86
 
88
87
  require "open3"
89
88
  # Set $SOURCE_DATE_EPOCH for the subprocess.
@@ -127,6 +126,18 @@ class Gem::Ext::Builder
127
126
  end
128
127
  end
129
128
 
129
+ def self.shellsplit(command)
130
+ require "shellwords"
131
+
132
+ Shellwords.split(command)
133
+ end
134
+
135
+ def self.shelljoin(command)
136
+ require "shellwords"
137
+
138
+ Shellwords.join(command)
139
+ end
140
+
130
141
  ##
131
142
  # Creates a new extension builder for +spec+. If the +spec+ does not yet
132
143
  # have build arguments, saved, set +build_args+ which is an ARGV-style
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../shellwords"
4
-
5
3
  # This class is used by rubygems to build Rust extensions. It is a thin-wrapper
6
4
  # over the `cargo rustc` command which takes care of building Rust code in a way
7
5
  # that Ruby can use.
@@ -159,7 +157,11 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
159
157
  # We want to use the same linker that Ruby uses, so that the linker flags from
160
158
  # mkmf work properly.
161
159
  def linker_args
162
- cc_flag = Shellwords.split(makefile_config("CC"))
160
+ cc_flag = self.class.shellsplit(makefile_config("CC"))
161
+ # Avoid to ccache like tool from Rust build
162
+ # see https://github.com/rubygems/rubygems/pull/8521#issuecomment-2689854359
163
+ # ex. CC="ccache gcc" or CC="sccache clang --any --args"
164
+ cc_flag.shift if cc_flag.size >= 2 && !cc_flag[1].start_with?("-")
163
165
  linker = cc_flag.shift
164
166
  link_args = cc_flag.flat_map {|a| ["-C", "link-arg=#{a}"] }
165
167
 
@@ -178,7 +180,7 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
178
180
 
179
181
  def libruby_args(dest_dir)
180
182
  libs = makefile_config(ruby_static? ? "LIBRUBYARG_STATIC" : "LIBRUBYARG_SHARED")
181
- raw_libs = Shellwords.split(libs)
183
+ raw_libs = self.class.shellsplit(libs)
182
184
  raw_libs.flat_map {|l| ldflag_to_link_modifier(l) }
183
185
  end
184
186
 
@@ -261,7 +263,7 @@ EOF
261
263
  end
262
264
 
263
265
  def split_flags(var)
264
- Shellwords.split(RbConfig::CONFIG.fetch(var, ""))
266
+ self.class.shellsplit(RbConfig::CONFIG.fetch(var, ""))
265
267
  end
266
268
 
267
269
  def ldflag_to_link_modifier(arg)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../shellwords"
4
-
5
3
  #--
6
4
  # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
7
5
  # All rights reserved.
@@ -22,7 +20,7 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
22
20
  rake = ENV["rake"]
23
21
 
24
22
  if rake
25
- rake = Shellwords.split(rake)
23
+ rake = shellsplit(rake)
26
24
  else
27
25
  begin
28
26
  rake = ruby << "-rrubygems" << Gem.bin_path("rake", "rake")
@@ -85,10 +85,17 @@ module Gem::GemcutterUtilities
85
85
  end
86
86
 
87
87
  def parse_otp_from_uri(uri)
88
- require "cgi"
88
+ query = uri.query
89
+ return unless query && !query.empty?
89
90
 
90
- return if uri.query.nil?
91
- CGI.parse(uri.query).dig("code", 0)
91
+ query.split("&") do |param|
92
+ key, value = param.split("=", 2)
93
+ if value && Gem::URI.decode_www_form_component(key) == "code"
94
+ return Gem::URI.decode_www_form_component(value)
95
+ end
96
+ end
97
+
98
+ nil
92
99
  end
93
100
 
94
101
  class SocketResponder
@@ -263,7 +263,10 @@ module Gem::GemcutterUtilities
263
263
  port = server.addr[1].to_s
264
264
 
265
265
  url_with_port = "#{webauthn_url}?port=#{port}"
266
- say "You have enabled multi-factor authentication. Please visit #{url_with_port} to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin command with the `--otp [your_code]` option."
266
+ say "You have enabled multi-factor authentication. Please visit the following URL to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin command with the `--otp [your_code]` option."
267
+ say ""
268
+ say url_with_port
269
+ say ""
267
270
 
268
271
  threads = [WebauthnListener.listener_thread(host, server), WebauthnPoller.poll_thread(options, host, webauthn_url, credentials)]
269
272
  otp_thread = wait_for_otp_thread(*threads)
@@ -316,7 +319,7 @@ module Gem::GemcutterUtilities
316
319
  end
317
320
 
318
321
  def get_scope_params(scope)
319
- scope_params = { index_rubygems: true }
322
+ scope_params = { index_rubygems: true, push_rubygem: true }
320
323
 
321
324
  if scope
322
325
  scope_params = { scope => true }
@@ -228,8 +228,7 @@ class Gem::Installer
228
228
  ruby_executable = true
229
229
  existing = io.read.slice(/
230
230
  ^\s*(
231
- gem \s |
232
- load \s Gem\.bin_path\( |
231
+ Gem\.activate_and_load_bin_path\( |
233
232
  load \s Gem\.activate_bin_path\(
234
233
  )
235
234
  (['"])(.*?)(\2),
@@ -749,54 +748,53 @@ class Gem::Installer
749
748
  def app_script_text(bin_file_name)
750
749
  # NOTE: that the `load` lines cannot be indented, as old RG versions match
751
750
  # against the beginning of the line
752
- <<-TEXT
753
- #{shebang bin_file_name}
754
- #
755
- # This file was generated by RubyGems.
756
- #
757
- # The application '#{spec.name}' is installed as part of a gem, and
758
- # this file is here to facilitate running it.
759
- #
760
-
761
- require 'rubygems'
762
- #{gemdeps_load(spec.name)}
763
- version = "#{Gem::Requirement.default_prerelease}"
764
-
765
- str = ARGV.first
766
- if str
767
- str = str.b[/\\A_(.*)_\\z/, 1]
768
- if str and Gem::Version.correct?(str)
769
- #{explicit_version_requirement(spec.name)}
770
- ARGV.shift
771
- end
772
- end
751
+ <<~TEXT
752
+ #{shebang bin_file_name}
753
+ #
754
+ # This file was generated by RubyGems.
755
+ #
756
+ # The application '#{spec.name}' is installed as part of a gem, and
757
+ # this file is here to facilitate running it.
758
+ #
759
+
760
+ require 'rubygems'
761
+ #{gemdeps_load(spec.name)}
762
+ version = "#{Gem::Requirement.default_prerelease}"
763
+
764
+ str = ARGV.first
765
+ if str
766
+ str = str.b[/\\A_(.*)_\\z/, 1]
767
+ if str and Gem::Version.correct?(str)
768
+ #{explicit_version_requirement(spec.name)}
769
+ ARGV.shift
770
+ end
771
+ end
773
772
 
774
- if Gem.respond_to?(:activate_bin_path)
775
- load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version)
776
- else
777
- gem #{spec.name.dump}, version
778
- load Gem.bin_path(#{spec.name.dump}, #{bin_file_name.dump}, version)
779
- end
780
- TEXT
773
+ if Gem.respond_to?(:activate_and_load_bin_path)
774
+ Gem.activate_and_load_bin_path('#{spec.name}', '#{bin_file_name}', version)
775
+ else
776
+ load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version)
777
+ end
778
+ TEXT
781
779
  end
782
780
 
783
781
  def gemdeps_load(name)
784
782
  return "" if name == "bundler"
785
783
 
786
- <<-TEXT
784
+ <<~TEXT
787
785
 
788
- Gem.use_gemdeps
789
- TEXT
786
+ Gem.use_gemdeps
787
+ TEXT
790
788
  end
791
789
 
792
790
  def explicit_version_requirement(name)
793
791
  code = "version = str"
794
792
  return code unless name == "bundler"
795
793
 
796
- code += <<-TEXT
794
+ code += <<~TEXT
797
795
 
798
- ENV['BUNDLER_VERSION'] = str
799
- TEXT
796
+ ENV['BUNDLER_VERSION'] = str
797
+ TEXT
800
798
  end
801
799
 
802
800
  ##
@@ -811,9 +809,9 @@ TEXT
811
809
 
812
810
  if File.exist?(File.join(bindir, ruby_exe))
813
811
  # stub & ruby.exe within same folder. Portable
814
- <<-TEXT
815
- @ECHO OFF
816
- @"%~dp0#{ruby_exe}" "%~dpn0" %*
812
+ <<~TEXT
813
+ @ECHO OFF
814
+ @"%~dp0#{ruby_exe}" "%~dpn0" %*
817
815
  TEXT
818
816
  elsif bindir.downcase.start_with? rb_topdir.downcase
819
817
  # stub within ruby folder, but not standard bin. Portable
@@ -821,16 +819,16 @@ TEXT
821
819
  from = Pathname.new bindir
822
820
  to = Pathname.new "#{rb_topdir}/bin"
823
821
  rel = to.relative_path_from from
824
- <<-TEXT
825
- @ECHO OFF
826
- @"%~dp0#{rel}/#{ruby_exe}" "%~dpn0" %*
822
+ <<~TEXT
823
+ @ECHO OFF
824
+ @"%~dp0#{rel}/#{ruby_exe}" "%~dpn0" %*
827
825
  TEXT
828
826
  else
829
827
  # outside ruby folder, maybe -user-install or bundler. Portable, but ruby
830
828
  # is dependent on PATH
831
- <<-TEXT
832
- @ECHO OFF
833
- @#{ruby_exe} "%~dpn0" %*
829
+ <<~TEXT
830
+ @ECHO OFF
831
+ @#{ruby_exe} "%~dpn0" %*
834
832
  TEXT
835
833
  end
836
834
  end
@@ -953,11 +951,8 @@ TEXT
953
951
  end
954
952
 
955
953
  def ensure_writable_dir(dir) # :nodoc:
956
- begin
957
- Dir.mkdir dir, *[options[:dir_mode] && 0o755].compact
958
- rescue SystemCallError
959
- raise unless File.directory? dir
960
- end
954
+ require "fileutils"
955
+ FileUtils.mkdir_p dir, mode: options[:dir_mode] && 0o755
961
956
 
962
957
  raise Gem::FilePermissionError.new(dir) unless File.writable? dir
963
958
  end
@@ -95,10 +95,11 @@ class Gem::Package::TarWriter
95
95
  end
96
96
 
97
97
  ##
98
- # Adds file +name+ with permissions +mode+, and yields an IO for writing the
99
- # file to
98
+ # Adds file +name+ with permissions +mode+ and mtime +mtime+ (sets
99
+ # Gem.source_date_epoch if not specified), and yields an IO for
100
+ # writing the file to
100
101
 
101
- def add_file(name, mode) # :yields: io
102
+ def add_file(name, mode, mtime=nil) # :yields: io
102
103
  check_closed
103
104
 
104
105
  name, prefix = split_name name
@@ -118,7 +119,7 @@ class Gem::Package::TarWriter
118
119
 
119
120
  header = Gem::Package::TarHeader.new name: name, mode: mode,
120
121
  size: size, prefix: prefix,
121
- mtime: Gem.source_date_epoch
122
+ mtime: mtime || Gem.source_date_epoch
122
123
 
123
124
  @io.write header
124
125
  @io.pos = final_pos
@@ -88,56 +88,45 @@ class Gem::Platform
88
88
  when Array then
89
89
  @cpu, @os, @version = arch
90
90
  when String then
91
- arch = arch.split "-"
91
+ cpu, os = arch.sub(/-+$/, "").split("-", 2)
92
92
 
93
- if arch.length > 2 && !arch.last.match?(/\d+(\.\d+)?$/) # reassemble x86-linux-{libc}
94
- extra = arch.pop
95
- arch.last << "-#{extra}"
96
- end
97
-
98
- cpu = arch.shift
99
-
100
- @cpu = case cpu
101
- when /i\d86/ then "x86"
102
- else cpu
103
- end
104
-
105
- if arch.length == 2 && arch.last.match?(/^\d+(\.\d+)?$/) # for command-line
106
- @os, @version = arch
107
- return
93
+ @cpu = if cpu.match?(/i\d86/)
94
+ "x86"
95
+ else
96
+ cpu
108
97
  end
109
98
 
110
- os, = arch
111
99
  if os.nil?
112
100
  @cpu = nil
113
101
  os = cpu
114
102
  end # legacy jruby
115
103
 
116
104
  @os, @version = case os
117
- when /aix(\d+)?/ then ["aix", $1]
118
- when /cygwin/ then ["cygwin", nil]
119
- when /darwin(\d+)?/ then ["darwin", $1]
120
- when /^macruby$/ then ["macruby", nil]
121
- when /freebsd(\d+)?/ then ["freebsd", $1]
122
- when /^java$/, /^jruby$/ then ["java", nil]
123
- when /^java([\d.]*)/ then ["java", $1]
124
- when /^dalvik(\d+)?$/ then ["dalvik", $1]
125
- when /^dotnet$/ then ["dotnet", nil]
126
- when /^dotnet([\d.]*)/ then ["dotnet", $1]
127
- when /linux-?(\w+)?/ then ["linux", $1]
128
- when /mingw32/ then ["mingw32", nil]
129
- when /mingw-?(\w+)?/ then ["mingw", $1]
130
- when /(mswin\d+)(\_(\d+))?/ then
105
+ when /aix-?(\d+)?/ then ["aix", $1]
106
+ when /cygwin/ then ["cygwin", nil]
107
+ when /darwin-?(\d+)?/ then ["darwin", $1]
108
+ when "macruby" then ["macruby", nil]
109
+ when /^macruby-?(\d+(?:\.\d+)*)?/ then ["macruby", $1]
110
+ when /freebsd-?(\d+)?/ then ["freebsd", $1]
111
+ when "java", "jruby" then ["java", nil]
112
+ when /^java-?(\d+(?:\.\d+)*)?/ then ["java", $1]
113
+ when /^dalvik-?(\d+)?$/ then ["dalvik", $1]
114
+ when /^dotnet$/ then ["dotnet", nil]
115
+ when /^dotnet-?(\d+(?:\.\d+)*)?/ then ["dotnet", $1]
116
+ when /linux-?(\w+)?/ then ["linux", $1]
117
+ when /mingw32/ then ["mingw32", nil]
118
+ when /mingw-?(\w+)?/ then ["mingw", $1]
119
+ when /(mswin\d+)(?:[_-](\d+))?/ then
131
120
  os = $1
132
- version = $3
133
- @cpu = "x86" if @cpu.nil? && os =~ /32$/
121
+ version = $2
122
+ @cpu = "x86" if @cpu.nil? && os.end_with?("32")
134
123
  [os, version]
135
- when /netbsdelf/ then ["netbsdelf", nil]
136
- when /openbsd(\d+\.\d+)?/ then ["openbsd", $1]
137
- when /solaris(\d+\.\d+)?/ then ["solaris", $1]
138
- when /wasi/ then ["wasi", nil]
124
+ when /netbsdelf/ then ["netbsdelf", nil]
125
+ when /openbsd-?(\d+\.\d+)?/ then ["openbsd", $1]
126
+ when /solaris-?(\d+\.\d+)?/ then ["solaris", $1]
127
+ when /wasi/ then ["wasi", nil]
139
128
  # test
140
- when /^(\w+_platform)(\d+)?/ then [$1, $2]
129
+ when /^(\w+_platform)-?(\d+)?/ then [$1, $2]
141
130
  else ["unknown", nil]
142
131
  end
143
132
  when Gem::Platform then
@@ -154,7 +143,7 @@ class Gem::Platform
154
143
  end
155
144
 
156
145
  def to_s
157
- to_a.compact.join "-"
146
+ to_a.compact.join(@cpu.nil? ? "" : "-")
158
147
  end
159
148
 
160
149
  ##
@@ -266,4 +255,118 @@ class Gem::Platform
266
255
  # This will be replaced with Gem::Platform::local.
267
256
 
268
257
  CURRENT = "current"
258
+
259
+ JAVA = Gem::Platform.new("java") # :nodoc:
260
+ MSWIN = Gem::Platform.new("mswin32") # :nodoc:
261
+ MSWIN64 = Gem::Platform.new("mswin64") # :nodoc:
262
+ MINGW = Gem::Platform.new("x86-mingw32") # :nodoc:
263
+ X64_MINGW_LEGACY = Gem::Platform.new("x64-mingw32") # :nodoc:
264
+ X64_MINGW = Gem::Platform.new("x64-mingw-ucrt") # :nodoc:
265
+ UNIVERSAL_MINGW = Gem::Platform.new("universal-mingw") # :nodoc:
266
+ WINDOWS = [MSWIN, MSWIN64, UNIVERSAL_MINGW].freeze # :nodoc:
267
+ X64_LINUX = Gem::Platform.new("x86_64-linux") # :nodoc:
268
+ X64_LINUX_MUSL = Gem::Platform.new("x86_64-linux-musl") # :nodoc:
269
+
270
+ GENERICS = [JAVA, *WINDOWS].freeze # :nodoc:
271
+ private_constant :GENERICS
272
+
273
+ GENERIC_CACHE = GENERICS.each_with_object({}) {|g, h| h[g] = g } # :nodoc:
274
+ private_constant :GENERIC_CACHE
275
+
276
+ class << self
277
+ ##
278
+ # Returns the generic platform for the given platform.
279
+
280
+ def generic(platform)
281
+ return Gem::Platform::RUBY if platform.nil? || platform == Gem::Platform::RUBY
282
+
283
+ GENERIC_CACHE[platform] ||= begin
284
+ found = GENERICS.find do |match|
285
+ platform === match
286
+ end
287
+ found || Gem::Platform::RUBY
288
+ end
289
+ end
290
+
291
+ ##
292
+ # Returns the platform specificity match for the given spec platform and user platform.
293
+
294
+ def platform_specificity_match(spec_platform, user_platform)
295
+ return -1 if spec_platform == user_platform
296
+ return 1_000_000 if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY
297
+
298
+ os_match(spec_platform, user_platform) +
299
+ cpu_match(spec_platform, user_platform) * 10 +
300
+ version_match(spec_platform, user_platform) * 100
301
+ end
302
+
303
+ ##
304
+ # Sorts and filters the best platform match for the given matching specs and platform.
305
+
306
+ def sort_and_filter_best_platform_match(matching, platform)
307
+ return matching if matching.one?
308
+
309
+ exact = matching.select {|spec| spec.platform == platform }
310
+ return exact if exact.any?
311
+
312
+ sorted_matching = sort_best_platform_match(matching, platform)
313
+ exemplary_spec = sorted_matching.first
314
+
315
+ sorted_matching.take_while {|spec| same_specificity?(platform, spec, exemplary_spec) && same_deps?(spec, exemplary_spec) }
316
+ end
317
+
318
+ ##
319
+ # Sorts the best platform match for the given matching specs and platform.
320
+
321
+ def sort_best_platform_match(matching, platform)
322
+ matching.sort_by.with_index do |spec, i|
323
+ [
324
+ platform_specificity_match(spec.platform, platform),
325
+ i, # for stable sort
326
+ ]
327
+ end
328
+ end
329
+
330
+ private
331
+
332
+ def same_specificity?(platform, spec, exemplary_spec)
333
+ platform_specificity_match(spec.platform, platform) == platform_specificity_match(exemplary_spec.platform, platform)
334
+ end
335
+
336
+ def same_deps?(spec, exemplary_spec)
337
+ spec.required_ruby_version == exemplary_spec.required_ruby_version &&
338
+ spec.required_rubygems_version == exemplary_spec.required_rubygems_version &&
339
+ spec.dependencies.sort == exemplary_spec.dependencies.sort
340
+ end
341
+
342
+ def os_match(spec_platform, user_platform)
343
+ if spec_platform.os == user_platform.os
344
+ 0
345
+ else
346
+ 1
347
+ end
348
+ end
349
+
350
+ def cpu_match(spec_platform, user_platform)
351
+ if spec_platform.cpu == user_platform.cpu
352
+ 0
353
+ elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm")
354
+ 0
355
+ elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal"
356
+ 1
357
+ else
358
+ 2
359
+ end
360
+ end
361
+
362
+ def version_match(spec_platform, user_platform)
363
+ if spec_platform.version == user_platform.version
364
+ 0
365
+ elsif spec_platform.version.nil?
366
+ 1
367
+ else
368
+ 2
369
+ end
370
+ end
371
+ end
269
372
  end
@@ -267,7 +267,7 @@ class Gem::RemoteFetcher
267
267
 
268
268
  def fetch_s3(uri, mtime = nil, head = false)
269
269
  begin
270
- public_uri = s3_uri_signer(uri).sign
270
+ public_uri = s3_uri_signer(uri, head ? "HEAD" : "GET").sign
271
271
  rescue Gem::S3URISigner::ConfigurationError, Gem::S3URISigner::InstanceProfileError => e
272
272
  raise FetchError.new(e.message, "s3://#{uri.host}")
273
273
  end
@@ -275,8 +275,8 @@ class Gem::RemoteFetcher
275
275
  end
276
276
 
277
277
  # we have our own signing code here to avoid a dependency on the aws-sdk gem
278
- def s3_uri_signer(uri)
279
- Gem::S3URISigner.new(uri)
278
+ def s3_uri_signer(uri, method)
279
+ Gem::S3URISigner.new(uri, method)
280
280
  end
281
281
 
282
282
  ##