aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--gem_prelude.rb186
-rw-r--r--lib/rubygems.rb35
-rw-r--r--lib/rubygems/installer.rb9
-rw-r--r--lib/rubygems/platform.rb9
-rw-r--r--lib/rubygems/require_paths_builder.rb15
-rw-r--r--test/rubygems/gemutilities.rb15
-rw-r--r--test/rubygems/test_gem_installer.rb11
-rw-r--r--test/rubygems/test_gem_platform.rb2
9 files changed, 254 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 4194ff2a56..1a54a045e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Nov 25 12:12:03 2007 Eric Hodel <drbrain@segment7.net>
+
+ * gem_prelude.rb: Import fast-loading gem_prelude.rb from RubyGems.
+
+ * lib/rubygems*: Import RubyGems r1516.
+
Fri Nov 23 17:34:24 2007 Koichi Sasada <ko1@atdot.net>
* io.c: add rb_read_internal() as blocking function.
diff --git a/gem_prelude.rb b/gem_prelude.rb
index 7340efcaaf..997dae4699 100644
--- a/gem_prelude.rb
+++ b/gem_prelude.rb
@@ -1,10 +1,182 @@
# empty gem_prelude.rb
#
# p Gem::Enable
-# p RbConfig::CONFIG["arch"]
-# p RbConfig::CONFIG["bindir"]
-# p RbConfig::CONFIG["datadir"]
-# p RbConfig::CONFIG["sitedir"]
-# p RbConfig::CONFIG["sitelibdir"]
-# p RbConfig::CONFIG["EXEEXT"]
-# p RbConfig::CONFIG["RUBY_SO_NAME"]
+
+if defined?(Gem::Enable) && Gem::Enable
+#t = Time.now
+
+module Kernel
+
+ def gem(gem_name, *version_requirements)
+ Gem.push_gem_version_on_load_path(gem_name, *version_requirements)
+ end
+
+end
+
+module Gem
+
+ ConfigMap = {
+ :sitedir => RbConfig::CONFIG["sitedir"],
+ :ruby_version => RbConfig::CONFIG["ruby_version"],
+ :libdir => RbConfig::CONFIG["libdir"],
+ :sitelibdir => RbConfig::CONFIG["sitelibdir"],
+ :arch => RbConfig::CONFIG["arch"],
+ :bindir => RbConfig::CONFIG["bindir"],
+ :EXEEXT => RbConfig::CONFIG["EXEEXT"],
+ :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
+ :ruby_install_name => RbConfig::CONFIG["ruby_install_name"]
+ }
+
+ class << self
+
+ def default_dir
+ if defined? RUBY_FRAMEWORK_VERSION
+ return File.join(File.dirname(ConfigMap[:sitedir]), "Gems")
+ else
+ File.join(ConfigMap[:libdir], 'ruby', 'gems', ConfigMap[:ruby_version])
+ end
+ end
+
+ def dir
+ @gem_home ||= nil
+ set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
+ @gem_home
+ end
+
+ def path
+ @gem_path ||= nil
+ unless @gem_path
+ paths = [ENV['GEM_PATH']]
+ paths << APPLE_GEM_HOME if defined? APPLE_GEM_HOME
+ set_paths(paths.compact.join(File::PATH_SEPARATOR))
+ end
+ @gem_path
+ end
+
+ # Set the Gem home directory (as reported by +dir+).
+ def set_home(home)
+ @gem_home = home
+ ensure_gem_subdirectories(@gem_home)
+ end
+
+ def set_paths(gpaths)
+ if gpaths
+ @gem_path = gpaths.split(File::PATH_SEPARATOR)
+ @gem_path << Gem.dir
+ else
+ @gem_path = [Gem.dir]
+ end
+ @gem_path.uniq!
+ @gem_path.each do |gp| ensure_gem_subdirectories(gp) end
+ end
+
+ def ensure_gem_subdirectories(path)
+ end
+
+ end
+
+ module QuickLoader
+
+ class << self
+ def load_full_rubygems_library
+ QuickLoader.instance_methods.each {|method_name| QuickLoader.send(:undef_method, method_name)}
+ load "rubygems.rb"
+ end
+ end
+
+ GemPaths = {}
+ GemVersions = {}
+
+ def push_gem_version_on_load_path(gem_name, *version_requirements)
+ if version_requirements.empty?
+ unless GemPaths.has_key?(gem_name)
+ raise LoadError.new("Could not find RubyGem #{gem_name} (>= 0)\n")
+ end
+ # highest version gems already active
+ return false
+ else
+ if version_requirements.length > 1
+ QuickLoader.load_full_rubygems_library
+ return gem(gem_name, *version_requirements)
+ end
+ requirement, version = version_requirements[0].split
+ requirement.strip!
+ if requirement == ">" || requirement == ">="
+ if (GemVersions[gem_name] <=> Gem.calculate_integers_for_gem_version(version)) >= 0
+ return false
+ end
+ elsif requirement == "~>"
+ loaded_version = GemVersions[gem_name]
+ required_version = Gem.calculate_integers_for_gem_version(version)
+ if loaded_version && (loaded_version[0] == required_version[0])
+ return false
+ end
+ end
+ QuickLoader.load_full_rubygems_library
+ gem(gem_name, *version_requirements)
+ end
+ end
+
+ def calculate_integers_for_gem_version(gem_version)
+ numbers = gem_version.split(".").collect {|n| n.to_i}
+ numbers.pop while numbers.last == 0
+ numbers << 0 if numbers.empty?
+ numbers
+ end
+
+ def push_all_highest_version_gems_on_load_path
+ Gem.path.each do |path|
+ gems_directory = File.join(path, "gems")
+ if File.exist?(gems_directory)
+ Dir.entries(gems_directory).each do |gem_directory_name|
+ next if gem_directory_name == "." || gem_directory_name == ".."
+ dash = gem_directory_name.rindex("-")
+ gem_name = gem_directory_name[0...dash]
+ current_version = GemVersions[gem_name]
+ new_version = calculate_integers_for_gem_version(gem_directory_name[dash+1..-1])
+ if current_version
+ if (current_version <=> new_version) == -1
+ GemVersions[gem_name] = new_version
+ GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)
+ end
+ else
+ GemVersions[gem_name] = new_version
+ GemPaths[gem_name] = File.join(gems_directory, gem_directory_name)
+ end
+ end
+ end
+ end
+ require_paths = []
+ GemPaths.values.each do |path|
+ if File.exist?(File.join(path, ".require_paths"))
+ require_paths.concat(File.read(File.join(path, ".require_paths")).split.map {|require_path| File.join(path, require_path)})
+ else
+ require_paths << File.join(path, "lib") if File.exist?(File.join(path, "lib"))
+ require_paths << File.join(path, "bin") if File.exist?(File.join(path, "bin"))
+ end
+ end
+
+ # gem directories must come after -I and ENV['RUBYLIB']
+ $:[$:.index(ConfigMap[:sitelibdir]),0] = require_paths
+ end
+
+ def const_missing(constant)
+ QuickLoader.load_full_rubygems_library
+ Gem.const_get(constant)
+ end
+
+ def method_missing(method, *args, &block)
+ QuickLoader.load_full_rubygems_library
+ Gem.send(method, *args, &block)
+ end
+ end
+
+ extend QuickLoader
+
+end
+
+Gem.push_all_highest_version_gems_on_load_path
+$".unshift File.join(Gem::ConfigMap[:libdir], "ruby", Gem::ConfigMap[:ruby_version], "rubygems.rb")
+
+#puts "Gem load in #{Time.now - t} seconds"
+end # Gem::Enable \ No newline at end of file
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 184461b4d0..f233b520f1 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -5,7 +5,6 @@
# See LICENSE.txt for permissions.
#++
-require 'rbconfig'
require 'rubygems/rubygems_version'
require 'thread'
@@ -82,11 +81,25 @@ end
#
module Gem
+ ConfigMap = {} unless defined?(ConfigMap)
+ require 'rbconfig'
+ ConfigMap.merge!(
+ :sitedir => RbConfig::CONFIG["sitedir"],
+ :ruby_version => RbConfig::CONFIG["ruby_version"],
+ :libdir => RbConfig::CONFIG["libdir"],
+ :sitelibdir => RbConfig::CONFIG["sitelibdir"],
+ :arch => RbConfig::CONFIG["arch"],
+ :bindir => RbConfig::CONFIG["bindir"],
+ :EXEEXT => RbConfig::CONFIG["EXEEXT"],
+ :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
+ :ruby_install_name => RbConfig::CONFIG["ruby_install_name"]
+ )
+
MUTEX = Mutex.new
RubyGemsPackageVersion = RubyGemsVersion
- DIRECTORIES = %w[cache doc gems specifications]
+ DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
@@source_index = nil
@@win_platform = nil
@@ -120,7 +133,7 @@ module Gem
def self.prefix
prefix = File.dirname File.expand_path(__FILE__)
- if prefix == Config::CONFIG['sitelibdir'] then
+ if prefix == ConfigMap[:sitelibdir] then
nil
else
File.dirname prefix
@@ -221,7 +234,7 @@ module Gem
if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
'/usr/bin'
else # generic install
- Config::CONFIG['bindir']
+ ConfigMap[:bindir]
end
end
@@ -280,9 +293,9 @@ module Gem
# Return the Ruby command to use to execute the Ruby interpreter.
def ruby
if @ruby.nil? then
- @ruby = File.join(Config::CONFIG['bindir'],
- Config::CONFIG['ruby_install_name'])
- @ruby << Config::CONFIG['EXEEXT']
+ @ruby = File.join(ConfigMap[:bindir],
+ ConfigMap[:ruby_install_name])
+ @ruby << ConfigMap[:EXEEXT]
end
@ruby
@@ -342,7 +355,7 @@ module Gem
File.join spec.full_gem_path, path
end
- sitelibdir = Config::CONFIG['sitelibdir']
+ sitelibdir = ConfigMap[:sitelibdir]
# gem directories must come after -I and ENV['RUBYLIB']
$:.insert($:.index(sitelibdir), *require_paths)
@@ -529,9 +542,9 @@ module Gem
# not specified in the environment.
def default_dir
if defined? RUBY_FRAMEWORK_VERSION
- return File.join(File.dirname(Config::CONFIG["sitedir"]), "Gems", Config::CONFIG['ruby_version'])
+ return File.join(File.dirname(ConfigMap[:sitedir]), "Gems", ConfigMap[:ruby_version])
else
- File.join(Config::CONFIG['libdir'], 'ruby', 'gems', Config::CONFIG['ruby_version'])
+ File.join(ConfigMap[:libdir], 'ruby', 'gems', ConfigMap[:ruby_version])
end
end
@@ -549,7 +562,7 @@ module Config # :nodoc:
# Return the path to the data directory associated with the named
# package. If the package is loaded as a gem, return the gem
# specific data directory. Otherwise return a path to the share
- # area as define by "#{Config::CONFIG['datadir']}/#{package_name}".
+ # area as define by "#{ConfigMap[:datadir]}/#{package_name}".
def datadir(package_name)
Gem.datadir(package_name) || Config.gem_original_datadir(package_name)
end
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 03f7c92828..46d0144a88 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -10,6 +10,7 @@ require 'rbconfig'
require 'rubygems/format'
require 'rubygems/ext'
+require 'rubygems/require_paths_builder'
##
# The installer class processes RubyGem .gem files and installs the
@@ -27,6 +28,8 @@ class Gem::Installer
class ExtensionBuildError < Gem::InstallError; end
include Gem::UserInteraction
+
+ include Gem::RequirePathsBuilder
##
# Constructs an Installer instance that will install the gem located at
@@ -111,6 +114,8 @@ class Gem::Installer
generate_bin
build_extensions
write_spec
+
+ write_require_paths_file_if_needed
# HACK remove? Isn't this done in multiple places?
cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
@@ -235,8 +240,8 @@ class Gem::Installer
# the symlink if the gem being installed has a newer version.
#
def generate_bin_symlink(filename, bindir)
- if Config::CONFIG["arch"] =~ /dos|win32/i then
- alert_warning "Unable to use symlinks on win32, installing wrapper"
+ if Gem.win_platform? then
+ alert_warning "Unable to use symlinks on Windows, installing wrapper"
generate_bin_script filename, bindir
return
end
diff --git a/lib/rubygems/platform.rb b/lib/rubygems/platform.rb
index 24081d4fec..496c4b1fb8 100644
--- a/lib/rubygems/platform.rb
+++ b/lib/rubygems/platform.rb
@@ -13,7 +13,7 @@ class Gem::Platform
attr_accessor :version
def self.local
- arch = Config::CONFIG['arch']
+ arch = Gem::ConfigMap[:arch]
arch = "#{arch}_60" if arch =~ /mswin32$/
@local ||= new(arch)
end
@@ -27,6 +27,8 @@ class Gem::Platform
def self.new(arch) # :nodoc:
case arch
+ when Gem::Platform::CURRENT then
+ Gem::Platform.local
when Gem::Platform::RUBY, nil, '' then
Gem::Platform::RUBY
else
@@ -71,7 +73,10 @@ class Gem::Platform
when /^java([\d.]*)/ then [ 'java', $1 ]
when /linux/ then [ 'linux', $1 ]
when /mingw32/ then [ 'mingw32', nil ]
- when /(mswin\d+)(\_(\d+))?/ then [ $1, $3 ]
+ when /(mswin\d+)(\_(\d+))?/ then
+ os, version = $1, $3
+ @cpu = 'x86' if @cpu.nil? and os =~ /32$/
+ [os, version]
when /netbsdelf/ then [ 'netbsdelf', nil ]
when /openbsd(\d+\.\d+)/ then [ 'openbsd', $1 ]
when /solaris(\d+\.\d+)/ then [ 'solaris', $1 ]
diff --git a/lib/rubygems/require_paths_builder.rb b/lib/rubygems/require_paths_builder.rb
new file mode 100644
index 0000000000..fe4f593bf4
--- /dev/null
+++ b/lib/rubygems/require_paths_builder.rb
@@ -0,0 +1,15 @@
+module Gem
+ module RequirePathsBuilder
+ def write_require_paths_file_if_needed(spec = @spec, gem_home = @gem_home)
+ return if spec.require_paths == ["lib"] && (spec.bindir.nil? || spec.bindir == "bin")
+ file_name = File.join(gem_home, 'gems', "#{@spec.full_name}", ".require_paths")
+ file_name.untaint
+ File.open(file_name, "w") do |file|
+ spec.require_paths.each do |path|
+ file.puts path
+ end
+ file.puts spec.bindir if spec.bindir
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/test/rubygems/gemutilities.rb b/test/rubygems/gemutilities.rb
index 0d5ab0297a..bb54ff6362 100644
--- a/test/rubygems/gemutilities.rb
+++ b/test/rubygems/gemutilities.rb
@@ -8,7 +8,7 @@
at_exit { $SAFE = 1 }
require 'fileutils'
-require 'test/unit/testcase'
+require 'test/unit'
require 'tmpdir'
require 'uri'
require 'rubygems/gem_open_uri'
@@ -20,6 +20,10 @@ module Gem
def self.source_index=(si)
@@source_index = si
end
+
+ def self.win_platform=(val)
+ @@win_platform = val
+ end
end
class FakeFetcher
@@ -58,7 +62,8 @@ class RubyGemTestCase < Test::Unit::TestCase
include Gem::DefaultUserInteraction
- undef_method :default_test
+ undef_method :default_test if instance_methods.include? 'default_test' or
+ instance_methods.include? :default_test
def setup
super
@@ -84,7 +89,7 @@ class RubyGemTestCase < Test::Unit::TestCase
@gem_repo = "http://gems.example.com"
Gem.sources.replace [@gem_repo]
- @orig_arch = Config::CONFIG['arch']
+ @orig_arch = Gem::ConfigMap[:arch]
if win_platform?
util_set_arch 'i386-mswin32'
@@ -96,7 +101,7 @@ class RubyGemTestCase < Test::Unit::TestCase
end
def teardown
- Config::CONFIG['arch'] = @orig_arch
+ Gem::ConfigMap[:arch] = @orig_arch
if defined? Gem::RemoteFetcher then
Gem::RemoteFetcher.instance_variable_set :@fetcher, nil
@@ -228,7 +233,7 @@ class RubyGemTestCase < Test::Unit::TestCase
# Set the platform to +cpu+ and +os+
def util_set_arch(arch)
- Config::CONFIG['arch'] = arch
+ Gem::ConfigMap[:arch] = arch
platform = Gem::Platform.new arch
Gem.instance_variable_set :@platforms, nil
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index 05e38f67f8..9a091a291e 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -417,8 +417,8 @@ load 'my_exec'
end
def test_generate_bin_symlinks_win32
- old_arch = Config::CONFIG["arch"]
- Config::CONFIG["arch"] = "win32"
+ old_win_platform = Gem.win_platform?
+ Gem.win_platform = true
@installer.wrappers = false
util_make_exec
@installer.gem_dir = util_gem_dir
@@ -431,16 +431,13 @@ load 'my_exec'
installed_exec = File.join(util_inst_bindir, "my_exec")
assert_equal true, File.exist?(installed_exec)
- assert_match(/Unable to use symlinks on win32, installing wrapper/i,
+ assert_match(/Unable to use symlinks on Windows, installing wrapper/i,
@ui.error)
-
- expected_mode = win_platform? ? 0100644 : 0100755
- assert_equal expected_mode, File.stat(installed_exec).mode
wrapper = File.read installed_exec
assert_match(/generated by RubyGems/, wrapper)
ensure
- Config::CONFIG["arch"] = old_arch
+ Gem.win_platform = old_win_platform
end
def test_generate_bin_uses_default_shebang
diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb
index 4a1651bc0e..a1462d4dcd 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -19,6 +19,7 @@ class TestGemPlatform < RubyGemTestCase
end
def test_self_new
+ assert_equal Gem::Platform.local, Gem::Platform.new(Gem::Platform::CURRENT)
assert_equal Gem::Platform::RUBY, Gem::Platform.new(Gem::Platform::RUBY)
assert_equal Gem::Platform::RUBY, Gem::Platform.new(nil)
assert_equal Gem::Platform::RUBY, Gem::Platform.new('')
@@ -63,6 +64,7 @@ class TestGemPlatform < RubyGemTestCase
'i386-openbsd4.0' => ['x86', 'openbsd', '4.0'],
'i386-solaris2.10' => ['x86', 'solaris', '2.10'],
'i386-solaris2.8' => ['x86', 'solaris', '2.8'],
+ 'mswin32' => ['x86', 'mswin32', nil],
'x86_64-linux' => ['x86_64', 'linux', nil],
'x86_64-openbsd3.9' => ['x86_64', 'openbsd', '3.9'],
'x86_64-openbsd4.0' => ['x86_64', 'openbsd', '4.0'],