summaryrefslogtreecommitdiff
path: root/lib/rubygems.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-31 22:40:06 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-31 22:40:06 +0000
commit8cc45aae947d453acca029e13eb64f3f5f0bf942 (patch)
treef9485a20c99defe1aae3f32555a41d23c2298ad8 /lib/rubygems.rb
parentdc8359969ec71ece10357ba9396430db7f029e45 (diff)
Import RubyGems 1.1.0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15873 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems.rb')
-rw-r--r--lib/rubygems.rb901
1 files changed, 504 insertions, 397 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 9549b9bdca..3f9657ac1e 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -17,82 +17,80 @@ end
module Kernel
- # Adds a Ruby Gem to the $LOAD_PATH. Before a Gem is loaded, its
- # required Gems are loaded. If the version information is omitted,
- # the highest version Gem of the supplied name is loaded. If a Gem
- # is not found that meets the version requirement and/or a required
- # Gem is not found, a Gem::LoadError is raised. More information on
- # version requirements can be found in the Gem::Version
- # documentation.
- #
- # The +gem+ directive should be executed *before* any require
- # statements (otherwise rubygems might select a conflicting library
- # version).
+ ##
+ # Use Kernel#gem to activate a specific version of +gem_name+.
#
- # You can define the environment variable GEM_SKIP as a way to not
- # load specified gems. You might do this to test out changes that
- # haven't been installed yet. Example:
+ # +version_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.
#
- # GEM_SKIP=libA:libB ruby-I../libA -I../libB ./mycode.rb
+ # If you will be activating the latest version of a gem, there is no need to
+ # call Kernel#gem, Kernel#require will do the right thing for you.
#
- # gem:: [String or Gem::Dependency] The gem name or dependency
- # instance.
+ # Kernel#gem returns true if the gem was activated, otherwise false. If the
+ # gem could not be found, didn't match the version requirements, or a
+ # different version was already activated, an exception will be raised.
#
- # version_requirement:: [default=">= 0"] The version
- # requirement.
+ # Kernel#gem should be called *before* any require statements (otherwise
+ # RubyGems may load a conflicting library version).
#
- # return:: [Boolean] true if the Gem is loaded, otherwise false.
+ # In older RubyGems versions, the environment variable GEM_SKIP could be
+ # used to skip activation of specified gems, for example to test out changes
+ # that haven't been installed yet. Now RubyGems defers to -I and the
+ # RUBYLIB environment variable to skip activation of a gem.
#
- # raises:: [Gem::LoadError] if Gem cannot be found, is listed in
- # GEM_SKIP, or version requirement not met.
+ # Example:
#
- def gem(gem_name, *version_requirements)
- active_gem_with_options(gem_name, version_requirements)
- end
-
- # Return the file name (string) and line number (integer) of the caller of
- # the caller of this method.
- def location_of_caller
- file, lineno = caller[1].split(':')
- lineno = lineno.to_i
- [file, lineno]
- end
- private :location_of_caller
+ # GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
- def active_gem_with_options(gem_name, version_requirements, options={})
+ def gem(gem_name, *version_requirements)
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
- Gem.activate(gem_name, options[:auto_require], *version_requirements)
+ Gem.activate(gem_name, *version_requirements)
end
- private :active_gem_with_options
+
end
+##
# Main module to hold all RubyGem classes/modules.
-#
+
module Gem
ConfigMap = {} unless defined?(ConfigMap)
require 'rbconfig'
RbConfig = Config unless defined? ::RbConfig
+
ConfigMap.merge!(
- :BASERUBY => RbConfig::CONFIG["BASERUBY"],
- :EXEEXT => RbConfig::CONFIG["EXEEXT"],
- :RUBY_INSTALL_NAME => RbConfig::CONFIG["RUBY_INSTALL_NAME"],
- :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
- :arch => RbConfig::CONFIG["arch"],
- :bindir => RbConfig::CONFIG["bindir"],
- :libdir => RbConfig::CONFIG["libdir"],
- :ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
- :ruby_version => RbConfig::CONFIG["ruby_version"],
- :sitedir => RbConfig::CONFIG["sitedir"],
- :sitelibdir => RbConfig::CONFIG["sitelibdir"]
+ :BASERUBY => RbConfig::CONFIG["BASERUBY"],
+ :EXEEXT => RbConfig::CONFIG["EXEEXT"],
+ :RUBY_INSTALL_NAME => RbConfig::CONFIG["RUBY_INSTALL_NAME"],
+ :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
+ :arch => RbConfig::CONFIG["arch"],
+ :bindir => RbConfig::CONFIG["bindir"],
+ :libdir => RbConfig::CONFIG["libdir"],
+ :ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
+ :ruby_version => RbConfig::CONFIG["ruby_version"],
+ :sitedir => RbConfig::CONFIG["sitedir"],
+ :sitelibdir => RbConfig::CONFIG["sitelibdir"]
)
+ DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
+
MUTEX = Mutex.new
RubyGemsPackageVersion = RubyGemsVersion
- DIRECTORIES = %w[cache doc gems specifications] unless defined?(DIRECTORIES)
+ ##
+ # An Array of Regexps that match windows ruby platforms.
+
+ WIN_PATTERNS = [
+ /bccwin/i,
+ /cygwin/i,
+ /djgpp/i,
+ /mingw/i,
+ /mswin/i,
+ /wince/i,
+ ]
@@source_index = nil
@@win_platform = nil
@@ -103,10 +101,129 @@ module Gem
@ruby = nil
@sources = []
+ ##
+ # Activates an installed gem matching +gem+. The gem must satisfy
+ # +version_requirements+.
+ #
+ # Returns true if the gem is activated, false if it is already
+ # loaded, or an exception otherwise.
+ #
+ # Gem#activate adds the library paths in +gem+ to $LOAD_PATH. Before a Gem
+ # is activated its required Gems are activated. If the version information
+ # is omitted, the highest version Gem of the supplied name is loaded. If a
+ # Gem is not found that meets the version requirements or a required Gem is
+ # not found, a Gem::LoadError is raised.
+ #
+ # 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.empty? then
+ version_requirements = Gem::Requirement.default
+ end
+
+ unless gem.respond_to?(:name) and
+ gem.respond_to?(:version_requirements) then
+ gem = Gem::Dependency.new(gem, version_requirements)
+ end
+
+ matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
+ report_activate_error(gem) if matches.empty?
+
+ if @loaded_specs[gem.name] then
+ # This gem is already loaded. If the currently loaded gem is not in the
+ # list of candidate gems, then we have a version conflict.
+ existing_spec = @loaded_specs[gem.name]
+
+ unless matches.any? { |spec| spec.version == existing_spec.version } then
+ raise Gem::Exception,
+ "can't activate #{gem}, already activated #{existing_spec.full_name}]"
+ end
+
+ return false
+ end
+
+ # new load
+ spec = matches.last
+ return false if spec.loaded?
+
+ spec.loaded = true
+ @loaded_specs[spec.name] = spec
+
+ # Load dependent gems first
+ spec.dependencies.each do |dep_gem|
+ activate dep_gem
+ 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
+
+ sitelibdir = ConfigMap[:sitelibdir]
+
+ # gem directories must come after -I and ENV['RUBYLIB']
+ insert_index = load_path_insert_index
+
+ if insert_index then
+ # gem directories must come after -I and ENV['RUBYLIB']
+ $LOAD_PATH.insert(insert_index, *require_paths)
+ else
+ # we are probably testing in core, -I and RUBYLIB don't apply
+ $LOAD_PATH.unshift(*require_paths)
+ end
+
+ return true
+ end
+
+ ##
+ # An Array of all possible load paths for all versions of all gems in the
+ # Gem installation.
+
+ def self.all_load_paths
+ result = []
+
+ Gem.path.each do |gemdir|
+ each_load_path all_partials(gemdir) do |load_path|
+ result << load_path
+ end
+ end
+
+ result
+ end
+
+ ##
+ # Return all the partial paths in +gemdir+.
+
+ def self.all_partials(gemdir)
+ Dir[File.join(gemdir, 'gems/*')]
+ end
+
+ private_class_method :all_partials
+
+ ##
+ # The mode needed to read a file as straight binary.
+
+ def self.binary_mode
+ @binary_mode ||= RUBY_VERSION > '1.9' ? 'rb:ascii-8bit' : 'rb'
+ end
+
+ ##
+ # The path where gem executables are to be installed.
+
+ def self.bindir(install_dir=Gem.dir)
+ return File.join(install_dir, 'bin') unless
+ install_dir.to_s == Gem.default_dir
+ Gem.default_bindir
+ end
+
+ ##
# Reset the +dir+ and +path+ values. The next time +dir+ or +path+
# is requested, the values will be calculated from scratch. This is
# mainly used by the unit tests to provide test isolation.
- #
+
def self.clear_paths
@gem_home = nil
@gem_path = nil
@@ -116,441 +233,430 @@ module Gem
end
end
- # The version of the Marshal format for your Ruby.
- def self.marshal_version
- "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
+ ##
+ # The path to standard location of the user's .gemrc file.
+
+ def self.config_file
+ File.join Gem.user_home, '.gemrc'
end
##
- # The directory prefix this RubyGems was installed at.
+ # The standard configuration object for gems.
- def self.prefix
- prefix = File.dirname File.expand_path(__FILE__)
- if prefix == ConfigMap[:sitelibdir] then
- nil
- else
- File.dirname prefix
- end
+ def self.configuration
+ return @configuration if @configuration
+ require 'rubygems/config_file'
+ @configuration = Gem::ConfigFile.new []
end
- # Returns an Cache of specifications that are in the Gem.path
- #
- # return:: [Gem::SourceIndex] Index of installed Gem::Specifications
- #
- def self.source_index
- @@source_index ||= SourceIndex.from_installed_gems
+ ##
+ # Use the given configuration object (which implements the ConfigFile
+ # protocol) as the standard configuration object.
+
+ def self.configuration=(config)
+ @configuration = config
end
##
- # An Array of Regexps that match windows ruby platforms.
+ # The path the the data directory specified by the gem name. If the
+ # package is not available as a gem, return nil.
- WIN_PATTERNS = [
- /bccwin/i,
- /cygwin/i,
- /djgpp/i,
- /mingw/i,
- /mswin/i,
- /wince/i,
- ]
+ def self.datadir(gem_name)
+ spec = @loaded_specs[gem_name]
+ return nil if spec.nil?
+ File.join(spec.full_gem_path, 'data', gem_name)
+ end
##
- # Is this a windows platform?
+ # The path where gems are to be installed.
- def self.win_platform?
- if @@win_platform.nil? then
- @@win_platform = !!WIN_PATTERNS.find { |r| RUBY_PLATFORM =~ r }
- end
+ def self.dir
+ @gem_home ||= nil
+ set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
+ @gem_home
+ end
- @@win_platform
+ ##
+ # Expand each partial gem path with each of the required paths specified
+ # in the Gem spec. Each expanded path is yielded.
+
+ def self.each_load_path(partials)
+ partials.each do |gp|
+ base = File.basename(gp)
+ specfn = File.join(dir, "specifications", base + ".gemspec")
+ if File.exist?(specfn)
+ spec = eval(File.read(specfn))
+ spec.require_paths.each do |rp|
+ yield(File.join(gp, rp))
+ end
+ else
+ filename = File.join(gp, 'lib')
+ yield(filename) if File.exist?(filename)
+ end
+ end
end
- class << self
+ private_class_method :each_load_path
- attr_reader :loaded_specs
+ ##
+ # Quietly ensure the named Gem directory contains all the proper
+ # subdirectories. If we can't create a directory due to a permission
+ # problem, then we will silently continue.
- # Quietly ensure the named Gem directory contains all the proper
- # subdirectories. If we can't create a directory due to a permission
- # problem, then we will silently continue.
- def ensure_gem_subdirectories(gemdir)
- require 'fileutils'
+ def self.ensure_gem_subdirectories(gemdir)
+ require 'fileutils'
- Gem::DIRECTORIES.each do |filename|
- fn = File.join gemdir, filename
- FileUtils.mkdir_p fn rescue nil unless File.exist? fn
- end
+ Gem::DIRECTORIES.each do |filename|
+ fn = File.join gemdir, filename
+ FileUtils.mkdir_p fn rescue nil unless File.exist? fn
end
+ end
- def platforms
- @platforms ||= [Gem::Platform::RUBY, Gem::Platform.local]
- 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).
- # Returns an Array of sources to fetch remote gems from. If the sources
- # list is empty, attempts to load the "sources" gem, then uses
- # default_sources if it is not installed.
- def sources
- if @sources.empty? then
- begin
- gem 'sources', '> 0.0.1'
- require 'sources'
- rescue LoadError
- @sources = default_sources
- end
- end
+ def self.find_home
+ ['HOME', 'USERPROFILE'].each do |homekey|
+ return ENV[homekey] if ENV[homekey]
+ end
- @sources
+ if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
+ return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
end
+ begin
+ File.expand_path("~")
+ rescue
+ if File::ALT_SEPARATOR then
+ "C:/"
+ else
+ "/"
+ end
+ end
+ end
- # Provide an alias for the old name.
- alias cache source_index
+ private_class_method :find_home
- # The directory path where Gems are to be installed.
- #
- # return:: [String] The directory path
- #
- def dir
- @gem_home ||= nil
- set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
- @gem_home
- end
+ ##
+ # Return a list of all possible load paths for the latest version for all
+ # gems in the Gem installation.
- # The directory path where executables are to be installed.
- #
- def bindir(install_dir=Gem.dir)
- return File.join(install_dir, 'bin') unless
- install_dir.to_s == Gem.default_dir
+ def self.latest_load_paths
+ result = []
- if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
- '/usr/bin'
- else # generic install
- ConfigMap[:bindir]
+ Gem.path.each do |gemdir|
+ each_load_path(latest_partials(gemdir)) do |load_path|
+ result << load_path
end
end
- # List of directory paths to search for Gems.
- #
- # return:: [List<String>] List of directory paths.
- #
- 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))
+ result
+ end
+
+ ##
+ # Return only the latest partial paths in the given +gemdir+.
+
+ def self.latest_partials(gemdir)
+ latest = {}
+ all_partials(gemdir).each do |gp|
+ base = File.basename(gp)
+ if base =~ /(.*)-((\d+\.)*\d+)/ then
+ name, version = $1, $2
+ ver = Gem::Version.new(version)
+ if latest[name].nil? || ver > latest[name][0]
+ latest[name] = [ver, gp]
+ end
end
- @gem_path
end
+ latest.collect { |k,v| v[1] }
+ end
- # The home directory for the user.
- def user_home
- @user_home ||= find_home
- end
+ private_class_method :latest_partials
- # Return the path to standard location of the users .gemrc file.
- def config_file
- File.join(Gem.user_home, '.gemrc')
+ ##
+ # The index to insert activated gem paths into the $LOAD_PATH.
+ #
+ # Defaults to the site lib directory unless gem_prelude.rb has loaded paths,
+ # then it inserts the activated gem's paths before the gem_prelude.rb paths
+ # so you can override the gem_prelude.rb default $LOAD_PATH paths.
+
+ def self.load_path_insert_index
+ index = $LOAD_PATH.index ConfigMap[:sitelibdir]
+
+ $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
- # The standard configuration object for gems.
- def configuration
- return @configuration if @configuration
- require 'rubygems/config_file'
- @configuration = Gem::ConfigFile.new []
- end
+ index
+ end
- # Use the given configuration object (which implements the
- # ConfigFile protocol) as the standard configuration object.
- def configuration=(config)
- @configuration = config
- end
+ ##
+ # The file name and line number of the caller of the caller of this method.
- # Return the path the the data directory specified by the gem
- # name. If the package is not available as a gem, return nil.
- def datadir(gem_name)
- spec = @loaded_specs[gem_name]
- return nil if spec.nil?
- File.join(spec.full_gem_path, 'data', gem_name)
- end
+ def self.location_of_caller
+ file, lineno = caller[1].split(':')
+ lineno = lineno.to_i
+ [file, lineno]
+ end
- # Return the searcher object to search for matching gems.
- def searcher
- MUTEX.synchronize do
- @searcher ||= Gem::GemPathSearcher.new
- end
- end
+ private_class_method :location_of_caller
- # Return the Ruby command to use to execute the Ruby interpreter.
- def ruby
- if @ruby.nil? then
- @ruby = File.join(ConfigMap[:bindir],
- ConfigMap[:ruby_install_name])
- @ruby << ConfigMap[:EXEEXT]
- end
+ ##
+ # manage_gems is useless and deprecated. Don't call it anymore.
+ #--
+ # TODO warn w/ RubyGems 1.2.x release.
- @ruby
- end
+ def self.manage_gems
+ #file, lineno = location_of_caller
- # Return the index to insert activated gem paths into the $LOAD_PATH
- # Defaults to the site lib directory unless gem_prelude.rb has loaded
- # paths then it inserts the path before those paths so you can override
- # the gem_prelude.rb default $LOAD_PATH paths.
- def load_path_insert_index
- index = $LOAD_PATH.index ConfigMap[:sitelibdir]
-
- $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
+ #warn "#{file}:#{lineno}:Warning: Gem#manage_gems is deprecated and will be removed on or after September 2008."
+ end
- index
- end
+ ##
+ # The version of the Marshal format for your Ruby.
- # Activate a gem (i.e. add it to the Ruby load path). The gem
- # must satisfy all the specified version constraints. If
- # +autorequire+ is true, then automatically require the specified
- # autorequire file in the gem spec.
- #
- # Returns true if the gem is loaded by this call, false if it is
- # already loaded, or an exception otherwise.
- #
- def activate(gem, autorequire, *version_requirements)
- if version_requirements.empty? then
- version_requirements = Gem::Requirement.default
- end
+ def self.marshal_version
+ "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
+ end
- unless gem.respond_to?(:name) && gem.respond_to?(:version_requirements)
- gem = Gem::Dependency.new(gem, version_requirements)
- end
+ ##
+ # Array of paths to search for Gems.
- matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
- report_activate_error(gem) if matches.empty?
+ def self.path
+ @gem_path ||= nil
- if @loaded_specs[gem.name]
- # This gem is already loaded. If the currently loaded gem is
- # not in the list of candidate gems, then we have a version
- # conflict.
- existing_spec = @loaded_specs[gem.name]
- if ! matches.any? { |spec| spec.version == existing_spec.version }
- fail Gem::Exception, "can't activate #{gem}, already activated #{existing_spec.full_name}]"
- end
- return false
- end
+ unless @gem_path then
+ paths = [ENV['GEM_PATH']] || [default_path]
- # new load
- spec = matches.last
- if spec.loaded?
- return false unless autorequire
- result = spec.autorequire ? require(spec.autorequire) : false
- return result || false
+ if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
+ paths << APPLE_GEM_HOME
end
- spec.loaded = true
- @loaded_specs[spec.name] = spec
+ set_paths paths.compact.join(File::PATH_SEPARATOR)
+ end
- # Load dependent gems first
- spec.dependencies.each do |dep_gem|
- activate(dep_gem, autorequire)
- end
+ @gem_path
+ end
- # bin directory must come before library directories
- spec.require_paths.unshift spec.bindir if spec.bindir
+ ##
+ # Array of platforms this RubyGems supports.
- require_paths = spec.require_paths.map do |path|
- File.join spec.full_gem_path, path
- end
+ def self.platforms
+ @platforms ||= [Gem::Platform::RUBY, Gem::Platform.local]
+ end
- sitelibdir = ConfigMap[:sitelibdir]
+ ##
+ # The directory prefix this RubyGems was installed at.
- # gem directories must come after -I and ENV['RUBYLIB']
- insert_index = load_path_insert_index
+ def self.prefix
+ prefix = File.dirname File.expand_path(__FILE__)
- if insert_index then
- # gem directories must come after -I and ENV['RUBYLIB']
- $LOAD_PATH.insert(insert_index, *require_paths)
- else
- # we are probably testing in core, -I and RUBYLIB don't apply
- $LOAD_PATH.unshift(*require_paths)
- end
+ if prefix == File.expand_path(ConfigMap[:sitelibdir]) then
+ nil
+ else
+ File.dirname prefix
+ end
+ end
- # Now autorequire
- if autorequire && spec.autorequire then # DEPRECATED
- Array(spec.autorequire).each do |a_lib|
- require a_lib
- end
- end
+ ##
+ # Safely read a file in binary mode on all platforms.
- return true
- end
+ def self.read_binary(path)
+ File.open path, binary_mode do |f| f.read end
+ end
+
+ ##
+ # Report a load error during activation. The message of load error
+ # depends on whether it was a version mismatch or if there are not gems of
+ # any version by the requested name.
- # Report a load error during activation. The message of load
- # error depends on whether it was a version mismatch or if there
- # are not gems of any version by the requested name.
- def report_activate_error(gem)
- matches = Gem.source_index.find_name(gem.name)
+ def self.report_activate_error(gem)
+ matches = Gem.source_index.find_name(gem.name)
- if matches.empty? then
- error = Gem::LoadError.new(
+ if matches.empty? then
+ error = Gem::LoadError.new(
"Could not find RubyGem #{gem.name} (#{gem.version_requirements})\n")
- else
- error = Gem::LoadError.new(
+ else
+ error = Gem::LoadError.new(
"RubyGem version error: " +
"#{gem.name}(#{matches.first.version} not #{gem.version_requirements})\n")
- end
-
- error.name = gem.name
- error.version_requirement = gem.version_requirements
- raise error
- end
- private :report_activate_error
-
- # Use the +home+ and (optional) +paths+ values for +dir+ and +path+.
- # Used mainly by the unit tests to provide environment isolation.
- #
- def use_paths(home, paths=[])
- clear_paths
- set_home(home) if home
- set_paths(paths.join(File::PATH_SEPARATOR)) if paths
end
- # Return a list of all possible load paths for all versions for
- # all gems in the Gem installation.
- #
- def all_load_paths
- result = []
- Gem.path.each do |gemdir|
- each_load_path(all_partials(gemdir)) do |load_path|
- result << load_path
- end
- end
- result
- end
+ error.name = gem.name
+ error.version_requirement = gem.version_requirements
+ raise error
+ end
- # Return a list of all possible load paths for the latest version
- # for all gems in the Gem installation.
- def latest_load_paths
- result = []
- Gem.path.each do |gemdir|
- each_load_path(latest_partials(gemdir)) do |load_path|
- result << load_path
- end
- end
- result
- end
+ private_class_method :report_activate_error
- def required_location(gemname, libfile, *version_constraints)
- version_constraints = Gem::Requirement.default if version_constraints.empty?
- matches = Gem.source_index.find_name(gemname, version_constraints)
- return nil if matches.empty?
- spec = matches.last
- spec.require_paths.each do |path|
- result = File.join(spec.full_gem_path, path, libfile)
- return result if File.exist?(result)
- end
- nil
+ def self.required_location(gemname, libfile, *version_constraints)
+ version_constraints = Gem::Requirement.default if version_constraints.empty?
+ matches = Gem.source_index.find_name(gemname, version_constraints)
+ return nil if matches.empty?
+ spec = matches.last
+ spec.require_paths.each do |path|
+ result = File.join(spec.full_gem_path, path, libfile)
+ return result if File.exist?(result)
end
+ nil
+ end
- def suffixes
- ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
- end
+ ##
+ # The path to the running Ruby interpreter.
- def suffix_pattern
- @suffix_pattern ||= "{#{suffixes.join(',')}}"
+ def self.ruby
+ if @ruby.nil? then
+ @ruby = File.join(ConfigMap[:bindir],
+ ConfigMap[:ruby_install_name])
+ @ruby << ConfigMap[:EXEEXT]
end
- # manage_gems is useless and deprecated. Don't call it anymore. This
- # will warn in two releases.
- def manage_gems
- # do nothing
- end
+ @ruby
+ end
- private
+ ##
+ # A Gem::Version for the currently running ruby.
- # Return all the partial paths in the given +gemdir+.
- def all_partials(gemdir)
- Dir[File.join(gemdir, 'gems/*')]
- end
+ def self.ruby_version
+ return @ruby_version if defined? @ruby_version
+ version = RUBY_VERSION.dup
+ version << ".#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
+ @ruby_version = Gem::Version.new version
+ end
- # Return only the latest partial paths in the given +gemdir+.
- def latest_partials(gemdir)
- latest = {}
- all_partials(gemdir).each do |gp|
- base = File.basename(gp)
- if base =~ /(.*)-((\d+\.)*\d+)/ then
- name, version = $1, $2
- ver = Gem::Version.new(version)
- if latest[name].nil? || ver > latest[name][0]
- latest[name] = [ver, gp]
- end
- end
- end
- latest.collect { |k,v| v[1] }
+ ##
+ # The GemPathSearcher object used to search for matching installed gems.
+
+ def self.searcher
+ MUTEX.synchronize do
+ @searcher ||= Gem::GemPathSearcher.new
end
+ end
+
+ ##
+ # Set the Gem home directory (as reported by Gem.dir).
+
+ def self.set_home(home)
+ home = home.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
+ @gem_home = home
+ ensure_gem_subdirectories(@gem_home)
+ end
- # Expand each partial gem path with each of the required paths
- # specified in the Gem spec. Each expanded path is yielded.
- def each_load_path(partials)
- partials.each do |gp|
- base = File.basename(gp)
- specfn = File.join(dir, "specifications", base + ".gemspec")
- if File.exist?(specfn)
- spec = eval(File.read(specfn))
- spec.require_paths.each do |rp|
- yield(File.join(gp, rp))
- end
- else
- filename = File.join(gp, 'lib')
- yield(filename) if File.exist?(filename)
+ private_class_method :set_home
+
+ ##
+ # Set the Gem search path (as reported by Gem.path).
+
+ def self.set_paths(gpaths)
+ if gpaths
+ @gem_path = gpaths.split(File::PATH_SEPARATOR)
+
+ if File::ALT_SEPARATOR then
+ @gem_path.map! do |path|
+ path.gsub File::ALT_SEPARATOR, File::SEPARATOR
end
end
+
+ @gem_path << Gem.dir
+ else
+ @gem_path = [Gem.dir]
end
- # Set the Gem home directory (as reported by +dir+).
- def set_home(home)
- @gem_home = home
- ensure_gem_subdirectories(@gem_home)
- end
+ @gem_path.uniq!
+ @gem_path.each do |gp| ensure_gem_subdirectories(gp) end
+ end
- # Set the Gem search path (as reported by +path+).
- 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
+ private_class_method :set_paths
- # 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 find_home
- ['HOME', 'USERPROFILE'].each do |homekey|
- return ENV[homekey] if ENV[homekey]
- end
- if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
- return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
- end
+ ##
+ # Returns the Gem::SourceIndex of specifications that are in the Gem.path
+
+ def self.source_index
+ @@source_index ||= SourceIndex.from_installed_gems
+ end
+
+ ##
+ # Returns an Array of sources to fetch remote gems from. If the sources
+ # list is empty, attempts to load the "sources" gem, then uses
+ # default_sources if it is not installed.
+
+ def self.sources
+ if @sources.empty? then
begin
- File.expand_path("~")
- rescue StandardError => ex
- if File::ALT_SEPARATOR
- "C:/"
- else
- "/"
- end
+ gem 'sources', '> 0.0.1'
+ require 'sources'
+ rescue LoadError
+ @sources = default_sources
end
end
+ @sources
+ end
+
+ ##
+ # Glob pattern for require-able path suffixes.
+
+ def self.suffix_pattern
+ @suffix_pattern ||= "{#{suffixes.join(',')}}"
+ end
+
+ ##
+ # Suffixes for require-able paths.
+
+ def self.suffixes
+ ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
+ end
+
+ ##
+ # Use the +home+ and +paths+ values for Gem.dir and Gem.path. Used mainly
+ # by the unit tests to provide environment isolation.
+
+ def self.use_paths(home, paths=[])
+ clear_paths
+ set_home(home) if home
+ set_paths(paths.join(File::PATH_SEPARATOR)) if paths
+ end
+
+ ##
+ # The home directory for the user.
+
+ def self.user_home
+ @user_home ||= find_home
+ end
+
+ ##
+ # Is this a windows platform?
+
+ def self.win_platform?
+ if @@win_platform.nil? then
+ @@win_platform = !!WIN_PATTERNS.find { |r| RUBY_PLATFORM =~ r }
+ end
+
+ @@win_platform
+ end
+
+ class << self
+
+ attr_reader :loaded_specs
+
+ # :stopdoc:
+
+ alias cache source_index # an alias for the old name
+
+ # :startdoc:
+
end
end
@@ -558,6 +664,7 @@ end
# Modify the non-gem version of datadir to handle gem package names.
require 'rbconfig/datadir'
+
module Config # :nodoc:
class << self
alias gem_original_datadir datadir