rubygems-update 3.5.21 → 3.5.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/bundler/CHANGELOG.md +34 -0
  4. data/bundler/lib/bundler/build_metadata.rb +2 -2
  5. data/bundler/lib/bundler/cli/add.rb +2 -0
  6. data/bundler/lib/bundler/cli/check.rb +2 -2
  7. data/bundler/lib/bundler/cli.rb +1 -0
  8. data/bundler/lib/bundler/definition.rb +10 -16
  9. data/bundler/lib/bundler/dsl.rb +38 -22
  10. data/bundler/lib/bundler/inline.rb +12 -8
  11. data/bundler/lib/bundler/installer.rb +1 -1
  12. data/bundler/lib/bundler/lazy_specification.rb +9 -2
  13. data/bundler/lib/bundler/lockfile_generator.rb +1 -1
  14. data/bundler/lib/bundler/man/bundle-add.1 +5 -2
  15. data/bundler/lib/bundler/man/bundle-add.1.ronn +4 -1
  16. data/bundler/lib/bundler/man/bundle-binstubs.1 +1 -1
  17. data/bundler/lib/bundler/man/bundle-cache.1 +1 -1
  18. data/bundler/lib/bundler/man/bundle-check.1 +1 -1
  19. data/bundler/lib/bundler/man/bundle-clean.1 +1 -1
  20. data/bundler/lib/bundler/man/bundle-config.1 +1 -5
  21. data/bundler/lib/bundler/man/bundle-config.1.ronn +0 -7
  22. data/bundler/lib/bundler/man/bundle-console.1 +1 -1
  23. data/bundler/lib/bundler/man/bundle-doctor.1 +1 -1
  24. data/bundler/lib/bundler/man/bundle-exec.1 +1 -1
  25. data/bundler/lib/bundler/man/bundle-gem.1 +1 -1
  26. data/bundler/lib/bundler/man/bundle-help.1 +1 -1
  27. data/bundler/lib/bundler/man/bundle-info.1 +1 -1
  28. data/bundler/lib/bundler/man/bundle-init.1 +1 -1
  29. data/bundler/lib/bundler/man/bundle-inject.1 +1 -1
  30. data/bundler/lib/bundler/man/bundle-install.1 +2 -2
  31. data/bundler/lib/bundler/man/bundle-install.1.ronn +1 -2
  32. data/bundler/lib/bundler/man/bundle-list.1 +1 -1
  33. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  34. data/bundler/lib/bundler/man/bundle-open.1 +1 -1
  35. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  36. data/bundler/lib/bundler/man/bundle-platform.1 +1 -1
  37. data/bundler/lib/bundler/man/bundle-plugin.1 +1 -1
  38. data/bundler/lib/bundler/man/bundle-pristine.1 +1 -1
  39. data/bundler/lib/bundler/man/bundle-remove.1 +1 -1
  40. data/bundler/lib/bundler/man/bundle-show.1 +1 -1
  41. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  42. data/bundler/lib/bundler/man/bundle-version.1 +1 -1
  43. data/bundler/lib/bundler/man/bundle-viz.1 +1 -1
  44. data/bundler/lib/bundler/man/bundle.1 +1 -1
  45. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  46. data/bundler/lib/bundler/plugin/api/source.rb +1 -1
  47. data/bundler/lib/bundler/plugin.rb +20 -1
  48. data/bundler/lib/bundler/process_lock.rb +10 -14
  49. data/bundler/lib/bundler/resolver/base.rb +4 -0
  50. data/bundler/lib/bundler/rubygems_ext.rb +35 -3
  51. data/bundler/lib/bundler/rubygems_gem_installer.rb +3 -1
  52. data/bundler/lib/bundler/rubygems_integration.rb +2 -51
  53. data/bundler/lib/bundler/settings.rb +5 -1
  54. data/bundler/lib/bundler/shared_helpers.rb +27 -15
  55. data/bundler/lib/bundler/source/git.rb +2 -2
  56. data/bundler/lib/bundler/source/metadata.rb +2 -3
  57. data/bundler/lib/bundler/source/path.rb +1 -1
  58. data/bundler/lib/bundler/source/rubygems.rb +1 -4
  59. data/bundler/lib/bundler/stub_specification.rb +11 -0
  60. data/bundler/lib/bundler/templates/newgem/Gemfile.tt +0 -3
  61. data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -15
  62. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +4 -4
  63. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +46 -8
  64. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +2 -0
  65. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  66. data/bundler/lib/bundler/version.rb +1 -1
  67. data/bundler/lib/bundler.rb +1 -1
  68. data/lib/rubygems/basic_specification.rb +11 -6
  69. data/lib/rubygems/command_manager.rb +7 -2
  70. data/lib/rubygems/commands/contents_command.rb +15 -8
  71. data/lib/rubygems/commands/pristine_command.rb +16 -6
  72. data/lib/rubygems/commands/setup_command.rb +6 -0
  73. data/lib/rubygems/dependency.rb +1 -1
  74. data/lib/rubygems/gem_runner.rb +9 -0
  75. data/lib/rubygems/gemcutter_utilities.rb +8 -2
  76. data/lib/rubygems/installer.rb +6 -7
  77. data/lib/rubygems/package/tar_header.rb +11 -0
  78. data/lib/rubygems/package/tar_reader/entry.rb +1 -5
  79. data/lib/rubygems/spec_fetcher.rb +35 -7
  80. data/lib/rubygems/specification.rb +2 -2
  81. data/lib/rubygems/specification_record.rb +1 -1
  82. data/lib/rubygems/stub_specification.rb +11 -10
  83. data/lib/rubygems/vendor/net-http/lib/net/http.rb +1 -1
  84. data/lib/rubygems/vendor/uri/lib/uri/common.rb +2 -0
  85. data/lib/rubygems/vendor/uri/lib/uri/version.rb +1 -1
  86. data/lib/rubygems.rb +4 -4
  87. data/rubygems-update.gemspec +1 -1
  88. metadata +3 -3
