rubygems-update 4.0.19 → 4.0.21

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/Manifest.txt +0 -2
  4. data/bundler/CHANGELOG.md +35 -0
  5. data/bundler/bundler.gemspec +1 -1
  6. data/bundler/lib/bundler/build_metadata.rb +2 -2
  7. data/bundler/lib/bundler/cli/doctor/diagnose.rb +1 -1
  8. data/bundler/lib/bundler/cli/exec.rb +15 -1
  9. data/bundler/lib/bundler/cli/init.rb +4 -0
  10. data/bundler/lib/bundler/cli/outdated.rb +37 -7
  11. data/bundler/lib/bundler/cli/update.rb +1 -1
  12. data/bundler/lib/bundler/cli.rb +2 -2
  13. data/bundler/lib/bundler/definition.rb +12 -2
  14. data/bundler/lib/bundler/dsl.rb +1 -1
  15. data/bundler/lib/bundler/fetcher/downloader.rb +9 -0
  16. data/bundler/lib/bundler/gem_helper.rb +2 -2
  17. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  18. data/bundler/lib/bundler/man/bundle-lock.1.ronn +3 -2
  19. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  20. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +7 -1
  21. data/bundler/lib/bundler/man/bundle-platform.1 +4 -0
  22. data/bundler/lib/bundler/man/bundle-platform.1.ronn +4 -0
  23. data/bundler/lib/bundler/man/bundle-update.1 +1 -1
  24. data/bundler/lib/bundler/man/bundle-update.1.ronn +3 -1
  25. data/bundler/lib/bundler/man/gemfile.5 +1 -1
  26. data/bundler/lib/bundler/man/gemfile.5.ronn +3 -1
  27. data/bundler/lib/bundler/runtime.rb +11 -11
  28. data/bundler/lib/bundler/self_manager.rb +15 -9
  29. data/bundler/lib/bundler/shared_helpers.rb +15 -0
  30. data/bundler/lib/bundler/source/git/git_proxy.rb +73 -4
  31. data/bundler/lib/bundler/source/git.rb +10 -8
  32. data/bundler/lib/bundler/source/path.rb +1 -1
  33. data/bundler/lib/bundler/source/rubygems.rb +1 -1
  34. data/bundler/lib/bundler/stub_specification.rb +3 -1
  35. data/bundler/lib/bundler/version.rb +1 -1
  36. data/bundler/lib/bundler.rb +15 -5
  37. data/lib/rubygems/command.rb +1 -1
  38. data/lib/rubygems/commands/contents_command.rb +14 -6
  39. data/lib/rubygems/commands/exec_command.rb +1 -1
  40. data/lib/rubygems/commands/setup_command.rb +11 -38
  41. data/lib/rubygems/commands/stale_command.rb +1 -1
  42. data/lib/rubygems/config_file.rb +21 -10
  43. data/lib/rubygems/ext/builder.rb +3 -1
  44. data/lib/rubygems/package.rb +1 -1
  45. data/lib/rubygems/security/signer.rb +1 -3
  46. data/lib/rubygems/update_suggestion.rb +6 -2
  47. data/lib/rubygems/util.rb +29 -5
  48. data/lib/rubygems/vendor/net-http/lib/net/http.rb +24 -2
  49. data/lib/rubygems.rb +1 -1
  50. metadata +2 -4
  51. data/lib/rubygems/vendor/resolv/COPYING +0 -56
  52. data/lib/rubygems/vendor/resolv/lib/resolv.rb +0 -3499
@@ -193,7 +193,13 @@ module Bundler
193
193
  return out if status.success?
194
194
 
195
195
  if err.include?("couldn't find remote ref") || err.include?("not our ref")
196
- raise MissingGitRevisionError.new(command_with_no_credentials, path, commit || explicit_ref, credential_filtered_uri)
196
+ default_branch = renamed_remote_default_branch if tracking_remote_default_branch?
197
+ if default_branch
198
+ out = follow_remote_default_branch(args, default_branch)
199
+ return out if out
200
+ end
201
+
202
+ raise MissingGitRevisionError.new(command_with_no_credentials, path, commit || explicit_ref || current_branch, credential_filtered_uri)
197
203
  else
