cd5466
From e80e7a3d0b3d72f7af7286b935702b3fab117008 Mon Sep 17 00:00:00 2001
cd5466
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
cd5466
Date: Wed, 8 Dec 2021 21:12:24 +0100
cd5466
Subject: [PATCH 1/5] More explicit require
cd5466
cd5466
This class does not use `rubygems/deprecate`. It uses
cd5466
`rubygems/version`, which in turn uses `rubygems/deprecate`. Make this
cd5466
explicit.
cd5466
---
cd5466
 lib/rubygems/requirement.rb | 2 +-
cd5466
 1 file changed, 1 insertion(+), 1 deletion(-)
cd5466
cd5466
diff --git a/lib/rubygems/requirement.rb b/lib/rubygems/requirement.rb
cd5466
index d2e28fab5b4..9edd6aa7d3c 100644
cd5466
--- a/lib/rubygems/requirement.rb
cd5466
+++ b/lib/rubygems/requirement.rb
cd5466
@@ -1,5 +1,5 @@
cd5466
 # frozen_string_literal: true
cd5466
-require_relative "deprecate"
cd5466
+require_relative "version"
cd5466
 
cd5466
 ##
cd5466
 # A Requirement is a set of one or more version restrictions. It supports a
cd5466
cd5466
From 4e46dcc17ee5cabbde43b8a34063b8ab042536f9 Mon Sep 17 00:00:00 2001
cd5466
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
cd5466
Date: Wed, 8 Dec 2021 21:17:30 +0100
cd5466
Subject: [PATCH 2/5] Remove ineffective autoloads
cd5466
cd5466
These files are loaded on startup unconditionally, so we can require
cd5466
them relatively when needed.
cd5466
---
cd5466
 lib/rubygems.rb               | 4 +---
cd5466
 lib/rubygems/specification.rb | 2 ++
cd5466
 2 files changed, 3 insertions(+), 3 deletions(-)
cd5466
cd5466
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
cd5466
index f803e47628e..b8747409304 100644
cd5466
--- a/lib/rubygems.rb
cd5466
+++ b/lib/rubygems.rb
cd5466
@@ -1310,19 +1310,17 @@ def default_gem_load_paths
cd5466
   autoload :Licenses,           File.expand_path('rubygems/util/licenses', __dir__)
cd5466
   autoload :NameTuple,          File.expand_path('rubygems/name_tuple', __dir__)
cd5466
   autoload :PathSupport,        File.expand_path('rubygems/path_support', __dir__)
cd5466
-  autoload :Platform,           File.expand_path('rubygems/platform', __dir__)
cd5466
   autoload :RequestSet,         File.expand_path('rubygems/request_set', __dir__)
cd5466
-  autoload :Requirement,        File.expand_path('rubygems/requirement', __dir__)
cd5466
   autoload :Resolver,           File.expand_path('rubygems/resolver', __dir__)
cd5466
   autoload :Source,             File.expand_path('rubygems/source', __dir__)
cd5466
   autoload :SourceList,         File.expand_path('rubygems/source_list', __dir__)
cd5466
   autoload :SpecFetcher,        File.expand_path('rubygems/spec_fetcher', __dir__)
cd5466
-  autoload :Specification,      File.expand_path('rubygems/specification', __dir__)
cd5466
   autoload :Util,               File.expand_path('rubygems/util', __dir__)
cd5466
   autoload :Version,            File.expand_path('rubygems/version', __dir__)
cd5466
 end
cd5466
 
cd5466
 require_relative 'rubygems/exceptions'
cd5466
+require_relative 'rubygems/specification'
cd5466
 
cd5466
 # REFACTOR: This should be pulled out into some kind of hacks file.
cd5466
 begin
cd5466
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
cd5466
index d3b96491a28..dc5e5ba0138 100644
cd5466
--- a/lib/rubygems/specification.rb
cd5466
+++ b/lib/rubygems/specification.rb
cd5466
@@ -9,6 +9,8 @@
cd5466
 require_relative 'deprecate'
cd5466
 require_relative 'basic_specification'
cd5466
 require_relative 'stub_specification'
cd5466
+require_relative 'platform'
cd5466
+require_relative 'requirement'
cd5466
 require_relative 'specification_policy'
cd5466
 require_relative 'util/list'
cd5466
 