@@ -68,6 +68,8 @@ autoload :OpenSSL, 'openssl'
68
68
  # #verify_callback :: For server certificate verification
69
69
  # #verify_depth :: Depth of certificate verification
70
70
  # #verify_mode :: How connections should be verified
71
+ # #verify_hostname :: Use hostname verification for server certificate
72
+ # during the handshake
71
73
  #
72
74
  # == Proxies
73
75
  #
@@ -174,7 +176,7 @@ class Gem::Net::HTTP::Persistent
174
176
  ##
175
177
  # The version of Gem::Net::HTTP::Persistent you are using
176
178
 
177
- VERSION = '4.0.2'
179
+ VERSION = '4.0.4'
178
180
 
179
181
  ##
180
182
  # Error class for errors raised by Gem::Net::HTTP::Persistent. Various
@@ -449,6 +451,21 @@ class Gem::Net::HTTP::Persistent
449
451
 
450
452
  attr_reader :verify_mode
451
453
 
454
+ ##
455
+ # HTTPS verify_hostname.
456
+ #
457
+ # If a client sets this to true and enables SNI with SSLSocket#hostname=,
458
+ # the hostname verification on the server certificate is performed
459
+ # automatically during the handshake using
460
+ # OpenSSL::SSL.verify_certificate_identity().
461
+ #
462
+ # You can set +verify_hostname+ as true to use hostname verification
463
+ # during the handshake.
464
+ #
465
+ # NOTE: This works with Ruby > 3.0.
466
+
467
+ attr_reader :verify_hostname
468
+
452
469
  ##
453
470
  # Creates a new Gem::Net::HTTP::Persistent.
454
471
  #
@@ -508,6 +525,7 @@ class Gem::Net::HTTP::Persistent
508
525
  @verify_callback = nil
509
526
  @verify_depth = nil
510
527
  @verify_mode = nil
528
+ @verify_hostname = nil
511
529
  @cert_store = nil
512
530
 