198
204
  if shallow?
199
205
  args -= depth_args
@@ -298,6 +304,61 @@ module Bundler
298
304
  branch_option || ref.nil?
299
305
  end
300
306
 
307
+ def tracking_remote_default_branch?
308
+ explicit_ref.nil? && commit.nil?
309
+ end
310
+
311
+ # Returns nil on any failure, leaving HEAD untouched so the caller reports
312
+ # the original fetch failure. Runs inside the retry block, so it must not
313
+ # touch the caller's command locals.
314
+ def follow_remote_default_branch(args, default_branch)
315
+ reference = "refs/heads/#{default_branch}"
316
+ command = fetch_command(args, "#{reference}:#{reference}")
317
+ check_allowed(command)
318
+
319
+ out, err, status = capture(command, path)
320
+ unless status.success?
321
+ Bundler.ui.debug "Could not fetch #{reference} from #{credential_filtered_uri}: #{err}"
322
+ return
323
+ end
324
+
325
+ previous_branch = current_branch
326
+ begin
327
+ git "symbolic-ref", "HEAD", reference, dir: path
328
+ rescue GitError => e
329
+ Bundler.ui.debug "Could not repoint the cached clone at #{reference}: #{e.message}"
330
+ return
331
+ end
332
+ @current_branch = nil
333
+ Bundler.ui.warn "#{credential_filtered_uri} no longer has #{previous_branch}, " \
334
+ "now following its default branch #{default_branch}"
335
+ out
336
+ end
337
+
338
+ # The cached clone's HEAD branch is gone from the remote, so the remote's
339
+ # own idea of its default branch is the only thing left to follow.
340
+ def renamed_remote_default_branch
341
+ default_branch = remote_default_branch
342
+ return if default_branch.nil? || default_branch == current_branch
343
+
344
+ default_branch
345
+ end
346
+
347
+ def remote_default_branch
348
+ command = ["ls-remote", "--symref", "--", configured_uri, "HEAD"]
349
+ check_allowed(command)
350
+
351
+ out, err, status = capture(command, path)
352
+ unless status.success?
353
+ Bundler.ui.debug "Could not ask #{credential_filtered_uri} for its default branch: #{err}"
354
+ return
355
+ end
356
+
357
+ # A remote is free to advertise a ref name that is not valid UTF-8, and
358
+ # matching that as text raises out of the GitError family.
359
+ out.b[%r{^ref:\s+refs/heads/(.+?)\s+HEAD}, 1]
360
+ end
361
+
301
362
  def pinned_to_full_sha?
302
363
  full_sha_revision?(ref)
303
364
  end
@@ -446,7 +507,15 @@ module Bundler
446
507
 
447
508
  return ["git", *opts, *cmd] unless dir
448
509
 
449
- ["git", "-C", dir.to_s, *opts, *cmd]
510
+ # With safe.bareRepository=explicit, git refuses to discover a bare
511
+ # repository from -C, so the cache clone is named with --git-dir.
512
+ # Working trees, like a local override, still go through -C.
513
+ location = bare_repo?(dir) ? "--git-dir" : "-C"
514
+ ["git", location, dir.to_s, *opts, *cmd]
515
+ end
516
+
517
+ def bare_repo?(dir)
518
+ File.exist?(File.join(dir, "objects")) && File.exist?(File.join(dir, "HEAD"))
450
519
  end
451
520
 
452
521
  def extra_clone_args
@@ -465,8 +534,8 @@ module Bundler
465
534
  args
466
535
  end
467
536
 
