pvalena / rpms / ruby

Forked from rpms/ruby 2 years ago
Clone
Blob Blame History Raw
From 37cd8547d23973a7ec23a004ab9b60738d67ada9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
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