513
531
  @generation = 0 # incremented when proxy Gem::URI changes
@@ -607,13 +625,23 @@ class Gem::Net::HTTP::Persistent
607
625
 
608
626
  return yield connection
609
627
  rescue Errno::ECONNREFUSED
610
- address = http.proxy_address || http.address
611
- port = http.proxy_port || http.port
628
+ if http.proxy?
629
+ address = http.proxy_address
630
+ port = http.proxy_port
631
+ else
632
+ address = http.address
633
+ port = http.port
634
+ end
612
635
 
613
636
  raise Error, "connection refused: #{address}:#{port}"
614
637
  rescue Errno::EHOSTDOWN
615
- address = http.proxy_address || http.address
616
- port = http.proxy_port || http.port
638
+ if http.proxy?
639
+ address = http.proxy_address
640
+ port = http.proxy_port
641
+ else
642
+ address = http.address
643
+ port = http.port
644
+ end
617
645
 
618
646
  raise Error, "host down: #{address}:#{port}"
619
647
  ensure
@@ -948,8 +976,10 @@ class Gem::Net::HTTP::Persistent
948
976
  connection.min_version = @min_version if @min_version
949
977
  connection.max_version = @max_version if @max_version
950
978
 
951
- connection.verify_depth = @verify_depth
952
- connection.verify_mode = @verify_mode
979
+ connection.verify_depth = @verify_depth
980
+ connection.verify_mode = @verify_mode
981
+ connection.verify_hostname = @verify_hostname if
982
+ @verify_hostname != nil && connection.respond_to?(:verify_hostname=)
953
983
 
954
984
  if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and
955
985
  not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then
@@ -1058,6 +1088,15 @@ application:
1058
1088
  reconnect_ssl
1059
1089
  end
1060
1090
 
1091
+ ##
1092
+ # Sets the HTTPS verify_hostname.
1093
+
1094
+ def verify_hostname= verify_hostname
1095
+ @verify_hostname = verify_hostname
1096
+
1097
+ reconnect_ssl
1098
+ end
1099
+
1061
1100
  ##
1062
1101
  # SSL verification callback.
1063
1102
 
@@ -1070,4 +1109,3 @@ end
1070
1109
 
1071
1110
  require_relative 'persistent/connection'
1072
1111
  require_relative 'persistent/pool'
1073
-
@@ -19,6 +19,8 @@ module Bundler::URI
19
19
  Parser = RFC2396_Parser
20
20
  RFC3986_PARSER = RFC3986_Parser.new
21
21
  Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
22
+ RFC2396_PARSER = RFC2396_Parser.new
23
+ Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor)
22
24
 
23
25
  # Bundler::URI::Parser.new
24
26
  DEFAULT_PARSER = Parser.new
@@ -1,6 +1,6 @@
1
1
  module Bundler::URI
2
2
  # :stopdoc:
3
- VERSION_CODE = '001300'.freeze
3
+ VERSION_CODE = '001301'.freeze
4
4
  VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
5
5
  # :startdoc:
6
6
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "2.5.21".freeze
4
+ VERSION = "2.5.23".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= VERSION.split(".").first.to_i
@@ -492,7 +492,7 @@ module Bundler
492
492
  end
493
493
 
494
494
  def mkdir_p(path)
495
- SharedHelpers.filesystem_access(path, :write) do |p|
495
+ SharedHelpers.filesystem_access(path, :create) do |p|
496
496
  FileUtils.mkdir_p(p)
497
497
  end
498
498
  end
@@ -71,11 +71,7 @@ class Gem::BasicSpecification
71
71
  # Return true if this spec can require +file+.
72
72
 
73
73
  def contains_requirable_file?(file)
74
- if @ignored
75
- return false
76
- elsif missing_extensions?
77
- @ignored = true
78
-
74
+ if ignored?
79
75
  if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
80
76
  warn "Ignoring #{full_name} because its extensions are not built. " \
81
77
  "Try: gem pristine #{name} --version #{version}"
