summaryrefslogtreecommitdiff
path: root/lib/rubygems.rb
diff options
context:
space:
mode:
authorryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-19 00:08:49 +0000
committerryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-19 00:08:49 +0000
commite798ccbacf489a3af2201ae30058ff0ae7f79045 (patch)
tree4147a7834eb88323057fd2120a2ddc96c1eb32ab /lib/rubygems.rb
parentd26fb035cae8d351dc238376722c980230dc5fbd (diff)
Import rubygems 1.5.0 (release candidate)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30599 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems.rb')
-rw-r--r--lib/rubygems.rb366
1 files changed, 237 insertions, 129 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 9f72b8aa45..28fe95889e 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -5,9 +5,24 @@
# See LICENSE.txt for permissions.
#++
+# TODO: remove when 1.9.1 no longer supported
+QUICKLOADER_SUCKAGE = RUBY_VERSION >= "1.9.1" and RUBY_VERSION < "1.9.2"
+# TODO: remove when 1.9.2 no longer supported
+GEM_PRELUDE_SUCKAGE = RUBY_VERSION >= "1.9.2" and RUBY_VERSION < "1.9.3"
+
+gem_preluded = GEM_PRELUDE_SUCKAGE and defined? Gem
+
+if GEM_PRELUDE_SUCKAGE and defined?(Gem::QuickLoader) then
+ Gem::QuickLoader.load_full_rubygems_library
+
+ class << Gem
+ remove_method :try_activate if Gem.respond_to?(:try_activate, true)
+ end
+end
+
require 'rubygems/defaults'
-require 'thread'
-require 'etc'
+require 'rbconfig'
+require 'thread' # HACK: remove me for 1.5 - this is here just for rails
##
# RubyGems is the Ruby standard for publishing and managing third party
@@ -98,7 +113,7 @@ require 'etc'
# -The RubyGems Team
module Gem
- RubyGemsVersion = VERSION = '1.3.7'
+ RubyGemsVersion = VERSION = '1.5.0'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
@@ -110,40 +125,49 @@ module Gem
attr_accessor :name
# Version requirement of gem
- attr_accessor :version_requirement
- end
+ attr_accessor :requirement
- ##
- # Configuration settings from ::RbConfig
+ def version_requirement
+ warn "#{Gem.location_of_caller.join ':'}:Warning: " \
+ "Gem::LoadError#version_requirement is deprecated " \
+ "and will be removed on or after January 2011. " \
+ "Use #requirement."
+
+ requirement
+ end
+
+ def version_requirement= requirement
+ warn "#{Gem.location_of_caller.join ':'}:Warning: " \
+ "Gem::LoadError#version_requirement= is deprecated " \
+ "and will be removed on or after January 2011. " \
+ "Use #requirement."
- ConfigMap = {} unless defined?(ConfigMap)
+ self.requirement = requirement
+ end
+ end
- require 'rbconfig'
+ RbConfigPriorities = %w[
+ EXEEXT RUBY_SO_NAME arch bindir datadir libdir ruby_install_name
+ ruby_version rubylibprefix sitedir sitelibdir vendordir vendorlibdir
+ ]
- ConfigMap.merge!(
- :EXEEXT => RbConfig::CONFIG["EXEEXT"],
- :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
- :arch => RbConfig::CONFIG["arch"],
- :bindir => RbConfig::CONFIG["bindir"],
- :datadir => RbConfig::CONFIG["datadir"],
- :libdir => RbConfig::CONFIG["libdir"],
- :ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
- :ruby_version => RbConfig::CONFIG["ruby_version"],
- :rubylibprefix => RbConfig::CONFIG["rubylibprefix"],
- :sitedir => RbConfig::CONFIG["sitedir"],
- :sitelibdir => RbConfig::CONFIG["sitelibdir"],
- :vendordir => RbConfig::CONFIG["vendordir"] ,
- :vendorlibdir => RbConfig::CONFIG["vendorlibdir"]
- )
+ unless defined?(ConfigMap)
+ ##
+ # Configuration settings from ::RbConfig
+ ConfigMap = Hash.new do |cm, key|
+ cm[key] = RbConfig::CONFIG[key.to_s]
+ end
+ else
+ RbConfigPriorities.each do |key|
+ ConfigMap[key.to_sym] = RbConfig::CONFIG[key]
+ end
+ end
##
# Default directories in a gem repository
DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
- # :stopdoc:
- MUTEX = Mutex.new
-
RubyGemsPackageVersion = VERSION
# :startdoc:
@@ -175,8 +199,21 @@ module Gem
@pre_install_hooks ||= []
##
+ # Try to activate a gem containing +path+. Returns true if
+ # activation succeeded or wasn't needed because it was already
+ # activated. Returns false if it can't find the path in a gem.
+
+ def self.try_activate path
+ spec = Gem.searcher.find path
+ return false unless spec
+
+ Gem.activate spec.name, "= #{spec.version}"
+ return true
+ end
+
+ ##
# Activates an installed gem matching +gem+. The gem must satisfy
- # +version_requirements+.
+ # +requirements+.
#
# Returns true if the gem is activated, false if it is already
# loaded, or an exception otherwise.
@@ -190,22 +227,22 @@ module Gem
# More information on version requirements can be found in the
# Gem::Requirement and Gem::Version documentation.
- def self.activate(gem, *version_requirements)
- if version_requirements.last.is_a?(Hash)
- options = version_requirements.pop
+ def self.activate(gem, *requirements)
+ if requirements.last.is_a?(Hash)
+ options = requirements.pop
else
options = {}
end
sources = options[:sources] || []
- if version_requirements.empty? then
- version_requirements = Gem::Requirement.default
+ if requirements.empty? then
+ requirements = Gem::Requirement.default
end
unless gem.respond_to?(:name) and
gem.respond_to?(:requirement) then
- gem = Gem::Dependency.new(gem, version_requirements)
+ gem = Gem::Dependency.new(gem, requirements)
end
matches = Gem.source_index.find_name(gem.name, gem.requirement)
@@ -226,7 +263,7 @@ module Gem
e = Gem::LoadError.new msg
e.name = gem.name
- e.version_requirement = gem.requirement
+ e.requirement = gem.requirement
raise e
end
@@ -247,9 +284,6 @@ module Gem
activate dep_gem, :sources => [spec, *sources]
end
- # bin directory must come before library directories
- spec.require_paths.unshift spec.bindir if spec.bindir
-
require_paths = spec.require_paths.map do |path|
File.join spec.full_gem_path, path
end
@@ -310,26 +344,30 @@ module Gem
##
# Find the full path to the executable for gem +name+. If the +exec_name+
# is not given, the gem's default_executable is chosen, otherwise the
- # specified executable's path is returned. +version_requirements+ allows
+ # specified executable's path is returned. +requirements+ allows
# you to specify specific gem versions.
- def self.bin_path(name, exec_name = nil, *version_requirements)
- version_requirements = Gem::Requirement.default if
- version_requirements.empty?
- spec = Gem.source_index.find_name(name, version_requirements).last
+ def self.bin_path(name, exec_name = nil, *requirements)
+ requirements = Gem::Requirement.default if
+ requirements.empty?
+ specs = Gem.source_index.find_name(name, requirements)
raise Gem::GemNotFoundException,
- "can't find gem #{name} (#{version_requirements})" unless spec
+ "can't find gem #{name} (#{requirements})" if specs.empty?
- exec_name ||= spec.default_executable
+ specs = specs.find_all do |spec|
+ spec.executables.include?(exec_name)
+ end if exec_name
- unless exec_name
- msg = "no default executable for #{spec.full_name}"
- raise Gem::Exception, msg
+ unless spec = specs.last
+ msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
+ raise Gem::GemNotFoundException, msg
end
- unless spec.executables.include? exec_name
- msg = "can't find executable #{exec_name} for #{spec.full_name}"
+ exec_name ||= spec.default_executable
+
+ unless exec_name
+ msg = "no default executable for #{spec.full_name} and none given"
raise Gem::Exception, msg
end
@@ -364,9 +402,7 @@ module Gem
@@source_index = nil
- MUTEX.synchronize do
- @searcher = nil
- end
+ @searcher = nil
end
##
@@ -414,7 +450,7 @@ module Gem
def self.dir
@gem_home ||= nil
- set_home(ENV['GEM_HOME'] || Gem.configuration.home || default_dir) unless @gem_home
+ set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
@gem_home
end
@@ -455,41 +491,66 @@ module Gem
end
##
- # Returns a list of paths matching +file+ that can be used by a gem to pick
+ # Returns a list of paths matching +glob+ that can be used by a gem to pick
# up features from other gems. For example:
#
# Gem.find_files('rdoc/discover').each do |path| load path end
#
- # find_files search $LOAD_PATH for files as well as gems.
+ # if +check_load_path+ is true (the default), then find_files also searches
+ # $LOAD_PATH for files as well as gems.
#
# Note that find_files will return all files even if they are from different
# versions of the same gem.
- def self.find_files(path)
- load_path_files = suffixes.map do |sfx|
- base = path + sfx
- $LOAD_PATH.map {|load_path|
- Dir[File.expand_path(base, load_path)]
- }
- end.flatten.select {|f| File.file?(f.untaint)}
+ def self.find_files(glob, check_load_path=true)
+ files = []
- specs = searcher.find_all path
+ if check_load_path
+ files = $LOAD_PATH.map { |load_path|
+ Dir["#{File.expand_path glob, load_path}#{Gem.suffix_pattern}"]
+ }.flatten.select { |file| File.file? file.untaint }
+ end
- specs_files = specs.map do |spec|
- searcher.matching_files spec, path
- end.flatten
+ specs = searcher.find_all glob
- (load_path_files + specs_files).flatten.uniq
+ specs.each do |spec|
+ files.concat searcher.matching_files(spec, glob)
+ end
+
+ # $LOAD_PATH might contain duplicate entries or reference
+ # the spec dirs directly, so we prune.
+ files.uniq! if check_load_path
+
+ return files
end
##
# Finds the user's home directory.
+ #--
+ # Some comments from the ruby-talk list regarding finding the home
+ # directory:
+ #
+ # I have HOME, USERPROFILE and HOMEDRIVE + HOMEPATH. Ruby seems
+ # to be depending on HOME in those code samples. I propose that
+ # it should fallback to USERPROFILE and HOMEDRIVE + HOMEPATH (at
+ # least on Win32).
def self.find_home
+ unless RUBY_VERSION > '1.9' then
+ ['HOME', 'USERPROFILE'].each do |homekey|
+ return File.expand_path(ENV[homekey]) if ENV[homekey]
+ end
+
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
+ return File.expand_path("#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}")
+ end
+ end
+
File.expand_path "~"
rescue
if File::ALT_SEPARATOR then
- "C:/"
+ drive = ENV['HOMEDRIVE'] || ENV['SystemDrive']
+ File.join(drive.to_s, '/')
else
"/"
end
@@ -530,6 +591,20 @@ module Gem
end
##
+ # Get the default RubyGems API host. This is normally
+ # <tt>https://rubygems.org</tt>.
+
+ def self.host
+ @host ||= "https://rubygems.org"
+ end
+
+ ## Set the default RubyGems API host.
+
+ def self.host= host
+ @host = host
+ end
+
+ ##
# Return a list of all possible load paths for the latest version for all
# gems in the Gem installation.
@@ -573,13 +648,29 @@ module Gem
# so you can override the gem_prelude.rb default $LOAD_PATH paths.
def self.load_path_insert_index
- $LOAD_PATH.index { |p| p.instance_variable_defined? :@gem_prelude_index }
+ index = $LOAD_PATH.index ConfigMap[:sitelibdir]
+
+ if QUICKLOADER_SUCKAGE then
+ $LOAD_PATH.each_with_index do |path, i|
+ if path.instance_variables.include?(:@gem_prelude_index) or
+ path.instance_variables.include?('@gem_prelude_index') then
+ index = i
+ break
+ end
+ end
+ end
+
+ index
end
- def self.remove_prelude_paths
- # Gem::QuickLoader::GemLoadPaths.each do |path|
- # $LOAD_PATH.delete(path)
- # end
+ ##
+ # Loads YAML, preferring Psych
+
+ def self.load_yaml
+ require 'psych'
+ rescue ::LoadError
+ ensure
+ require 'yaml'
end
##
@@ -607,7 +698,7 @@ module Gem
@gem_path ||= nil
unless @gem_path then
- paths = [ENV['GEM_PATH'] || Gem.configuration.path || default_path]
+ paths = [ENV['GEM_PATH'] || default_path]
if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
paths << APPLE_GEM_HOME
@@ -720,9 +811,7 @@ module Gem
def self.refresh
source_index.refresh!
- MUTEX.synchronize do
- @searcher = nil
- end
+ @searcher = nil
end
##
@@ -750,7 +839,7 @@ module Gem
end
error.name = gem.name
- error.version_requirement = gem.requirement
+ error.requirement = gem.requirement
raise error
end
@@ -812,9 +901,7 @@ module Gem
# The GemPathSearcher object used to search for matching installed gems.
def self.searcher
- MUTEX.synchronize do
- @searcher ||= Gem::GemPathSearcher.new
- end
+ @searcher ||= Gem::GemPathSearcher.new
end
##
@@ -895,8 +982,14 @@ module Gem
# Suffixes for require-able paths.
def self.suffixes
- ['', '.rb', ".#{RbConfig::CONFIG["DLEXT"]}"]
- end unless defined?(suffixes)
+ @suffixes ||= ['',
+ '.rb',
+ *%w(DLEXT DLEXT2).map { |key|
+ val = RbConfig::CONFIG[key]
+ ".#{val}" unless val.empty?
+ }
+ ].compact.uniq
+ end
##
# Prints the amount of time the supplied block takes to run using the debug
@@ -952,11 +1045,9 @@ module Gem
end
##
- # Find all 'rubygems_plugin' files and load them
-
- def self.load_plugins
- plugins = Gem.find_files 'rubygems_plugin'
+ # Load +plugins+ as ruby files
+ def self.load_plugin_files(plugins)
plugins.each do |plugin|
# Skip older versions of the GemCutter plugin: Its commands are in
@@ -973,6 +1064,31 @@ module Gem
end
end
+ ##
+ # Find all 'rubygems_plugin' files in installed gems and load them
+
+ def self.load_plugins
+ load_plugin_files find_files('rubygems_plugin', false)
+ end
+
+ ##
+ # Find all 'rubygems_plugin' files in $LOAD_PATH and load them
+
+ def self.load_env_plugins
+ path = "rubygems_plugin"
+
+ files = []
+ $LOAD_PATH.each do |load_path|
+ globbed = Dir["#{File.expand_path path, load_path}#{Gem.suffix_pattern}"]
+
+ globbed.each do |load_path_file|
+ files << load_path_file if File.file?(load_path_file.untaint)
+ end
+ end
+
+ load_plugin_files files
+ end
+
class << self
##
@@ -1014,21 +1130,27 @@ module Gem
MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"
- ##
- # Location of legacy YAML quick gemspecs on remote repositories
-
- YAML_SPEC_DIR = 'quick/'
-
+ autoload :Version, 'rubygems/version'
+ autoload :Requirement, 'rubygems/requirement'
+ autoload :Dependency, 'rubygems/dependency'
+ autoload :GemPathSearcher, 'rubygems/gem_path_searcher'
+ autoload :SpecFetcher, 'rubygems/spec_fetcher'
+ autoload :Specification, 'rubygems/specification'
+ autoload :Cache, 'rubygems/source_index'
+ autoload :SourceIndex, 'rubygems/source_index'
+ autoload :Platform, 'rubygems/platform'
+ autoload :Builder, 'rubygems/builder'
+ autoload :ConfigFile, 'rubygems/config_file'
end
module Kernel
- remove_method :gem if respond_to?(:gem, true) # defined in gem_prelude.rb on 1.9
+ remove_method :gem if respond_to? :gem # defined in gem_prelude.rb on 1.9
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
- # +version_requirements+ is a list of version requirements that the
+ # +requirements+ is a list of version requirements that the
# specified gem must match, most commonly "= example.version.number". See
# Gem::Requirement for how to specify a version requirement.
#
@@ -1051,10 +1173,10 @@ module Kernel
#
# GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
- def gem(gem_name, *version_requirements) # :doc:
+ def gem(gem_name, *requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
- Gem.activate(gem_name, *version_requirements)
+ Gem.activate(gem_name, *requirements)
end
private :gem
@@ -1068,54 +1190,40 @@ end
# "#{ConfigMap[:datadir]}/#{package_name}".
def RbConfig.datadir(package_name)
+ require 'rbconfig/datadir' # TODO Deprecate after June 2010.
Gem.datadir(package_name) ||
File.join(Gem::ConfigMap[:datadir], package_name)
end
require 'rubygems/exceptions'
-require 'rubygems/version'
-require 'rubygems/requirement'
-require 'rubygems/dependency'
-require 'rubygems/gem_path_searcher' # Needed for Kernel#gem
-require 'rubygems/source_index' # Needed for Kernel#gem
-require 'rubygems/platform'
-require 'rubygems/builder' # HACK: Needed for rake's package task.
-begin
- ##
- # Defaults the operating system (or packager) wants to provide for RubyGems.
-
- require 'rubygems/defaults/operating_system'
-rescue LoadError
-end
-
-if defined?(RUBY_ENGINE) then
+unless gem_preluded then # TODO: remove guard after 1.9.2 dropped
begin
##
- # Defaults the ruby implementation wants to provide for RubyGems
+ # Defaults the operating system (or packager) wants to provide for RubyGems.
- require "rubygems/defaults/#{RUBY_ENGINE}"
+ require 'rubygems/defaults/operating_system'
rescue LoadError
end
-end
-
-require 'rubygems/config_file'
-class << Gem
- remove_method :try_activate if Gem.respond_to?(:try_activate, true)
+ if defined?(RUBY_ENGINE) then
+ begin
+ ##
+ # Defaults the ruby implementation wants to provide for RubyGems
- def try_activate(path)
- spec = Gem.searcher.find(path)
- return false unless spec
-
- Gem.activate(spec.name, "= #{spec.version}")
- return true
+ require "rubygems/defaults/#{RUBY_ENGINE}"
+ rescue LoadError
+ end
end
end
-require 'rubygems/custom_require'
+##
+# Enables the require hook for RubyGems.
+#
+# Ruby 1.9 allows --disable-gems, so we require it when we didn't detect a Gem
+# constant at rubygems.rb load time.
-Gem.clear_paths
+require 'rubygems/custom_require' unless RUBY_VERSION > '1.9'
-Gem.load_plugins
+Gem.clear_paths