commit 00a4e37e5a4f2c035627e8127391ebc1ffc42aff Author: Pavel Skrylev Date: Mon Aug 15 21:26:44 2022 +0300 feat: single instantination feature + single instantination feature allowing to optimize gem folder tree diff --git a/configure.ac b/configure.ac index 2ab04193e7..b345c3e69a 100644 --- a/configure.ac +++ b/configure.ac @@ -4182,6 +4182,12 @@ AC_ARG_WITH(cachedir, AS_HELP_STRING([--with-cachedir=DIR], [specify ruby cache dir]), [cachedir=$withval]) +single_instantiating=no +AC_ARG_ENABLE(single-instantiating, + AS_HELP_STRING([--enable-single-instantiating], [enable single ruby versions in tree]), + [single_instantiating=$enableval], [single_instantiating=no]) +AC_SUBST(single_instantiating)dnl + AC_SUBST(rubyhdrdir)dnl AC_SUBST(sitehdrdir)dnl AC_SUBST(vendorhdrdir)dnl diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 5dd2bfe88d..9f519b6a2a 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -223,6 +223,13 @@ def initialize(args) handle_arguments args end + ## + # Has the ruby build single instantiated, defaulting to false/nil + + def single_instantiating? + @single_instantiating ||= RbConfig::CONFIG["single_instantiating"] == 'yes' + end + ## # Hash of RubyGems.org and alternate API keys diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index d9f7fab1e8..228748fe57 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -38,7 +38,14 @@ def self.default_spec_cache_dir # specified in the environment def self.default_dir - @default_dir ||= File.join(RbConfig::CONFIG['rubylibprefix'], 'gems', RbConfig::CONFIG['ruby_version']) + subpath = if Gem.configuration.single_instantiating? + ['gemie'] + else + ['gems', RbConfig::CONFIG['ruby_version']] + end + path = [RbConfig::CONFIG['rubylibprefix']] + subpath + + @default_dir ||= File.join(*path) end ## @@ -49,7 +56,18 @@ def self.default_dir # Ruby counterparts, therefore nil is returned def self.default_ext_dir_for(base_dir) - nil + if Gem.configuration.single_instantiating? + parts = + if base_dir.nil? + [RbConfig::CONFIG['rubyarchdir'], 'gemie'] + elsif base_dir[0...RbConfig::CONFIG['rubylibprefix'].size] == RbConfig::CONFIG['rubylibprefix'] + [RbConfig::CONFIG['rubyarchdir'], base_dir[RbConfig::CONFIG['rubylibprefix'].size..-1]] + else + [base_dir, 'gemie'] + end + ['extensions'] + + File.join(parts) + end end ## @@ -81,7 +81,12 @@ module Gem # Path to specification files of default gems. def self.default_specifications_dir - @default_specifications_dir ||= File.join(Gem.default_dir, "specifications", "default") + @default_specifications_dir ||= + if Gem.configuration.single_instantiating? + File.join(RbConfig::CONFIG['rubylibprefix'], "specifications") + else + File.join(Gem.default_dir, "specifications", "default") + end end ## @@ -237,8 +255,13 @@ def self.vendor_dir # :nodoc: return nil unless RbConfig::CONFIG.key? 'vendordir' - File.join RbConfig::CONFIG['vendordir'], 'gems', - RbConfig::CONFIG['ruby_version'] + subpath = if Gem.configuration.single_instantiating? + ['gemie'] + else + ['gems', RbConfig::CONFIG['ruby_version']] + end + + File.join RbConfig::CONFIG['vendordir'], *subpath end ## diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index b3b63b51aa..e77a316012 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -190,7 +190,12 @@ def to_fullpath(path) # eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0 def gem_dir - @gem_dir ||= File.expand_path File.join(gems_dir, full_name) + @gem_dir ||= + if default_gem? + File.expand_path(gems_dir) + else + File.expand_path File.join(gems_dir, full_name) + end end ## diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index cb8ee063b4..168a3060b1 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1915,7 +1920,12 @@ def gem_dir # :nodoc: end def gems_dir - @gems_dir ||= File.join(base_dir, "gems") + @gems_dir ||= + if default_gem? + base_dir + else + File.join(base_dir, "gems") + end end ## @@ -2032,7 +2032,7 @@ def initialize_copy(other_spec) def base_dir return Gem.dir unless loaded_from - @base_dir ||= if default_gem? + @base_dir ||= if !Gem.configuration.single_instantiating? && default_gem? File.dirname File.dirname File.dirname loaded_from else File.dirname File.dirname loaded_from --- a/template/ruby.pc.in 2022-08-15 22:32:35.948000000 +0000 +++ b/template/ruby.pc.in 2022-08-16 10:29:49.008000000 +0000 @@ -23,6 +23,7 @@ sitearchincludedir=@sitearchincludedir@ rubylibprefix=@rubylibprefix@ rubyarchprefix=@rubyarchprefix@ use_system_dirs=@use_system_dirs@ +single_instantiating=@single_instantiating@ rubysitearchprefix=@rubysitearchprefix@ rubylibdir=@rubylibdir@ vendordir=@vendordir@