@@ -93,8 +89,17 @@ class Gem::BasicSpecification
93
89
  end
94
90
  end
95
91
 
92
+ ##
93
+ # Return true if this spec should be ignored because it's missing extensions.
94
+
95
+ def ignored?
96
+ return @ignored unless @ignored.nil?
97
+
98
+ @ignored = missing_extensions?
99
+ end
100
+
96
101
  def default_gem?
97
- loaded_from &&
102
+ !loaded_from.nil? &&
98
103
  File.dirname(loaded_from) == Gem.default_specifications_dir
99
104
  end
100
105
 
@@ -232,9 +232,14 @@ class Gem::CommandManager
232
232
  const_name = command_name.capitalize.gsub(/_(.)/) { $1.upcase } << "Command"
233
233
 
234
234
  begin
235
- require "rubygems/commands/#{command_name}_command"
235
+ begin
236
+ require "rubygems/commands/#{command_name}_command"
237
+ rescue LoadError
238
+ # it may have been defined from a rubygems_plugin.rb file
239
+ end
240
+
236
241
  Gem::Commands.const_get(const_name).new
237
- rescue StandardError, LoadError => e
242
+ rescue StandardError => e
238
243
  alert_error clean_text("Loading command: #{command_name} (#{e.class})\n\t#{e}")
239
244
  ui.backtrace e
240
245
  end
@@ -103,16 +103,23 @@ prefix or only the files that are requireable.
103
103
 
104
104
  def files_in_default_gem(spec)
105
105
  spec.files.map do |file|
