From 37cd8547d23973a7ec23a004ab9b60738d67ada9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Thu, 3 Nov 2011 16:43:05 +0100 Subject: [PATCH] Add dedicate extensions folder into $LOAD_PATH. --- lib/rubygems/basic_specification.rb | 35 ++++++++++++++++++++++++++++++++--- lib/rubygems/defaults.rb | 11 +++++++++++ lib/rubygems/ext/builder.rb | 6 +++++- lib/rubygems/installer.rb | 1 + lib/rubygems/specification.rb | 7 +++++++ lib/rubygems/uninstaller.rb | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index a10eab3..da3af91 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -51,6 +51,14 @@ class Gem::BasicSpecification File.dirname(loaded_from) == self.class.default_specifications_dir end + ## + # Returns the full path to the exts directory containing this spec's + # gem directory. eg: /usr/local/lib/ruby/1.8/exts + + def exts_dir + @exts_dir ||= Gem.default_ext_dir_for(base_dir) || gems_dir + end + def find_full_gem_path # :nodoc: # TODO: also, shouldn't it default to full_name if it hasn't been written? path = File.expand_path File.join(gems_dir, full_name) @@ -60,6 +68,15 @@ class Gem::BasicSpecification private :find_full_gem_path + def find_full_gem_ext_path # :nodoc: + # TODO: skip for gems without extensions. + path = File.expand_path File.join(exts_dir, full_name) + path.untaint + path if File.directory? path + end + + private :find_full_gem_ext_path + ## # The full path to the gem (install path + full name). @@ -70,6 +87,13 @@ class Gem::BasicSpecification end ## + # The full path to the gem binary extension (install path + full name). + + def full_gem_ext_path + @full_gem_ext_path ||= find_full_gem_ext_path + end + + ## # Returns the full name (name-version) of this Gem. Platform information # is included (name-version-platform) if it is specified and not the # default Ruby platform. @@ -88,9 +112,12 @@ class Gem::BasicSpecification # def full_require_paths - require_paths.map do |path| - File.join full_gem_path, path - end + require_paths.map do |require_path| + full_gem_paths = [full_gem_path, full_gem_ext_path] + full_gem_paths.compact! + + full_gem_paths.map { |path| File.join path, require_path } + end.flatten end ## @@ -110,7 +137,9 @@ class Gem::BasicSpecification @loaded_from = path && path.to_s @full_gem_path = nil + @full_gem_ext_path = nil @gems_dir = nil + @exts_dir = nil @base_dir = nil end diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 591580b..8ed474f 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -111,6 +111,17 @@ module Gem end ## + # Returns binary extensions dir for specified RubyGems base dir or nil + # if such directory cannot be determined. + # + # By default, the binary extensions are located side by side with their + # Ruby counterparts, therefore nil is returned + + def self.default_ext_dir_for base_dir + nil + end + + ## # A wrapper around RUBY_ENGINE const that may not be defined def self.ruby_engine diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index 8c05723..75d5fc2 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -170,7 +170,7 @@ EOF say "This could take a while..." end - dest_path = File.join @gem_dir, @spec.require_paths.first + dest_path = File.join(@only_install_dir ? @gem_dir : @spec.ext_dir, @spec.require_paths.first) @ran_rake = false # only run rake once @@ -181,5 +181,9 @@ EOF end end + def only_install_dir= only_install_dir + @only_install_dir = only_install_dir + end + end diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 261af89..a6aca5d 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -662,6 +662,7 @@ TEXT def build_extensions builder = Gem::Ext::Builder.new spec, @build_args + builder.only_install_dir = @only_install_dir builder.build_extensions end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index deac343..b630fa3 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1612,6 +1612,13 @@ class Gem::Specification < Gem::BasicSpecification @executables = Array(value) end + # Returns the full path to this spec's ext directory. + # eg: /usr/local/lib/ruby/1.8/exts/mygem-1.0 + + def ext_dir + @ext_dir ||= File.expand_path File.join(exts_dir, full_name) + end + ## # Sets extensions to +extensions+, ensuring it is an array. Don't # use this, push onto the array instead. diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb index 143ab6d..f81a23d 100644 --- a/lib/rubygems/uninstaller.rb +++ b/lib/rubygems/uninstaller.rb @@ -247,6 +247,7 @@ class Gem::Uninstaller File.writable?(spec.base_dir) FileUtils.rm_rf spec.full_gem_path + FileUtils.rm_rf spec.ext_dir # TODO: should this be moved to spec?... I vote eww (also exists in docmgr) old_platform_name = [spec.name, -- 1.8.3.1