cd5466
cd5466
From 96b6b3e04e8e4fec17f63079a0caf999a2709d71 Mon Sep 17 00:00:00 2001
cd5466
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
cd5466
Date: Wed, 8 Dec 2021 21:45:16 +0100
cd5466
Subject: [PATCH 3/5] Load `operating_system.rb` customizations before setting
cd5466
 up default gems
cd5466
cd5466
It's very common for packagers to configure gem paths in this file, for
cd5466
example, `Gem.default_dir`. Also, setting up default gems requires these
cd5466
paths to be set, so that we know which default gems need to be setup.
cd5466
cd5466
If we setup default gems before loading `operatin_system.rb`
cd5466
customizations, the wrong default gems will be setup.
cd5466
cd5466
Unfortunately, default gems loaded by `operating_system.rb` can't be
cd5466
upgraded if we do this, but it seems much of a smaller issue. I wasn't
cd5466
even fully sure it was the right thing to do when I added that, and it
cd5466
was not the culprit of the end user issue that led to making that
cd5466
change.
cd5466
---
cd5466
 lib/rubygems.rb                | 32 ++++++++++++++++----------------
cd5466
 test/rubygems/test_rubygems.rb | 23 +++++++++++++++++++++++
cd5466
 2 files changed, 39 insertions(+), 16 deletions(-)
cd5466
cd5466
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
cd5466
index b8747409304..11474b6554c 100644
cd5466
--- a/lib/rubygems.rb
cd5466
+++ b/lib/rubygems.rb
cd5466
@@ -1323,22 +1323,6 @@ def default_gem_load_paths
cd5466
 require_relative 'rubygems/specification'
cd5466
 
cd5466
 # REFACTOR: This should be pulled out into some kind of hacks file.
cd5466
-begin
cd5466
-  ##
cd5466
-  # Defaults the Ruby implementation wants to provide for RubyGems
cd5466
-
cd5466
-  require "rubygems/defaults/#{RUBY_ENGINE}"
cd5466
-rescue LoadError
cd5466
-end
cd5466
-
cd5466
-##
cd5466
-# Loads the default specs.
cd5466
-Gem::Specification.load_defaults
cd5466
-
cd5466
-require_relative 'rubygems/core_ext/kernel_gem'
cd5466
-require_relative 'rubygems/core_ext/kernel_require'
cd5466
-require_relative 'rubygems/core_ext/kernel_warn'
cd5466
-
cd5466
 begin
cd5466
   ##
cd5466
   # Defaults the operating system (or packager) wants to provide for RubyGems.
cd5466
@@ -1354,3 +1338,19 @@ def default_gem_load_paths
cd5466
     "the problem and ask for help."
cd5466
   raise e.class, msg
cd5466
 end
cd5466
+
cd5466
+begin
cd5466
+  ##
cd5466
+  # Defaults the Ruby implementation wants to provide for RubyGems
cd5466
+
cd5466
+  require "rubygems/defaults/#{RUBY_ENGINE}"
cd5466
+rescue LoadError
cd5466
+end
cd5466
+
cd5466
+##
cd5466
+# Loads the default specs.
cd5466
+Gem::Specification.load_defaults
cd5466
+
cd5466
+require_relative 'rubygems/core_ext/kernel_gem'
cd5466
+require_relative 'rubygems/core_ext/kernel_require'
cd5466
+require_relative 'rubygems/core_ext/kernel_warn'
cd5466
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
cd5466
index 493b9fdf4a3..fa77a299322 100644
cd5466
--- a/test/rubygems/test_rubygems.rb
cd5466
+++ b/test/rubygems/test_rubygems.rb
cd5466
@@ -22,6 +22,29 @@ def test_operating_system_other_exceptions
cd5466
     "the problem and ask for help."
cd5466
   end
cd5466
 
cd5466
+  def test_operating_system_customizing_default_dir
cd5466
+    pend "does not apply to truffleruby" if RUBY_ENGINE == 'truffleruby'
cd5466
+    pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == 'jruby'
cd5466
+
cd5466
+    # On a non existing default dir, there should be no gems
cd5466
+
cd5466
+    path = util_install_operating_system_rb <<-RUBY
cd5466
+      module Gem
cd5466
+        def self.default_dir
cd5466
+          File.expand_path("foo")
cd5466
+        end
cd5466
+      end
cd5466
+    RUBY
cd5466
+
cd5466
+    output = Gem::Util.popen(
cd5466
+      *ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
cd5466
+      '-e',
cd5466
+      "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)",
cd5466
+      {:err => [:child, :out]}
cd5466
+    ).strip
cd5466
+    assert_empty output
cd5466
+  end
cd5466
+
cd5466
   private