106
- case file
107
- when %r{\A#{spec.bindir}/}
108
- # $' is POSTMATCH
109
- [RbConfig::CONFIG["bindir"], $']
110
- when /\.so\z/
111
- [RbConfig::CONFIG["archdir"], file]
106
+ if file.start_with?("#{spec.bindir}/")
107
+ [RbConfig::CONFIG["bindir"], file.delete_prefix("#{spec.bindir}/")]
112
108
  else
113
- [RbConfig::CONFIG["rubylibdir"], file]
109
+ gem spec.name, spec.version
110
+
111
+ require_path = spec.require_paths.find do |path|
112
+ file.start_with?("#{path}/")
113
+ end
114
+
115
+ requirable_part = file.delete_prefix("#{require_path}/")
116
+
117
+ resolve = $LOAD_PATH.resolve_feature_path(requirable_part)&.last
118
+ next unless resolve
119
+
120
+ [resolve.delete_suffix(requirable_part), requirable_part]
114
121
  end
115
- end
122
+ end.compact
116
123
  end
117
124
 
118
125
  def gem_contents(name)
@@ -134,10 +134,14 @@ extensions will be restored.
134
134
 
135
135
  say "Restoring gems to pristine condition..."
136
136
 
137
- specs.each do |spec|
138
- if spec.default_gem?
139
- say "Skipped #{spec.full_name}, it is a default gem"
140
- next
137
+ specs.group_by(&:full_name_with_location).values.each do |grouped_specs|
138
+ spec = grouped_specs.find {|s| !s.default_gem? } || grouped_specs.first
139
+
140
+ unless only_executables_or_plugins?
141
+ # Default gemspecs include changes provided by ruby-core installer that
142
+ # can't currently be pristined (inclusion of compiled extension targets in
143
+ # the file list). So stick to resetting executables if it's a default gem.
144
+ options[:only_executables] = true if spec.default_gem?
141
145
  end
142
146
 
143
147
  if options.key? :skip
@@ -147,14 +151,14 @@ extensions will be restored.
147
151
  end
148
152
  end
149
153
 
150
- unless spec.extensions.empty? || options[:extensions] || options[:only_executables] || options[:only_plugins]
154
+ unless spec.extensions.empty? || options[:extensions] || only_executables_or_plugins?
151
155
  say "Skipped #{spec.full_name_with_location}, it needs to compile an extension"
152
156
  next
153
157
  end
154
158
 
155
159
  gem = spec.cache_file
156
160
 
157
- unless File.exist?(gem) || options[:only_executables] || options[:only_plugins]
161
+ unless File.exist?(gem) || only_executables_or_plugins?
158
162
  require_relative "../remote_fetcher"
159
163
 
160
164
  say "Cached gem for #{spec.full_name_with_location} not found, attempting to fetch..."
@@ -204,4 +208,10 @@ extensions will be restored.
204
208
  say "Restored #{spec.full_name_with_location}"
205
209
  end
206
210
  end
211
+
212
+ private
213
+
214
+ def only_executables_or_plugins?
215
+ options[:only_executables] || options[:only_plugins]
216
+ end
207
217
  end
@@ -365,9 +365,15 @@ By default, this RubyGems will install gem as:
365
365
  def install_default_bundler_gem(bin_dir)
366
366
  current_default_spec = Gem::Specification.default_stubs.find {|s| s.name == "bundler" }
367
367
  specs_dir = if current_default_spec && default_dir == Gem.default_dir
368
+ all_specs_current_version = Gem::Specification.stubs.select {|s| s.full_name == current_default_spec.full_name }
369
+
368
370
  Gem::Specification.remove_spec current_default_spec
369
371
  loaded_from = current_default_spec.loaded_from
370
372
  File.delete(loaded_from)
373
+
374
+ # Remove previous default gem executables if they were not shadowed by a regular gem
375
+ FileUtils.rm_rf current_default_spec.full_gem_path if all_specs_current_version.size == 1
376
+
371
377
  File.dirname(loaded_from)
372
378
  else
373
379
  target_specs_dir = File.join(default_dir, "specifications", "default")
@@ -279,7 +279,7 @@ class Gem::Dependency
279
279
  end
280
280
  end
281
281
 
282
- matches
282
+ matches.reject(&:ignored?)
283
283
  end
284
284
 
285
285
  ##
@@ -29,6 +29,7 @@ class Gem::GemRunner
29
29
  # Run the gem command with the following arguments.
30
30
 
31
31
  def run(args)
32
+ validate_encoding args
32
33
  build_args = extract_build_args args
33
34
 
34
35
  do_configuration args
@@ -72,6 +73,14 @@ class Gem::GemRunner
72
73
 
73
74
  private
74
75
 
76
+ def validate_encoding(args)
77
+ invalid_arg = args.find {|arg| !arg.valid_encoding? }
78
+
79
+ if invalid_arg
80
+ raise Gem::OptionParser::InvalidArgument.new("'#{invalid_arg.scrub}' has invalid encoding")
81
+ end
82
+ end
83
+
75
84
  def do_configuration(args)
76
85
  Gem.configuration = @config_file_class.new(args)
77
86
  Gem.use_paths Gem.configuration[:gemhome], Gem.configuration[:gempath]
@@ -62,6 +62,10 @@ module Gem::GemcutterUtilities
62
62
  options[:otp] || ENV["GEM_HOST_OTP_CODE"]
63
63
  end
64
64
 
65
+ def webauthn_enabled?
66
+ options[:webauthn]
67
+ end
68
+
65
69
  ##
66
70
  # The host to connect to either from the RUBYGEMS_HOST environment variable
67
71
  # or from the user's configuration
@@ -136,7 +140,6 @@ module Gem::GemcutterUtilities
136
140
  response = rubygems_api_request(:put, "api/v1/api_key",
137
141
  sign_in_host, scope: scope) do |request|
138
142
  request.basic_auth identifier, password
139
- request["OTP"] = otp if otp
140
143
  request.body = Gem::URI.encode_www_form({ api_key: api_key }.merge(update_scope_params))
141
144
  end
142
145
 
@@ -176,7 +179,6 @@ module Gem::GemcutterUtilities
176
179
  response = rubygems_api_request(:post, "api/v1/api_key",
177
180
  sign_in_host, credentials: credentials, scope: scope) do |request|
178
181
  request.basic_auth identifier, password
179
- request["OTP"] = otp if otp
180
182
  request.body = Gem::URI.encode_www_form({ name: key_name }.merge(all_params))
181
183
  end
182
184
 
@@ -251,6 +253,8 @@ module Gem::GemcutterUtilities
251
253
  req["OTP"] = otp if otp
252
254
  block.call(req)
253
255
  end
256
+ ensure
257
+ options[:otp] = nil if webauthn_enabled?
254
258
  end
255
259
 
256
260
  def fetch_otp(credentials)
@@ -271,6 +275,8 @@ module Gem::GemcutterUtilities
271
275
  terminate_interaction(1)
272
276
  end
273
277
 
278
+ options[:webauthn] = true
279
+
274
280
  say "You are verified with a security device. You may close the browser window."
275
281
  otp_thread[:otp]
276
282
  else
@@ -998,18 +998,17 @@ TEXT
998
998
 
999
999
  def bash_prolog_script
1000
1000
  if load_relative_enabled?
1001
- script = +<<~EOS
1002
- bindir="${0%/*}"
1003
- EOS
1004
-
1005
- script << %(exec "$bindir/#{ruby_install_name}" "-x" "$0" "$@"\n)
1006
-
1007
1001
  <<~EOS
1008
1002
  #!/bin/sh
1009
1003
  # -*- ruby -*-
1010
1004
  _=_\\
1011
1005
  =begin
1012
- #{script.chomp}
1006
+ bindir="${0%/*}"
1007
+ ruby="$bindir/#{ruby_install_name}"
1008
+ if [ ! -f "$ruby" ]; then
1009
+ ruby="#{ruby_install_name}"
1010
+ fi
1011
+ exec "$ruby" "-x" "$0" "$@"
1013
1012
  =end
1014
1013
  EOS
1015
1014
  else
@@ -228,6 +228,17 @@ class Gem::Package::TarHeader
228
228
  @checksum = oct calculate_checksum(header), 6
229
229
  end
230
230
 
231
+ ##
232
+ # Header's full name, including prefix
233
+
234
+ def full_name
235
+ if prefix != ""
236
+ File.join prefix, name
237
+ else
238
+ name
239
+ end
240
+ end
241
+
231
242
  private
232
243
 
233
244
  def calculate_checksum(header)
@@ -87,11 +87,7 @@ class Gem::Package::TarReader::Entry
87
87
  # Full name of the tar entry
88
88
 
89
89
  def full_name
90
- if @header.prefix != ""
91
- File.join @header.prefix, @header.name
92
- else
93
- @header.name
94
- end
90
+ @header.full_name.force_encoding(Encoding::UTF_8)
95
91
  rescue ArgumentError => e
96
92
  raise unless e.message == "string contains null byte"
97
93
  raise Gem::Package::TarInvalidError,
@@ -170,17 +170,45 @@ class Gem::SpecFetcher
170
170
  # alternative gem names.
171
171
 
172
172
  def suggest_gems_from_name(gem_name, type = :latest, num_results = 5)
173
- gem_name = gem_name.downcase.tr("_-", "")
174
- max = gem_name.size / 2
175
- names = available_specs(type).first.values.flatten(1)
173
+ gem_name = gem_name.downcase.tr("_-", "")
176
174
 
177
- matches = names.map do |n|
175
+ # All results for 3-character-or-shorter (minus hyphens/underscores) gem
176
+ # names get rejected, so we just return an empty array immediately instead.
177
+ return [] if gem_name.length <= 3
178
+
179
+ max = gem_name.size / 2
180
+ names = available_specs(type).first.values.flatten(1)
181
+
182
+ min_length = gem_name.length - max
183
+ max_length = gem_name.length + max
184
+
185
+ matches = names.filter_map do |n|
186
+ len = n.name.length
187
+ # If the length is min_length or shorter, we've done `max` deletions.
188
+ # If the length is max_length or longer, we've done `max` insertions.
189
+ # These would both be rejected later, so we skip early for performance.
190
+ next if len <= min_length || len >= max_length
191
+
192
+ # If the gem doesn't support the current platform, bail early.
178
193
  next unless n.match_platform?
179
- distance = levenshtein_distance gem_name, n.name.downcase.tr("_-", "")
194
+
195
+ # The candidate name, normalized the same as gem_name.
196
+ normalized_name = n.name.downcase
197
+ normalized_name.tr!("_-", "")
198
+
199
+ # If we found an exact match (after stripping underscores and hyphens),
200
+ # that's our most likely candidate.
201
+ # Return it immediately, and skip the rest of the loop.
202
+ return [n.name] if normalized_name == gem_name
203
+
204
+ distance = levenshtein_distance gem_name, normalized_name
205
+
206
+ # Skip current candidate, if the edit distance is greater than allowed.
180
207
  next if distance >= max
181
- return [n.name] if distance == 0
208
+
209
+ # If all else fails, return the name and the calculated distance.
182
210
  [n.name, distance]
183
- end.compact
211
+ end
184
212
 
185
213
  matches = if matches.empty? && type != :prerelease
186
214
  suggest_gems_from_name gem_name, :prerelease
@@ -391,7 +391,7 @@ class Gem::Specification < Gem::BasicSpecification
391
391
  # "homepage_uri" => "https://bestgemever.example.io",
392
392
  # "mailing_list_uri" => "https://groups.example.com/bestgemever",
393
393
  # "source_code_uri" => "https://example.com/user/bestgemever",
394
- # "wiki_uri" => "https://example.com/user/bestgemever/wiki"
394
+ # "wiki_uri" => "https://example.com/user/bestgemever/wiki",
395
395
  # "funding_uri" => "https://example.com/donate"
396
396
  # }
397
397
  #
@@ -2470,7 +2470,7 @@ class Gem::Specification < Gem::BasicSpecification
2470
2470
 
2471
2471
  if @installed_by_version
2472
2472
  result << nil
2473
- result << " s.installed_by_version = #{ruby_code Gem::VERSION} if s.respond_to? :installed_by_version"
2473
+ result << " s.installed_by_version = #{ruby_code Gem::VERSION}"
2474
2474
  end
2475
2475
 
2476
2476
  unless dependencies.empty?
@@ -30,7 +30,7 @@ module Gem
30
30
  # Returns the list of all specifications in the record
31
31
 
32
32
  def all
33
- @all ||= Gem.loaded_specs.values | stubs.map(&:to_spec)
33
+ @all ||= stubs.map(&:to_spec)
34
34
  end
35
35
 
36
36
  ##
@@ -83,11 +83,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
83
83
  # True when this gem has been activated
84
84
 
85
85
  def activated?
86
- @activated ||=
87
- begin
88
- loaded = Gem.loaded_specs[name]
89
- loaded && loaded.version == version
90
- end
86
+ @activated ||= !loaded_spec.nil?
91
87
  end
92
88
 
93
89
  def default_gem?
@@ -187,11 +183,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
187
183
  # The full Gem::Specification for this gem, loaded from evalling its gemspec
188
184
 
189
185
  def spec
190
- @spec ||= if @data
191
- loaded = Gem.loaded_specs[name]
192
- loaded if loaded && loaded.version == version
193
- end
194
-
186
+ @spec ||= loaded_spec if @data
195
187
  @spec ||= Gem::Specification.load(loaded_from)
196
188
  end
197
189
  alias_method :to_spec, :spec
@@ -231,4 +223,13 @@ class Gem::StubSpecification < Gem::BasicSpecification
231
223
  def sort_obj # :nodoc:
232
224
  [name, version, Gem::Platform.sort_priority(platform)]
233
225
  end
226
+
227
+ private
228
+
229
+ def loaded_spec
230
+ spec = Gem.loaded_specs[name]
231
+ return unless spec && spec.version == version && spec.default_gem? == default_gem?
232
+
233
+ spec
234
+ end
234
235
  end
@@ -722,7 +722,7 @@ module Gem::Net #:nodoc:
722
722
  class HTTP < Protocol
723
723
 
724
724
  # :stopdoc:
725
- VERSION = "0.4.0"
725
+ VERSION = "0.4.1"
726
726
  HTTPVersion = '1.1'
727
727
  begin
728
728
  require 'zlib'
@@ -19,6 +19,8 @@ module Gem::URI
19
19
  Parser = RFC2396_Parser
20
20
  RFC3986_PARSER = RFC3986_Parser.new
21
21
  Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
22
+ RFC2396_PARSER = RFC2396_Parser.new
23
+ Ractor.make_shareable(RFC2396_PARSER) if defined?(Ractor)
22
24
 
23
25
  # Gem::URI::Parser.new
24
26
  DEFAULT_PARSER = Parser.new
@@ -1,6 +1,6 @@
1
1
  module Gem::URI
2
2
  # :stopdoc:
3
- VERSION_CODE = '001300'.freeze
3
+ VERSION_CODE = '001301'.freeze
4
4
  VERSION = VERSION_CODE.scan(/../).collect{|n| n.to_i}.join('.').freeze
5
5
  # :startdoc:
6
6
  end
data/lib/rubygems.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  require "rbconfig"
10
10
 
11
11
  module Gem
12
- VERSION = "3.5.21"
12
+ VERSION = "3.5.23"
13
13
  end
14
14
 
15
15
  # Must be first since it unloads the prelude from 1.9.2
@@ -781,6 +781,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
781
781
  file_lock = "#{path}.lock"
782
782
  open_file_with_flock(file_lock, &block)
783
783
  ensure
784
+ require "fileutils"
784
785
  FileUtils.rm_f file_lock
785
786
  end
786
787
 
@@ -788,15 +789,14 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
788
789
  # Open a file with given flags, and protect access with flock
789
790
 
790
791
  def self.open_file_with_flock(path, &block)
791
- mode = IO::RDONLY | IO::APPEND | IO::CREAT | IO::BINARY
792
+ # read-write mode is used rather than read-only in order to support NFS
793
+ mode = IO::RDWR | IO::APPEND | IO::CREAT | IO::BINARY
792
794
  mode |= IO::SHARE_DELETE if IO.const_defined?(:SHARE_DELETE)
793
795
 
794
796
  File.open(path, mode) do |io|
795
797
  begin
796
798
  io.flock(File::LOCK_EX)
797
799
  rescue Errno::ENOSYS, Errno::ENOTSUP
798
- rescue Errno::ENOLCK # NFS
799
- raise unless Thread.main == Thread.current
800
800
  end
801
801
  yield io
802
802
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "rubygems-update"
5
- s.version = "3.5.21"
5
+ s.version = "3.5.23"
6
6
  s.authors = ["Jim Weirich", "Chad Fowler", "Eric Hodel", "Luis Lavena", "Aaron Patterson", "Samuel Giddins", "André Arko", "Evan Phoenix", "Hiroshi SHIBATA"]
7
7
  s.email = ["", "", "drbrain@segment7.net", "luislavena@gmail.com", "aaron@tenderlovemaking.com", "segiddins@segiddins.me", "andre@arko.net", "evan@phx.io", "hsbt@ruby-lang.org"]
8
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubygems-update
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.21
4
+ version: 3.5.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -16,7 +16,7 @@ authors:
16
16
  autorequire:
17
17
  bindir: exe
18
18
  cert_chain: []
19
- date: 2024-10-03 00:00:00.000000000 Z
19
+ date: 2024-11-05 00:00:00.000000000 Z
20
20
  dependencies: []
21
21
  description: |-
22
22
  A package (also known as a library) contains a set of functionality
@@ -737,7 +737,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
737
737
  - !ruby/object:Gem::Version
738
738
  version: '0'
739
739
  requirements: []
740
- rubygems_version: 3.5.21
740
+ rubygems_version: 3.5.23
741
741
  signing_key:
742
742
  specification_version: 4
743
743
  summary: RubyGems is a package management framework for Ruby. This gem is downloaded