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