cd5466
 
cd5466
   def util_install_operating_system_rb(content)
cd5466
cd5466
From 52cfdd14fd1213a97aac12f01177e27779de9035 Mon Sep 17 00:00:00 2001
cd5466
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
cd5466
Date: Thu, 9 Dec 2021 06:08:31 +0100
cd5466
Subject: [PATCH 4/5] Install default fiddle on latest ruby on specs that need
cd5466
 it
cd5466
cd5466
Otherwise first OS customizations load and activate that fiddle version,
cd5466
but then when we change to `Gem.default_dir`, that fiddle version is no
cd5466
longer there.
cd5466
---
cd5466
 spec/bundler/commands/clean_spec.rb          | 2 +-
cd5466
 spec/bundler/install/gems/standalone_spec.rb | 2 +-
cd5466
 2 files changed, 2 insertions(+), 2 deletions(-)
cd5466
cd5466
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
cd5466
index ffaf22dbb32..65231b35fac 100644
cd5466
--- a/spec/bundler/commands/clean_spec.rb
cd5466
+++ b/spec/bundler/commands/clean_spec.rb
cd5466
@@ -638,7 +638,7 @@ def should_not_have_gems(*gems)
cd5466
       s.executables = "irb"
cd5466
     end
cd5466
 
cd5466
-    realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
cd5466
+    realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1"
cd5466
 
cd5466
     install_gemfile <<-G
cd5466
       source "#{file_uri_for(gem_repo2)}"
cd5466
diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb
cd5466
index db16a1b0e13..faefda25f45 100644
cd5466
--- a/spec/bundler/install/gems/standalone_spec.rb
cd5466
+++ b/spec/bundler/install/gems/standalone_spec.rb
cd5466
@@ -113,7 +113,7 @@
cd5466
       skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2
cd5466
       skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
cd5466
 
cd5466
-      realworld_system_gems "fiddle --version 1.0.6", "tsort --version 0.1.0"
cd5466
+      realworld_system_gems "fiddle --version 1.0.8", "tsort --version 0.1.0"
cd5466
 
cd5466
       necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "yaml --version 0.1.1", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.0.0"]
cd5466
       necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.3.a")
cd5466
cd5466
From c6a9c81021092c9157f5616a2bbe1323411a5bf8 Mon Sep 17 00:00:00 2001
cd5466
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@riseup.net>
cd5466
Date: Thu, 9 Dec 2021 12:46:23 +0100
cd5466
Subject: [PATCH 5/5] Resolve symlinks in LOAD_PATH when activating
cd5466
 pre-required default gems
cd5466
cd5466
Some double load issues were reported a while ago by OS packagers where
cd5466
if a gem has been required before rubygems, and then after, rubygems
cd5466
require would cause a double load.
cd5466
cd5466
We avoid this issue by activating the corresponding gem if we detect
cd5466
that a file in the default LOAD_PATH that belongs to a default gem has
cd5466
already been required when rubygems registers default gems.
cd5466
cd5466
However, the fix does not take into account that the default LOAD_PATH
cd5466
could potentially include symlinks. This change fixes the same double
cd5466
load issue described above but for situations where the default
cd5466
LOAD_PATH includes symlinks.
cd5466
---
cd5466
 lib/rubygems.rb | 7 ++++++-
cd5466
 1 file changed, 6 insertions(+), 1 deletion(-)
cd5466
cd5466
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
cd5466
index 11474b6554c..b7dda38d522 100644
cd5466
--- a/lib/rubygems.rb
cd5466
+++ b/lib/rubygems.rb
cd5466
@@ -1293,7 +1293,12 @@ def already_loaded?(file)
cd5466
     end
cd5466
 
cd5466
     def default_gem_load_paths
cd5466
-      @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1]
cd5466
+      @default_gem_load_paths ||= $LOAD_PATH[load_path_insert_index..-1].map do |lp|
cd5466
+        expanded = File.expand_path(lp)
cd5466
+        next expanded unless File.exist?(expanded)
cd5466
+
cd5466
+        File.realpath(expanded)
cd5466
+      end
cd5466
     end
cd5466
   end
cd5466