diff options
author | ryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-01-19 00:08:49 +0000 |
---|---|---|
committer | ryan <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-01-19 00:08:49 +0000 |
commit | e798ccbacf489a3af2201ae30058ff0ae7f79045 (patch) | |
tree | 4147a7834eb88323057fd2120a2ddc96c1eb32ab /lib/rubygems.rb | |
parent | d26fb035cae8d351dc238376722c980230dc5fbd (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.rb | 366 |
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 |