468
- def fetch_command(args)
469
- ["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, refspec].compact
537
+ def fetch_command(args, spec = refspec)
538
+ ["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, spec].compact
470
539
  end
471
540
 
472
541
  def clone_command(args)
@@ -91,9 +91,9 @@ module Bundler
91
91
 
92
92
  def to_s
93
93
  begin
94
- at = humanized_ref || current_branch
95
-
96
- rev = "at #{at}@#{shortref_for_display(revision)}"
94
+ at = humanized_ref
95
+ at = "#{at}@" if at
96
+ rev = "at #{at}#{shortref_for_display(revision)}"
97
97
  rescue GitError
98
98
  ""
99
99
  end
@@ -320,7 +320,7 @@ module Bundler
320
320
 
321
321
  def serialize_gemspecs_in(destination)
322
322
  destination = destination.expand_path(Bundler.root) if destination.relative?
323
- Gem::Util.glob_files_in_dir(@glob, destination.to_s).each do |spec_path|
323
+ SharedHelpers.glob_files_in_dir(@glob, destination.to_s).each do |spec_path|
324
324
  # Evaluate gemspecs and cache the result. Gemspecs
325
325
  # in git might require git or other dependencies.
326
326
  # The gemspecs we cache should already be evaluated.
@@ -423,10 +423,12 @@ module Bundler
423
423
  def validate_spec(_spec); end
424
424
 
425
425
  def load_gemspec(file)
426
- dirname = Pathname.new(file).dirname
427
- SharedHelpers.chdir(dirname.to_s) do
428
- stub = Gem::StubSpecification.gemspec_stub(file, install_path.parent, install_path.parent)
429
- stub.full_gem_path = dirname.expand_path(root).to_s
426
+ # Expand the path before the chdir below, since resolving it inside the
427
+ # block would base it on the gemspec directory instead of `root`.
428
+ gemspec_path = Pathname.new(file).expand_path(root)
429
+ SharedHelpers.chdir(gemspec_path.dirname.to_s) do
430
+ stub = Gem::StubSpecification.gemspec_stub(gemspec_path.to_s, install_path.parent, install_path.parent)
431
+ stub.full_gem_path = gemspec_path.dirname.to_s
430
432
  StubSpecification.from_stub(stub)
431
433
  end
432
434
  end
@@ -161,7 +161,7 @@ module Bundler
161
161
 
162
162
  if File.directory?(expanded_path)
163
163
  # We sort depth-first since `<<` will override the earlier-found specs
164
- Gem::Util.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
164
+ SharedHelpers.glob_files_in_dir(@glob, expanded_path).sort_by {|p| -p.split(File::SEPARATOR).size }.each do |file|
165
165
  next unless spec = load_gemspec(file)
166
166
  spec.source = self
167
167
 
@@ -406,7 +406,7 @@ module Bundler
406
406
  @cached_specs ||= begin
407
407
  idx = Index.new
408
408
 
409
- Gem::Util.glob_files_in_dir("*.gem", cache_path.to_s).each do |gemfile|
409
+ SharedHelpers.glob_files_in_dir("*.gem", cache_path.to_s).each do |gemfile|
410
410
  s ||= Bundler.rubygems.spec_from_gem(gemfile)
411
411
  s.source = self
412
412
  idx << s
@@ -126,7 +126,9 @@ module Bundler
126
126
  def _remote_specification
127
127
  @_remote_specification ||= begin
128
128
  rs = stub.to_spec
129
- if rs.equal?(self) # happens when to_spec gets the spec from Gem.loaded_specs
129
+ # Gem::StubSpecification#to_spec may return an activated specification
130
+ # with the same name and version from a different gem installation.
131
+ if rs.equal?(self) || rs.loaded_from != loaded_from
130
132
  rs = Gem::Specification.load(loaded_from)
131
133
  Bundler.rubygems.stub_set_spec(stub, rs)
132
134
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "4.0.19".freeze
4
+ VERSION = "4.0.21".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= gem_version.segments.first
@@ -527,11 +527,11 @@ module Bundler
527
527
  end
528
528
 
529
529
  def load_gemspec_uncached(file, validate = false)
530
- path = Pathname.new(file)
531
- contents = read_file(file)
530
+ path = Pathname.new(file).expand_path
531
+ contents = read_file(path.to_s)
532
532
  spec = eval_gemspec(path, contents)
533
533
  return unless spec
534
- spec.loaded_from = path.expand_path.to_s
534
+ spec.loaded_from = path.to_s
535
535
  Bundler.rubygems.validate(spec) if validate
536
536
  spec
537
537
  end
@@ -646,9 +646,19 @@ module Bundler
646
646
  eval_yaml_gemspec(path, contents)
647
647
  else
648
648
  # Eval the gemspec from its parent directory, because some gemspecs
649
- # depend on "./" relative paths.
649
+ # depend on "./" relative paths. The caller expands `path` first, since
650
+ # expanding it here would resolve against the gemspec directory once
651
+ # the chdir is active.
650
652
  SharedHelpers.chdir(path.dirname.to_s) do
651
- eval(contents, TOPLEVEL_BINDING.dup, path.expand_path.to_s)
653
+ # TOPLEVEL_BINDING always belongs to the main box, so inside a
654
+ # Ruby::Box use a binding from the box Bundler is loaded in, where
655
+ # Gem::Specification carries Bundler's own monkey patches.
656
+ eval_binding = if defined?(Ruby::Box) && Ruby::Box.enabled?
657
+ Ruby::Box.current.eval("binding")
658
+ else
659
+ TOPLEVEL_BINDING.dup
660
+ end
661
+ eval(contents, eval_binding, path.to_s)
652
662
  end
653
663
  end
654
664
  rescue ScriptError, StandardError => e
@@ -440,7 +440,7 @@ class Gem::Command
440
440
  def handle_options(args)
441
441
  args = add_extra_args(args)
442
442
  check_deprecated_options(args)
443
- @options = Marshal.load Marshal.dump @defaults # deep copy
443
+ @options = Gem::Util.deep_dup @defaults
444
444
  parser.parse!(args)
445
445
  @options[:args] = args
446
446
  end
@@ -91,13 +91,21 @@ prefix or only the files that are requireable.
91
91
  end
92
92
 
93
93
  def files_in_gem(spec)
94
- gem_path = spec.full_gem_path
95
- extra = "/{#{spec.require_paths.join ","}}" if options[:lib_only]
96
- glob = "#{gem_path}#{extra}/**/*"
97
- prefix_re = %r{#{Regexp.escape(gem_path)}/}
94
+ gem_path = spec.full_gem_path
98
95
 
99
- Dir[glob].map do |file|
100
- [gem_path, file.sub(prefix_re, "")]
96
+ if options[:lib_only]
97
+ # raw_require_paths rather than require_paths, since the latter prepends
98
+ # the absolute extension_dir, which would escape the glob base
99
+ require_paths = spec.raw_require_paths
100
+ return [] if require_paths.empty?
101
+
102
+ glob = "{#{require_paths.join ","}}/**/*"
103
+ else
104
+ glob = "**/*"
105
+ end
106
+
107
+ Dir.glob(glob, base: gem_path).map do |file|
108
+ [gem_path, file]
101
109
  end
102
110
  end
103
111
 
@@ -79,7 +79,7 @@ to the same gem path as user-installed gems.
79
79
  def handle_options(args)
80
80
  args = add_extra_args(args)
81
81
  check_deprecated_options(args)
82
- @options = Marshal.load Marshal.dump @defaults # deep copy
82
+ @options = Gem::Util.deep_dup @defaults
83
83
  parser.order!(args) do |v|
84
84
  # put the non-option back at the front of the list of arguments
85
85
  args.unshift(v)
@@ -7,9 +7,6 @@ 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*$}
12
-
13
10
  ENV_PATHS = %w[/usr/bin/env /bin/env].freeze
14
11
 
15
12
  def initialize
@@ -23,7 +20,7 @@ class Gem::Commands::SetupCommand < Gem::Command
23
20
 
24
21
  add_option "--previous-version=VERSION",
25
22
  "Previous version of RubyGems",
26
- "Used for changelog processing" do |version, options|
23
+ "Used for the release notes link" do |version, options|
27
24
  options[:previous_version] = version
28
25
  end
29
26
 
@@ -183,12 +180,6 @@ By default, this RubyGems will install gem as:
183
180
  say
184
181
  end
185
182
 
186
- if options[:previous_version].empty?
187
- options[:previous_version] = Gem::VERSION.sub(/[0-9]+$/, "0")
188
- end
189
-
190
- options[:previous_version] = Gem::Version.new(options[:previous_version])
191
-
192
183
  show_release_notes
193
184
 
194
185
  say
@@ -319,7 +310,7 @@ By default, this RubyGems will install gem as:
319
310
  (!File.exist?(rubygems_doc_dir) ||
320
311
  File.writable?(rubygems_doc_dir))
321
312
  say "Removing old RubyGems RDoc and ri" if @verbose
322
- Dir[File.join(Gem.dir, "doc", "rubygems-[0-9]*")].each do |dir|
313
+ Gem::Util.glob_files_in_dir("rubygems-[0-9]*", gem_doc_dir).each do |dir|
323
314
  rm_rf dir
324
315
  end
325
316
 
@@ -552,34 +543,16 @@ abort "#{deprecation_message}"
552
543
  end
553
544
 
554
545
  def show_release_notes
555
- release_notes = File.join Dir.pwd, "CHANGELOG.md"
556
-
557
- release_notes =
558
- if File.exist? release_notes
559
- history = File.read release_notes
560
-
561
- history.force_encoding Encoding::UTF_8
562
-
563
- text = history.split(HISTORY_HEADER)
564
- text.shift # correct an off-by-one generated by split
565
- version_lines = history.scan(HISTORY_HEADER)
566
- versions = history.scan(VERSION_MATCHER).flatten.map do |x|
567
- Gem::Version.new(x)
568
- end
546
+ ref = Gem::VERSION.include?(".dev") ? "master" : "v#{Gem::VERSION}"
547
+ link = "https://github.com/ruby/rubygems/blob/#{ref}/CHANGELOG.md"
569
548
 
570
- history_string = ""
571
-
572
- until versions.length == 0 ||
573
- versions.shift <= options[:previous_version] do
574
- history_string += version_lines.shift + text.shift
575
- end
576
-
577
- history_string
578
- else
579
- "Oh-no! Unable to find release notes!"
580
- end
581
-
582
- say release_notes
549
+ previous = options[:previous_version].to_s.strip
550
+ if previous.empty? || !Gem::Version.correct?(previous) ||
551
+ Gem::Version.new(previous) >= Gem::Version.new(Gem::VERSION)
552
+ say "See #{link} for the changes."
553
+ else
554
+ say "See #{link} for the changes since #{previous}."
555
+ end
583
556
  end
584
557
 
585
558
  def uninstall_old_gemcutter
@@ -25,7 +25,7 @@ longer using.
25
25
  gem_to_atime = {}
26
26
  Gem::Specification.each do |spec|
27
27
  name = spec.full_name
28
- Dir["#{spec.full_gem_path}/**/*.*"].each do |file|
28
+ Gem::Util.glob_files_in_dir("**/*.*", spec.full_gem_path).each do |file|
29
29
  next if File.directory?(file)
30
30
  stat = File.stat(file)
31
31
  gem_to_atime[name] ||= stat.atime
@@ -26,9 +26,20 @@ require "rbconfig"
26
26
  # RubyGems options use symbol keys. Valid options are:
27
27
  #
28
28
  # +:backtrace+:: See #backtrace
29
- # +:sources+:: Sets Gem::sources
29
+ # +:bulk_threshold+:: See #bulk_threshold
30
30
  # +:verbose+:: See #verbose
31
+ # +:update_sources+:: See #update_sources
31
32
  # +:concurrent_downloads+:: See #concurrent_downloads
33
+ # +:cert_expiration_length_days+:: See #cert_expiration_length_days
34
+ # +:install_extension_in_lib+:: See #install_extension_in_lib
35
+ # +:ipv4_fallback_enabled+:: See #ipv4_fallback_enabled
36
+ # +:gemhome+:: See #home
37
+ # +:gempath+:: See #path
38
+ # +:sources+:: Sets Gem::sources
39
+ # +:disable_default_gem_server+:: See #disable_default_gem_server
40
+ # +:ssl_verify_mode+:: See #ssl_verify_mode
41
+ # +:ssl_ca_cert+:: See #ssl_ca_cert
42
+ # +:ssl_client_cert+:: See #ssl_client_cert
32
43
  #
33
44
  # gemrc files may exist in various locations and are read and merged in
34
45
  # the following order:
@@ -193,8 +204,8 @@ class Gem::ConfigFile
193
204
  @install_extension_in_lib = DEFAULT_INSTALL_EXTENSION_IN_LIB
194
205
  @ipv4_fallback_enabled = ENV["IPV4_FALLBACK_ENABLED"] == "true" || DEFAULT_IPV4_FALLBACK_ENABLED
195
206
 
196
- operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
197
- platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
207
+ operating_system_config = Gem::Util.deep_dup(OPERATING_SYSTEM_DEFAULTS)
208
+ platform_config = Gem::Util.deep_dup(PLATFORM_DEFAULTS)
198
209
  system_config = load_file SYSTEM_WIDE_CONFIG_FILE
199
210
  user_config = load_file config_file_name
200
211
 
@@ -562,13 +573,13 @@ if you believe they were disclosed to a third party.
562
573
 
563
574
  def self.deep_transform_config_keys!(config)
564
575
  config.transform_keys! do |k|
565
- if k.match?(/\A:(.*)\Z/)
576
+ if k.match?(/\A:(.*)\z/)
566
577
  k[1..-1].to_sym
567
- elsif k.include?("__") || k.match?(%r{/\Z})
578
+ elsif k.include?("__") || k.end_with?("/")
568
579
  if k.is_a?(Symbol)
569
- k.to_s.gsub(/__/,".").gsub(%r{/\Z}, "").to_sym
580
+ k.to_s.gsub(/__/,".").delete_suffix("/").to_sym
570
581
  else
571
- k.dup.gsub(/__/,".").gsub(%r{/\Z}, "")
582
+ k.dup.gsub(/__/,".").delete_suffix("/")
572
583
  end
573
584
  else
574
585
  k
@@ -577,11 +588,11 @@ if you believe they were disclosed to a third party.
577
588
 
578
589
  config.transform_values! do |v|
579
590
  if v.is_a?(String)
580
- if v.match?(/\A:(.*)\Z/)
591
+ if v.match?(/\A:(.*)\z/)
581
592
  v[1..-1].to_sym
582
- elsif v.match?(/\A[+-]?\d+\Z/)
593
+ elsif v.match?(/\A[+-]?\d+\z/)
583
594
  v.to_i
584
- elsif v.match?(/\Atrue|false\Z/)
595
+ elsif v.match?(/\A(?:true|false)\z/)
585
596
  v == "true"
586
597
  elsif v.empty?
587
598
  nil
@@ -101,7 +101,9 @@ class Gem::Ext::Builder
101
101
 
102
102
  require "open3"
103
103
  # Set $SOURCE_DATE_EPOCH for the subprocess.
104
- build_env = { "SOURCE_DATE_EPOCH" => Gem.source_date_epoch_string }.merge(env)
104
+ # Under Ruby::Box mkmf makes RbConfig.expand recurse until SystemStackError.
105
+ # Drop $RUBY_BOX last so no caller can restore it.
106
+ build_env = { "SOURCE_DATE_EPOCH" => Gem.source_date_epoch_string }.merge(env).merge("RUBY_BOX" => nil)
105
107
  # A single-element command would be parsed as a shell command line,
106
108
  # splitting an unquoted command path containing spaces. Use the
107
109
  # [cmdname, argv0] form to keep exec semantics.
@@ -429,7 +429,7 @@ EOM
429
429
 
430
430
  if entry.symlink?
431
431
  link_target = entry.header.linkname
432
- real_destination = link_target.start_with?("/") ? link_target : File.expand_path(link_target, File.dirname(destination))
432
+ real_destination = File.expand_path(link_target, File.dirname(destination))
433
433
 
434
434
  raise Gem::Package::SymlinkError.new(full_name, real_destination, destination_dir) unless
435
435
  normalize_path(real_destination).start_with? normalize_path(destination_dir + "/")
@@ -109,9 +109,7 @@ class Gem::Security::Signer
109
109
  subject_alt_name = cert.extensions.find {|e| e.oid == "subjectAltName" }
110
110
 
111
111
  if subject_alt_name
112
- /\Aemail:/ =~ subject_alt_name.value # rubocop:disable Performance/StartWith
113
-
114
- $' || subject_alt_name.value
112
+ subject_alt_name.value.delete_prefix("email:")
115
113
  else
116
114
  cert.subject
117
115
  end
@@ -10,10 +10,14 @@ module Gem::UpdateSuggestion
10
10
  # Message to promote available RubyGems update with related gem update command.
11
11
 
12
12
  def update_suggestion
13
+ current = Gem.rubygems_version
14
+ latest = Gem.latest_rubygems_version
15
+
13
16
  <<-MESSAGE
14
17
 
15
- A new release of RubyGems is available: #{Gem.rubygems_version} → #{Gem.latest_rubygems_version}!
16
- Run `gem update --system #{Gem.latest_rubygems_version}` to update your installation.
18
+ A new release of RubyGems is available: #{current} → #{latest}!
19
+ See https://github.com/ruby/rubygems/blob/v#{latest}/CHANGELOG.md for the changes since #{current}.
20
+ Run `gem update --system #{latest}` to update your installation.
17
21
 
18
22
  MESSAGE
19
23
  end
data/lib/rubygems/util.rb CHANGED
@@ -75,15 +75,39 @@ module Gem::Util
75
75
  end
76
76
 
77
77
  ##
78
- # Globs for files matching +pattern+ inside of +directory+,
79
- # returning absolute paths to the matching files. Unlike a plain
80
- # Dir.glob with an interpolated path, glob metacharacters in
81
- # +base_path+ are not treated as part of the pattern.
78
+ # Globs for entries matching +glob+ inside of +base_path+, returning
79
+ # absolute paths to the matching files and directories. Unlike a plain
80
+ # Dir.glob with an interpolated path, glob metacharacters in +base_path+
81
+ # are not treated as part of the pattern. Matched entries are joined to
82
+ # +base_path+ literally, so an entry starting with `~` is not expanded
83
+ # into a home directory, and no other normalization is applied to them.
82
84
 
83
85
  def self.glob_files_in_dir(glob, base_path)
84
86
  expanded_path = nil
85
87
  Dir.glob(glob, base: base_path).map! do |f|
86
- File.expand_path(f, expanded_path ||= File.expand_path(base_path))
88
+ # File.join instead of File.expand_path, so that matched entries
89
+ # starting with `~` are not expanded into the home directory
90
+ File.join(expanded_path ||= File.expand_path(base_path), f)
91
+ end
92
+ end
93
+
94
+ ##
95
+ # Duplicates +obj+ without Marshal, which cannot resolve Gem:: constants from
96
+ # the root box under Ruby::Box (RUBY_BOX=1). Hashes and arrays are copied
97
+ # recursively, anything else with a plain +dup+, so an object's internals stay
98
+ # shared with the original, as are hash keys. Shared references are not
99
+ # preserved, and a cyclic +obj+ raises SystemStackError.
100
+
101
+ def self.deep_dup(obj) # :nodoc:
102
+ case obj
103
+ when Hash then obj.to_h {|k, v| [k, deep_dup(v)] }
104
+ when Array then obj.map {|e| deep_dup(e) }
105
+ else
106
+ begin
107
+ obj.dup
108
+ rescue TypeError
109
+ obj
110
+ end
87
111
  end
88
112
  end
89
113
 
@@ -22,7 +22,6 @@
22
22
 
23
23
  require_relative '../../../net-protocol/lib/net/protocol'
24
24
  require_relative '../../../uri/lib/uri'
25
- require_relative '../../../resolv/lib/resolv'
26
25
  autoload :OpenSSL, 'openssl'
27
26
 
28
27
  module Gem::Net #:nodoc:
@@ -1531,6 +1530,29 @@ module Gem::Net #:nodoc:
1531
1530
 
1532
1531
  SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc:
1533
1532
 
1533
+ # Resolv::IPv4::Regex and Resolv::IPv6::Regex, copied from resolv 0.7.1 rather
1534
+ # than required, so that net/http does not load a DNS resolver just to keep an
1535
+ # IP address literal out of the Server Name Indication.
1536
+ # https://github.com/ruby/resolv/blob/v0.7.1/lib/resolv.rb
1537
+ ipv4_octet = /0|1(?:[0-9][0-9]?)?|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?|[3-9][0-9]?/
1538
+ hex16 = /[0-9A-Fa-f]{1,4}/
1539
+ hex16_group = /(?:#{hex16}(?::#{hex16})*)?/
1540
+ dotted_quad = /\d+\.\d+\.\d+\.\d+/
1541
+ zone_id = /%[-0-9A-Za-z._~]+/
1542
+
1543
+ IPV4_ADDRESS = /\A(?:#{ipv4_octet})\.(?:#{ipv4_octet})\.(?:#{ipv4_octet})\.(?:#{ipv4_octet})\z/ # :nodoc:
1544
+
1545
+ IPV6_ADDRESS = /\A(?:
1546
+ (?:#{hex16}:){7}#{hex16} # a:b:c:d:e:f:g:h
1547
+ | #{hex16_group}::#{hex16_group} # a::b
1548
+ | (?:#{hex16}:){6}#{dotted_quad} # a:b:c:d:e:f:w.x.y.z
1549
+ | #{hex16_group}::(?:#{hex16}:)*#{dotted_quad} # a::b:w.x.y.z
1550
+ | [Ff][Ee]80(?::#{hex16}){7}#{zone_id} # fe80:b:c:d:e:f:g:h%em1
1551
+ | [Ff][Ee]80:(?:#{hex16_group}::#{hex16_group}|:#{hex16_group})?:#{hex16}#{zone_id} # fe80::b%em1
1552
+ )\z/x # :nodoc:
1553
+
1554
+ private_constant :IPV4_ADDRESS, :IPV6_ADDRESS
1555
+
1534
1556
  # Sets or returns the path to a CA certification file in PEM format.
1535
1557
  attr_accessor :ca_file
1536
1558
 
@@ -1714,7 +1736,7 @@ module Gem::Net #:nodoc:
1714
1736
 
1715
1737
  # Server Name Indication (SNI) RFC 3546/6066
1716
1738
  case @address
1717
- when Gem::Resolv::IPv4::Regex, Gem::Resolv::IPv6::Regex
1739
+ when IPV4_ADDRESS, IPV6_ADDRESS
1718
1740
  # don't set SNI, as IP addresses in SNI is not valid
1719
1741
  # per RFC 6066, section 3.
1720
1742
 
data/lib/rubygems.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  require "rbconfig"
10
10
 
11
11
  module Gem
12
- VERSION = "4.0.19"
12
+ VERSION = "4.0.21"
13
13
  end
14
14
 
15
15
  require_relative "rubygems/defaults"
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: 4.0.19
4
+ version: 4.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
@@ -661,8 +661,6 @@ files:
661
661
  - lib/rubygems/vendor/optparse/lib/optparse/time.rb
662
662
  - lib/rubygems/vendor/optparse/lib/optparse/uri.rb
663
663
  - lib/rubygems/vendor/optparse/lib/optparse/version.rb
664
- - lib/rubygems/vendor/resolv/COPYING
665
- - lib/rubygems/vendor/resolv/lib/resolv.rb
666
664
  - lib/rubygems/vendor/securerandom/COPYING
667
665
  - lib/rubygems/vendor/securerandom/lib/securerandom.rb
668
666
  - lib/rubygems/vendor/timeout/COPYING
@@ -723,7 +721,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
723
721
  - !ruby/object:Gem::Version
724
722
  version: '0'
725
723
  requirements: []
726
- rubygems_version: 3.6.9
724
+ rubygems_version: 4.0.16
727
725
  specification_version: 4
728
726
  summary: RubyGems is a package management framework for Ruby. This gem is downloaded
729
727
  and installed by `gem update --system`, so that the `gem` CLI can update itself.