[前][次][番号順一覧][スレッド一覧]

ruby-changes:8022

From: drbrain <ko1@a...>
Date: Thu, 25 Sep 2008 19:14:24 +0900 (JST)
Subject: [ruby-changes:8022] Ruby:r19547 (trunk): Update to RubyGems 1.3.0 r1891

drbrain	2008-09-25 19:13:50 +0900 (Thu, 25 Sep 2008)

  New Revision: 19547

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19547

  Log:
    Update to RubyGems 1.3.0 r1891

  Added files:
    trunk/test/rubygems/test_gem_commands_list_command.rb
    trunk/test/rubygems/test_gem_commands_lock_command.rb
    trunk/test/rubygems/test_gem_commands_uninstall_command.rb
  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/commands/contents_command.rb
    trunk/lib/rubygems/commands/environment_command.rb
    trunk/lib/rubygems/commands/help_command.rb
    trunk/lib/rubygems/commands/install_command.rb
    trunk/lib/rubygems/commands/lock_command.rb
    trunk/lib/rubygems/commands/outdated_command.rb
    trunk/lib/rubygems/commands/pristine_command.rb
    trunk/lib/rubygems/commands/query_command.rb
    trunk/lib/rubygems/commands/rdoc_command.rb
    trunk/lib/rubygems/commands/specification_command.rb
    trunk/lib/rubygems/commands/unpack_command.rb
    trunk/lib/rubygems/commands/update_command.rb
    trunk/lib/rubygems/commands/which_command.rb
    trunk/lib/rubygems/config_file.rb
    trunk/lib/rubygems/defaults.rb
    trunk/lib/rubygems/dependency_installer.rb
    trunk/lib/rubygems/doc_manager.rb
    trunk/lib/rubygems/gem_path_searcher.rb
    trunk/lib/rubygems/installer.rb
    trunk/lib/rubygems/local_remote_options.rb
    trunk/lib/rubygems/package/tar_reader.rb
    trunk/lib/rubygems/platform.rb
    trunk/lib/rubygems/remote_fetcher.rb
    trunk/lib/rubygems/rubygems_version.rb
    trunk/lib/rubygems/source_index.rb
    trunk/lib/rubygems/source_info_cache.rb
    trunk/lib/rubygems/spec_fetcher.rb
    trunk/lib/rubygems/specification.rb
    trunk/lib/rubygems/test_utilities.rb
    trunk/lib/rubygems/uninstaller.rb
    trunk/lib/rubygems.rb
    trunk/test/rubygems/gemutilities.rb
    trunk/test/rubygems/mockgemui.rb
    trunk/test/rubygems/test_gem.rb
    trunk/test/rubygems/test_gem_builder.rb
    trunk/test/rubygems/test_gem_command_manager.rb
    trunk/test/rubygems/test_gem_commands_dependency_command.rb
    trunk/test/rubygems/test_gem_commands_install_command.rb
    trunk/test/rubygems/test_gem_commands_query_command.rb
    trunk/test/rubygems/test_gem_config_file.rb
    trunk/test/rubygems/test_gem_ext_configure_builder.rb
    trunk/test/rubygems/test_gem_ext_rake_builder.rb
    trunk/test/rubygems/test_gem_gem_path_searcher.rb
    trunk/test/rubygems/test_gem_install_update_options.rb
    trunk/test/rubygems/test_gem_installer.rb
    trunk/test/rubygems/test_gem_local_remote_options.rb
    trunk/test/rubygems/test_gem_package_tar_header.rb
    trunk/test/rubygems/test_gem_platform.rb
    trunk/test/rubygems/test_gem_remote_fetcher.rb
    trunk/test/rubygems/test_gem_source_index.rb
    trunk/test/rubygems/test_gem_source_info_cache.rb
    trunk/test/rubygems/test_gem_spec_fetcher.rb
    trunk/test/rubygems/test_gem_specification.rb
    trunk/test/rubygems/test_gem_stream_ui.rb
    trunk/test/rubygems/test_gem_uninstaller.rb
    trunk/test/rubygems/test_gem_version.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 19546)
+++ ChangeLog	(revision 19547)
@@ -1,3 +1,7 @@
+Thu Sep 25 19:13:12 2008
+
+	* lib/rubygems*: Update to RubyGems 1.3.0 r1891.
+
 Thu Sep 25 18:40:42 2008  Yuki Sonoda (Yugui)  <yugui@y...>
 
 	* class.c (rb_make_metaclass): Made class of class of class
Index: lib/rubygems/local_remote_options.rb
===================================================================
--- lib/rubygems/local_remote_options.rb	(revision 19546)
+++ lib/rubygems/local_remote_options.rb	(revision 19547)
@@ -110,6 +110,13 @@
   end
 
   ##
+  # Is fetching of local and remote information enabled?
+
+  def both?
+    options[:domain] == :both
+  end
+
+  ##
   # Is local fetching enabled?
 
   def local?
Index: lib/rubygems/spec_fetcher.rb
===================================================================
--- lib/rubygems/spec_fetcher.rb	(revision 19546)
+++ lib/rubygems/spec_fetcher.rb	(revision 19547)
@@ -167,7 +167,7 @@
 
       if all and @specs.include? source_uri then
         list[source_uri] = @specs[source_uri]
-      elsif @latest_specs.include? source_uri then
+      elsif not all and @latest_specs.include? source_uri then
         list[source_uri] = @latest_specs[source_uri]
       else
         specs = load_specs source_uri, file
@@ -182,6 +182,10 @@
     list
   end
 
+  ##
+  # Loads specs in +file+, fetching from +source_uri+ if the on-disk cache is
+  # out of date.
+
   def load_specs(source_uri, file)
     file_name  = "#{file}.#{Gem.marshal_version}"
     spec_path  = source_uri + "#{file_name}.gz"
@@ -192,7 +196,7 @@
     if File.exist? local_file then
       spec_dump = @fetcher.fetch_path spec_path, File.mtime(local_file)
 
-      if spec_dump.empty? then
+      if spec_dump.nil? then
         spec_dump = Gem.read_binary local_file
       else
         loaded = true
Index: lib/rubygems/dependency_installer.rb
===================================================================
--- lib/rubygems/dependency_installer.rb	(revision 19546)
+++ lib/rubygems/dependency_installer.rb	(revision 19547)
@@ -38,9 +38,17 @@
   # :ignore_dependencies:: Don't install any dependencies.
   # :install_dir:: See Gem::Installer#install.
   # :security_policy:: See Gem::Installer::new and Gem::Security.
+  # :user_install:: See Gem::Installer.new
   # :wrappers:: See Gem::Installer::new
 
   def initialize(options = {})
+    if options[:install_dir] then
+      spec_dir = options[:install_dir], 'specifications'
+      @source_index = Gem::SourceIndex.from_gems_in spec_dir
+    else
+      @source_index = Gem.source_index
+    end
+
     options = DEFAULT_OPTIONS.merge options
 
     @bin_dir = options[:bin_dir]
@@ -51,19 +59,13 @@
     @format_executable = options[:format_executable]
     @ignore_dependencies = options[:ignore_dependencies]
     @security_policy = options[:security_policy]
+    @user_install = options[:user_install]
     @wrappers = options[:wrappers]
 
     @installed_gems = []
 
     @install_dir = options[:install_dir] || Gem.dir
     @cache_dir = options[:cache_dir] || @install_dir
-
-    if options[:install_dir] then
-      spec_dir = File.join @install_dir, 'specifications'
-      @source_index = Gem::SourceIndex.from_gems_in spec_dir
-    else
-      @source_index = Gem.source_index
-    end
   end
 
   ##
@@ -232,15 +234,17 @@
       end
 
       inst = Gem::Installer.new local_gem_path,
-                                :env_shebang => @env_shebang,
-                                :force => @force,
-                                :format_executable => @format_executable,
+                                :bin_dir             => @bin_dir,
+                                :development         => @development,
+                                :env_shebang         => @env_shebang,
+                                :force               => @force,
+                                :format_executable   => @format_executable,
                                 :ignore_dependencies => @ignore_dependencies,
-                                :install_dir => @install_dir,
-                                :security_policy => @security_policy,
-                                :wrappers => @wrappers,
-                                :bin_dir => @bin_dir,
-                                :development => @development
+                                :install_dir         => @install_dir,
+                                :security_policy     => @security_policy,
+                                :source_index        => @source_index,
+                                :user_install        => @user_install,
+                                :wrappers            => @wrappers
 
       spec = inst.install
 
Index: lib/rubygems/doc_manager.rb
===================================================================
--- lib/rubygems/doc_manager.rb	(revision 19546)
+++ lib/rubygems/doc_manager.rb	(revision 19547)
@@ -5,133 +5,195 @@
 #++
 
 require 'fileutils'
+require 'rubygems'
 
-module Gem
+##
+# The documentation manager generates RDoc and RI for RubyGems.
 
-  class DocManager
+class Gem::DocManager
 
-    include UserInteraction
+  include Gem::UserInteraction
 
-    # Create a document manager for the given gem spec.
-    #
-    # spec::      The Gem::Specification object representing the gem.
-    # rdoc_args:: Optional arguments for RDoc (template etc.) as a String.
-    #
-    def initialize(spec, rdoc_args="")
-      @spec = spec
-      @doc_dir = File.join(spec.installation_path, "doc", spec.full_name)
-      @rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split
-    end
+  @configured_args = []
 
-    # Is the RDoc documentation installed?
-    def rdoc_installed?
-      return File.exist?(File.join(@doc_dir, "rdoc"))
+  def self.configured_args
+    @configured_args ||= []
+  end
+
+  def self.configured_args=(args)
+    case args
+    when Array
+      @configured_args = args
+    when String
+      @configured_args = args.split
     end
+  end
 
-    # Generate the RI documents for this gem spec.
-    #
-    # Note that if both RI and RDoc documents are generated from the
-    # same process, the RI docs should be done first (a likely bug in
-    # RDoc will cause RI docs generation to fail if run after RDoc).
-    def generate_ri
-      if @spec.has_rdoc then
-        load_rdoc
-        install_ri # RDoc bug, ri goes first
-      end
+  ##
+  # Load RDoc from a gem if it is available, otherwise from Ruby's stdlib
 
-      FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
+  def self.load_rdoc
+    begin
+      gem 'rdoc'
+    rescue Gem::LoadError
+      # use built-in RDoc
     end
 
-    # Generate the RDoc documents for this gem spec.
-    #
-    # Note that if both RI and RDoc documents are generated from the
-    # same process, the RI docs should be done first (a likely bug in
-    # RDoc will cause RI docs generation to fail if run after RDoc).
-    def generate_rdoc
-      if @spec.has_rdoc then
-        load_rdoc
-        install_rdoc
-      end
-
-      FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
+    begin
+      require 'rdoc/rdoc'
+    rescue LoadError => e
+      raise Gem::DocumentError,
+          "ERROR: RDoc documentation generator not installed!"
     end
+  end
 
-    # Load the RDoc documentation generator library.
-    def load_rdoc
-      if File.exist?(@doc_dir) && !File.writable?(@doc_dir) then
-        raise Gem::FilePermissionError.new(@doc_dir)
-      end
+  ##
+  # Updates the RI cache for RDoc 2 if it is installed
 
-      FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
+  def self.update_ri_cache
+    load_rdoc rescue return
 
-      begin
-        gem 'rdoc'
-      rescue Gem::LoadError
-        # use built-in RDoc
-      end
+    return unless defined? RDoc::VERSION # RDoc 1 does not have VERSION
 
-      begin
-        require 'rdoc/rdoc'
-      rescue LoadError => e
-        raise Gem::DocumentError,
-          "ERROR: RDoc documentation generator not installed!"
-      end
-    end
+    require 'rdoc/ri/driver'
 
-    def install_rdoc
-      rdoc_dir = File.join @doc_dir, 'rdoc'
+    options = {
+      :use_cache => true,
+      :use_system => true,
+      :use_site => true,
+      :use_home => true,
+      :use_gems => true,
+      :formatter => RDoc::RI::Formatter,
+    }
 
-      FileUtils.rm_rf rdoc_dir
+    driver = RDoc::RI::Driver.new(options).class_cache
+  end
 
-      say "Installing RDoc documentation for #{@spec.full_name}..."
-      run_rdoc '--op', rdoc_dir
+  ##
+  # Create a document manager for +spec+. +rdoc_args+ contains arguments for
+  # RDoc (template etc.) as a String.
+
+  def initialize(spec, rdoc_args="")
+    @spec = spec
+    @doc_dir = File.join(spec.installation_path, "doc", spec.full_name)
+    @rdoc_args = rdoc_args.nil? ? [] : rdoc_args.split
+  end
+
+  ##
+  # Is the RDoc documentation installed?
+
+  def rdoc_installed?
+    File.exist?(File.join(@doc_dir, "rdoc"))
+  end
+
+  ##
+  # Generate the RI documents for this gem spec.
+  #
+  # Note that if both RI and RDoc documents are generated from the same
+  # process, the RI docs should be done first (a likely bug in RDoc will cause
+  # RI docs generation to fail if run after RDoc).
+
+  def generate_ri
+    if @spec.has_rdoc then
+      setup_rdoc
+      install_ri # RDoc bug, ri goes first
     end
 
-    def install_ri
-      ri_dir = File.join @doc_dir, 'ri'
+    FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
+  end
 
-      FileUtils.rm_rf ri_dir
+  ##
+  # Generate the RDoc documents for this gem spec.
+  #
+  # Note that if both RI and RDoc documents are generated from the same
+  # process, the RI docs should be done first (a likely bug in RDoc will cause
+  # RI docs generation to fail if run after RDoc).
 
-      say "Installing ri documentation for #{@spec.full_name}..."
-      run_rdoc '--ri', '--op', ri_dir
+  def generate_rdoc
+    if @spec.has_rdoc then
+      setup_rdoc
+      install_rdoc
     end
 
-    def run_rdoc(*args)
-      args << @spec.rdoc_options
-      args << DocManager.configured_args
-      args << '--quiet'
-      args << @spec.require_paths.clone
-      args << @spec.extra_rdoc_files
-      args = args.flatten.map do |arg| arg.to_s end
+    FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
+  end
 
-      r = RDoc::RDoc.new
+  ##
+  # Generate and install RDoc into the documentation directory
 
-      old_pwd = Dir.pwd
-      Dir.chdir(@spec.full_gem_path)
-      begin
-        r.document args
-      rescue Errno::EACCES => e
-        dirname = File.dirname e.message.split("-")[1].strip
-        raise Gem::FilePermissionError.new(dirname)
-      rescue RuntimeError => ex
-        alert_error "While generating documentation for #{@spec.full_name}"
-        ui.errs.puts "... MESSAGE:   #{ex}"
-        ui.errs.puts "... RDOC args: #{args.join(' ')}"
-        ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
-          Gem.configuration.backtrace
-        ui.errs.puts "(continuing with the rest of the installation)"
-      ensure
-        Dir.chdir(old_pwd)
-      end
+  def install_rdoc
+    rdoc_dir = File.join @doc_dir, 'rdoc'
+
+    FileUtils.rm_rf rdoc_dir
+
+    say "Installing RDoc documentation for #{@spec.full_name}..."
+    run_rdoc '--op', rdoc_dir
+  end
+
+  ##
+  # Generate and install RI into the documentation directory
+
+  def install_ri
+    ri_dir = File.join @doc_dir, 'ri'
+
+    FileUtils.rm_rf ri_dir
+
+    say "Installing ri documentation for #{@spec.full_name}..."
+    run_rdoc '--ri', '--op', ri_dir
+  end
+
+  ##
+  # Run RDoc with +args+, which is an ARGV style argument list
+
+  def run_rdoc(*args)
+    args << @spec.rdoc_options
+    args << self.class.configured_args
+    args << '--quiet'
+    args << @spec.require_paths.clone
+    args << @spec.extra_rdoc_files
+    args = args.flatten.map do |arg| arg.to_s end
+
+    r = RDoc::RDoc.new
+
+    old_pwd = Dir.pwd
+    Dir.chdir(@spec.full_gem_path)
+    begin
+      r.document args
+    rescue Errno::EACCES => e
+      dirname = File.dirname e.message.split("-")[1].strip
+      raise Gem::FilePermissionError.new(dirname)
+    rescue RuntimeError => ex
+      alert_error "While generating documentation for #{@spec.full_name}"
+      ui.errs.puts "... MESSAGE:   #{ex}"
+      ui.errs.puts "... RDOC args: #{args.join(' ')}"
+      ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
+      Gem.configuration.backtrace
+      ui.errs.puts "(continuing with the rest of the installation)"
+    ensure
+      Dir.chdir(old_pwd)
     end
+  end
 
-    def uninstall_doc
-      raise Gem::FilePermissionError.new(@spec.installation_path) unless
-        File.writable? @spec.installation_path
+  def setup_rdoc
+    if File.exist?(@doc_dir) && !File.writable?(@doc_dir) then
+      raise Gem::FilePermissionError.new(@doc_dir)
+    end
 
-      original_name = [
-        @spec.name, @spec.version, @spec.original_platform].join '-'
+    FileUtils.mkdir_p @doc_dir unless File.exist?(@doc_dir)
 
+    self.class.load_rdoc
+  end
+
+  ##
+  # Remove RDoc and RI documentation
+
+  def uninstall_doc
+    raise Gem::FilePermissionError.new(@spec.installation_path) unless
+    File.writable? @spec.installation_path
+
+    original_name = [
+      @spec.name, @spec.version, @spec.original_platform].join '-'
+
       doc_dir = File.join @spec.installation_path, 'doc', @spec.full_name
       unless File.directory? doc_dir then
         doc_dir = File.join @spec.installation_path, 'doc', original_name
@@ -146,22 +208,7 @@
       end
 
       FileUtils.rm_rf ri_dir
-    end
+  end
 
-    class << self
-      def configured_args
-        @configured_args ||= []
-      end
+end
 
-      def configured_args=(args)
-        case args
-        when Array
-          @configured_args = args
-        when String
-          @configured_args = args.split
-        end
-      end
-    end
-    
-  end
-end
Index: lib/rubygems/config_file.rb
===================================================================
--- lib/rubygems/config_file.rb	(revision 19546)
+++ lib/rubygems/config_file.rb	(revision 19547)
@@ -49,6 +49,9 @@
   # List of arguments supplied to the config file object.
   attr_reader :args
 
+  # Where to look for gems
+  attr_accessor :path
+
   # True if we print backtraces on errors.
   attr_writer :backtrace
 
@@ -123,9 +126,10 @@
     @backtrace = @hash[:backtrace] if @hash.key? :backtrace
     @benchmark = @hash[:benchmark] if @hash.key? :benchmark
     @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
-    Gem.sources.replace @hash[:sources] if @hash.key? :sources
+    Gem.sources = @hash[:sources] if @hash.key? :sources
     @verbose = @hash[:verbose] if @hash.key? :verbose
     @update_sources = @hash[:update_sources] if @hash.key? :update_sources
+    @path = @hash[:gempath]
 
     handle_arguments arg_list
   end
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 19546)
+++ lib/rubygems/specification.rb	(revision 19547)
@@ -24,6 +24,7 @@
 
 module Gem
 
+  ##
   # == Gem::Specification
   #
   # The Specification class contains the metadata for a Gem.  Typically
@@ -38,7 +39,7 @@
   #
   # There are many <em>gemspec attributes</em>, and the best place to learn
   # about them in the "Gemspec Reference" linked from the RubyGems wiki.
-  #
+
   class Specification
 
     ##
@@ -46,8 +47,6 @@
 
     attr_accessor :original_platform # :nodoc:
 
-    # ------------------------- Specification version constants.
-
     ##
     # The the version number of a specification that does not specify one
     # (i.e. RubyGems 0.7 or earlier).
@@ -88,77 +87,98 @@
     TODAY = now - ((now.to_i + now.gmt_offset) % 86400)
     # :startdoc:
 
-    # ------------------------- Class variables.
+    ##
+    # List of Specification instances.
 
-    # List of Specification instances.
     @@list = []
 
+    ##
     # Optional block used to gather newly defined instances.
+
     @@gather = nil
 
+    ##
     # List of attribute names: [:name, :version, ...]
     @@required_attributes = []
 
-    # List of _all_ attributes and default values: [[:name, nil], [:bindir, 'bin'], ...]
+    ##
+    # List of _all_ attributes and default values:
+    #
+    #   [[:name, nil],
+    #    [:bindir, 'bin'],
+    #    ...]
+
     @@attributes = []
 
     @@nil_attributes = []
     @@non_nil_attributes = [:@original_platform]
 
+    ##
     # List of array attributes
+
     @@array_attributes = []
 
+    ##
     # Map of attribute names to default values.
+
     @@default_value = {}
 
-    # ------------------------- Convenience class methods.
+    ##
+    # Names of all specification attributes
 
     def self.attribute_names
       @@attributes.map { |name, default| name }
     end
 
+    ##
+    # Default values for specification attributes
+
     def self.attribute_defaults
       @@attributes.dup
     end
 
+    ##
+    # The default value for specification attribute +name+
+
     def self.default_value(name)
       @@default_value[name]
     end
 
+    ##
+    # Required specification attributes
+
     def self.required_attributes
       @@required_attributes.dup
     end
 
+    ##
+    # Is +name+ a required attribute?
+
     def self.required_attribute?(name)
       @@required_attributes.include? name.to_sym
     end
 
+    ##
+    # Specification attributes that are arrays (appendable and so-forth)
+
     def self.array_attributes
       @@array_attributes.dup
     end
 
-    # ------------------------- Infrastructure class methods.
+    ##
+    # A list of Specification instances that have been defined in this Ruby
+    # instance.
 
-    # A list of Specification instances that have been defined in this Ruby instance.
     def self.list
       @@list
     end
 
-    # Used to specify the name and default value of a specification
-    # attribute.  The side effects are:
-    # * the name and default value are added to the @@attributes list
-    #   and @@default_value map
-    # * a standard _writer_ method (<tt>attribute=</tt>) is created
-    # * a non-standard _reader method (<tt>attribute</tt>) is created
+    ##
+    # Specifies the +name+ and +default+ for a specification attribute, and
+    # creates a reader and writer method like Module#attr_accessor.
     #
-    # The reader method behaves like this:
-    #   def attribute
-    #     @attribute ||= (copy of default value)
-    #   end
-    #
-    # This allows lazy initialization of attributes to their default
-    # values. 
-    #
+    # The reader method returns the default if the value hasn't been set.
+
     def self.attribute(name, default=nil)
       ivar_name = "@#{name}".intern
       if default.nil? then
@@ -172,8 +192,10 @@
       attr_accessor(name)
     end
 
-    # Same as :attribute, but ensures that values assigned to the
-    # attribute are array values by applying :to_a to the value.
+    ##
+    # Same as :attribute, but ensures that values assigned to the attribute
+    # are array values by applying :to_a to the value.
+
     def self.array_attribute(name)
       @@non_nil_attributes << ["@#{name}".intern, []]
 
@@ -192,51 +214,60 @@
       module_eval code, __FILE__, __LINE__ - 9
     end
 
+    ##
     # Same as attribute above, but also records this attribute as mandatory.
+
     def self.required_attribute(*args)
       @@required_attributes << args.first
       attribute(*args)
     end
 
-    # Sometimes we don't want the world to use a setter method for a particular attribute.
+    ##
+    # Sometimes we don't want the world to use a setter method for a
+    # particular attribute.
+    #
     # +read_only+ makes it private so we can still use it internally.
+
     def self.read_only(*names)
       names.each do |name|
         private "#{name}="
       end
     end
 
-    # Shortcut for creating several attributes at once (each with a default value of
-    # +nil+).
+    # Shortcut for creating several attributes at once (each with a default
+    # value of +nil+).
+
     def self.attributes(*args)
       args.each do |arg|
         attribute(arg, nil)
       end
     end
 
-    # Some attributes require special behaviour when they are accessed.  This allows for
-    # that.
+    ##
+    # Some attributes require special behaviour when they are accessed.  This
+    # allows for that.
+
     def self.overwrite_accessor(name, &block)
       remove_method name
       define_method(name, &block)
     end
 
-    # Defines a _singular_ version of an existing _plural_ attribute
-    # (i.e. one whose value is expected to be an array).  This means
-    # just creating a helper method that takes a single value and
-    # appends it to the array.  These are created for convenience, so
-    # that in a spec, one can write 
+    ##
+    # Defines a _singular_ version of an existing _plural_ attribute (i.e. one
+    # whose value is expected to be an array).  This means just creating a
+    # helper method that takes a single value and appends it to the array.
+    # These are created for convenience, so that in a spec, one can write 
     #
     #   s.require_path = 'mylib'
     #
-    # instead of
+    # instead of:
     #
     #   s.require_paths = ['mylib']
     #
-    # That above convenience is available courtesy of
+    # That above convenience is available courtesy of:
     #
     #   attribute_alias_singular :require_path, :require_paths 
-    #
+
     def self.attribute_alias_singular(singular, plural)
       define_method("#{singular}=") { |val|
         send("#{plural}=", [val])
@@ -320,190 +351,46 @@
       spec
     end
 
-    # REQUIRED gemspec attributes ------------------------------------
-    
-    required_attribute :rubygems_version, Gem::RubyGemsVersion
-    required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
-    required_attribute :name
-    required_attribute :version
-    required_attribute :date, TODAY
-    required_attribute :summary
-    required_attribute :require_paths, ['lib']
+    ##
+    # List of depedencies that will automatically be activated at runtime.
 
-    # OPTIONAL gemspec attributes ------------------------------------
-    
-    attributes :email, :homepage, :rubyforge_project, :description
-    attributes :autorequire, :default_executable
-
-    attribute :bindir,                     'bin'
-    attribute :has_rdoc,                   false
-    attribute :required_ruby_version,      Gem::Requirement.default
-    attribute :required_rubygems_version,  Gem::Requirement.default
-    attribute :platform,                   Gem::Platform::RUBY
-
-    attribute :signing_key,            nil
-    attribute :cert_chain,             []
-    attribute :post_install_message,   nil
-
-    array_attribute :authors
-    array_attribute :files
-    array_attribute :test_files
-    array_attribute :rdoc_options
-    array_attribute :extra_rdoc_files
-    array_attribute :executables
-
-    # Array of extensions to build.  See Gem::Installer#build_extensions for
-    # valid values.
-
-    array_attribute :extensions
-    array_attribute :requirements
-    array_attribute :dependencies
-
-    read_only :dependencies
-
     def runtime_dependencies
       dependencies.select { |d| d.type == :runtime || d.type == nil }
     end
 
+    ##
+    # List of dependencies that are used for development
+
     def development_dependencies
       dependencies.select { |d| d.type == :development }
     end
 
-    # ALIASED gemspec attributes -------------------------------------
-    
-    attribute_alias_singular :executable,   :executables
-    attribute_alias_singular :author,   :authors
-    attribute_alias_singular :require_path, :require_paths
-    attribute_alias_singular :test_file,    :test_files
-
-    # DEPRECATED gemspec attributes ----------------------------------
-    
-    def test_suite_file
+    def test_suite_file # :nodoc:
       warn 'test_suite_file deprecated, use test_files'
       test_files.first
     end
 
-    def test_suite_file=(val)
+    def test_suite_file=(val) # :nodoc:
       warn 'test_suite_file= deprecated, use test_files='
       @test_files = [] unless defined? @test_files
       @test_files << val
     end
 
+    ##
     # true when this gemspec has been loaded from a specifications directory.
     # This attribute is not persisted.
 
-    attr_writer :loaded
+    attr_accessor :loaded
 
+    ##
     # Path this gemspec was loaded from.  This attribute is not persisted.
+
     attr_accessor :loaded_from
 
-    # Special accessor behaviours (overwriting default) --------------
-    
-    overwrite_accessor :version= do |version|
-      @version = Version.create(version)
-    end
+    ##
+    # Returns an array with bindir attached to each executable in the
+    # executables list
 
-    overwrite_accessor :platform do
-      @new_platform
-    end
-
-    overwrite_accessor :platform= do |platform|
-      if @original_platform.nil? or
-         @original_platform == Gem::Platform::RUBY then
-        @original_platform = platform
-      end
-
-      case platform
-      when Gem::Platform::CURRENT then
-        @new_platform = Gem::Platform.local
-        @original_platform = @new_platform.to_s
-
-      when Gem::Platform then
-        @new_platform = platform
-
-      # legacy constants
-      when nil, Gem::Platform::RUBY then
-        @new_platform = Gem::Platform::RUBY
-      when 'mswin32' then # was Gem::Platform::WIN32
-        @new_platform = Gem::Platform.new 'x86-mswin32'
-      when 'i586-linux' then # was Gem::Platform::LINUX_586
-        @new_platform = Gem::Platform.new 'x86-linux'
-      when 'powerpc-darwin' then # was Gem::Platform::DARWIN
-        @new_platform = Gem::Platform.new 'ppc-darwin'
-      else
-        @new_platform = Gem::Platform.new platform
-      end
-
-      @platform = @new_platform.to_s
-
-      @new_platform
-    end
-
-    overwrite_accessor :required_ruby_version= do |value|
-      @required_ruby_version = Gem::Requirement.create(value)
-    end
-
-    overwrite_accessor :required_rubygems_version= do |value|
-      @required_rubygems_version = Gem::Requirement.create(value)
-    end
-
-    overwrite_accessor :date= do |date|
-      # We want to end up with a Time object with one-day resolution.
-      # This is the cleanest, most-readable, faster-than-using-Date
-      # way to do it.
-      case date
-      when String then
-        @date = if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
-                  Time.local($1.to_i, $2.to_i, $3.to_i)
-                else
-                  require 'time'
-                  Time.parse date
-                end
-      when Time then
-        @date = Time.local(date.year, date.month, date.day)
-      when Date then
-        @date = Time.local(date.year, date.month, date.day)
-      else
-        @date = TODAY
-      end
-    end
-
-    overwrite_accessor :date do
-      self.date = nil if @date.nil?  # HACK Sets the default value for date
-      @date
-    end
-
-    overwrite_accessor :summary= do |str|
-      @summary = if str then
-                   str.strip.
-                   gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').
-                   gsub(/\n[ \t]*/, " ")
-                 end
-    end
-
-    overwrite_accessor :description= do |str|
-      @description = if str then
-                       str.strip.
-                       gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').
-                       gsub(/\n[ \t]*/, " ")
-                     end
-    end
-
-    overwrite_accessor :default_executable do
-      begin
-        if defined?(@default_executable) and @default_executable
-          result = @default_executable
-        elsif @executables and @executables.size == 1
-          result = Array(@executables).first
-        else
-          result = nil
-        end
-        result
-      rescue
-        nil
-      end
-    end
-
     def add_bindir(executables)
       return nil if executables.nil?
 
@@ -516,17 +403,9 @@
       return nil
     end
 
-    overwrite_accessor :files do
-      result = []
-      result.push(*@files) if defined?(@files)
-      result.push(*@test_files) if defined?(@test_files)
-      result.push(*(add_bindir(@executables)))
-      result.push(*@extra_rdoc_files) if defined?(@extra_rdoc_files)
-      result.push(*@extensions) if defined?(@extensions)
-      result.uniq.compact
-    end
+    ##
+    # Files in the Gem under one of the require_paths
 
-    # Files in the Gem under one of the require_paths
     def lib_files
       @files.select do |file|
         require_paths.any? do |path|
@@ -535,34 +414,25 @@
       end
     end
 
-    overwrite_accessor :test_files do
-      # Handle the possibility that we have @test_suite_file but not
-      # @test_files.  This will happen when an old gem is loaded via
-      # YAML.
-      if defined? @test_suite_file then
-        @test_files = [@test_suite_file].flatten
-        @test_suite_file = nil
-      end
-      if defined?(@test_files) and @test_files then
-        @test_files
-      else
-        @test_files = []
-      end
+    ##
+    # True if this gem was loaded from disk
+
+    alias :loaded? :loaded
+
+    ##
+    # True if this gem has files in test_files
+
+    def has_unit_tests?
+      not test_files.empty?
     end
 
-    # Predicates -----------------------------------------------------
+    alias has_test_suite? has_unit_tests? # :nodoc: deprecated
     
-    def loaded?; @loaded ? true : false ; end
-    def has_rdoc?; has_rdoc ? true : false ; end
-    def has_unit_tests?; not test_files.empty?; end
-    alias has_test_suite? has_unit_tests?               # (deprecated)
-    
-    # Constructors ---------------------------------------------------
-    
+    ##
     # Specification constructor.  Assigns the default values to the
     # attributes, adds this spec to the list of loaded specs (see
     # Specification.list), and yields itself for further initialization.
-    #
+
     def initialize
       @new_platform = nil
       assign_defaults
@@ -575,11 +445,13 @@
       @@gather.call(self) if @@gather
     end
 
-    # Each attribute has a default value (possibly nil).  Here, we
-    # initialize all attributes to their default value.  This is
-    # done through the accessor methods, so special behaviours will
-    # be honored.  Furthermore, we take a _copy_ of the default so
-    # each specification instance has its own empty arrays, etc.
+    ##
+    # Each attribute has a default value (possibly nil).  Here, we initialize
+    # all attributes to their default value.  This is done through the
+    # accessor methods, so special behaviours will be honored.  Furthermore,
+    # we take a _copy_ of the default so each specification instance has its
+    # own empty arrays, etc.
+
     def assign_defaults
       @@nil_attributes.each do |name|
         instance_variable_set name, nil
@@ -598,13 +470,14 @@
       instance_variable_set :@new_platform, Gem::Platform::RUBY
     end
 
-    # Special loader for YAML files.  When a Specification object is
-    # loaded from a YAML file, it bypasses the normal Ruby object
-    # initialization routine (#initialize).  This method makes up for
-    # that and deals with gems of different ages.
+    ##
+    # Special loader for YAML files.  When a Specification object is loaded
+    # from a YAML file, it bypasses the normal Ruby object initialization
+    # routine (#initialize).  This method makes up for that and deals with
+    # gems of different ages.
     #
     # 'input' can be anything that YAML.load() accepts: String or IO. 
-    #
+
     def self.from_yaml(input)
       input = normalize_yaml_input input
       spec = YAML.load input
@@ -627,6 +500,9 @@
       spec
     end 
 
+    ##
+    # Loads ruby format gemspec from +filename+
+
     def self.load(filename)
       gemspec = nil
       fail "NESTED Specification.load calls not allowed!" if @@gather
@@ -638,22 +514,25 @@
       @@gather = nil
     end
 
-    # Make sure the yaml specification is properly formatted with dashes.
+    ##
+    # Make sure the YAML specification is properly formatted with dashes
+
     def self.normalize_yaml_input(input)
       result = input.respond_to?(:read) ? input.read : input
       result = "--- " + result unless result =~ /^--- /
       result
     end
     
-    # Instance methods -----------------------------------------------
-    
-    # Sets the rubygems_version to Gem::RubyGemsVersion.
-    #
+    ##
+    # Sets the rubygems_version to the current RubyGems version
+
     def mark_version
       @rubygems_version = RubyGemsVersion
     end
 
-    # Ignore unknown attributes if the 
+    ##
+    # Ignore unknown attributes while loading
+
     def method_missing(sym, *a, &b) # :nodoc:
       if @specification_version > CURRENT_SPECIFICATION_VERSION and
          sym.to_s =~ /=$/ then
@@ -663,35 +542,39 @@
       end
     end
 
-    # Adds a development dependency to this Gem.  For example,
+    ##
+    # Adds a development dependency named +gem+ with +requirements+ to this
+    # Gem.  For example:
     #
-    #   spec.add_development_dependency('jabber4r', '> 0.1', '<= 0.5')
+    #   spec.add_development_dependency 'jabber4r', '> 0.1', '<= 0.5'
     #
-    # Development dependencies aren't installed by default, and
-    # aren't activated when a gem is required.
-    #
-    # gem:: [String or Gem::Dependency] The Gem name/dependency.
-    # requirements:: [default=">= 0"] The version requirements.
+    # Development dependencies aren't installed by default and aren't
+    # activated when a gem is required.
+
     def add_development_dependency(gem, *requirements)
       add_dependency_with_type(gem, :development, *requirements)
     end
 
-    # Adds a runtime dependency to this Gem.  For example,
+    ##
+    # Adds a runtime dependency named +gem+ with +requirements+ to this Gem.
+    # For example:
     #
-    #   spec.add_runtime_dependency('jabber4r', '> 0.1', '<= 0.5')
-    #
-    # gem:: [String or Gem::Dependency] The Gem name/dependency.
-    # requirements:: [default=">= 0"] The version requirements.
+    #   spec.add_runtime_dependency 'jabber4r', '> 0.1', '<= 0.5'
+
     def add_runtime_dependency(gem, *requirements)
       add_dependency_with_type(gem, :runtime, *requirements)
     end
 
+    ##
+    # Adds a runtime dependency
+
     alias add_dependency add_runtime_dependency
 
+    ##
     # 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).
-    #
+    # is included (name-version-platform) if it is specified and not the
+    # default Ruby platform.
+
     def full_name
       if platform == Gem::Platform::RUBY or platform.nil? then
         "#{@name}-#{@version}"
@@ -700,9 +583,10 @@
       end
     end
 
+    ##
     # Returns the full name (name-version) of this gemspec using the original
-    # platform.
-    #
+    # platform.  For use with legacy gems.
+
     def original_name # :nodoc:
       if platform == Gem::Platform::RUBY or platform.nil? then
         "#{@name}-#{@version}"
@@ -736,18 +620,16 @@
       File.expand_path path
     end
 
-    # Checks if this Specification meets the requirement of the supplied
-    # dependency.
-    # 
-    # dependency:: [Gem::Dependency] the dependency to check
-    # return:: [Boolean] true if dependency is met, otherwise false
-    #
+    ##
+    # Checks if this specification meets the requirement of +dependency+.
+
     def satisfies_requirement?(dependency)
       return @name == dependency.name && 
         dependency.version_requirements.satisfied_by?(@version)
     end
 
-    # Comparison methods ---------------------------------------------
+    ##
+    # Returns an object you can use to sort specifications in #sort_by.
 
     def sort_obj
       [@name, @version.to_ints, @new_platform == Gem::Platform::RUBY ? -1 : 1]
@@ -757,19 +639,25 @@
       sort_obj <=> other.sort_obj
     end
 
+    ##
     # Tests specs for equality (across all attributes).
+
     def ==(other) # :nodoc:
       self.class === other && same_attributes?(other)
     end
 
     alias eql? == # :nodoc:
 
+    ##
+    # True if this gem has the same attributes as +other+.
+
     def same_attributes?(other)
       @@attributes.each do |name, default|
         return false unless self.send(name) == other.send(name)
       end
       true
     end
+
     private :same_attributes?
 
     def hash # :nodoc:
@@ -779,8 +667,6 @@
       }
     end
 
-    # Export methods (YAML and Ruby code) ----------------------------
-
     def to_yaml(opts = {}) # :nodoc:
       mark_version
 
@@ -825,6 +711,8 @@
     def to_ruby
       mark_version
       result = []
+      result << "# -*- encoding: utf-8 -*-"
+      result << nil
       result << "Gem::Specification.new do |s|"
 
       result << "  s.name = #{ruby_code name}"
@@ -861,7 +749,7 @@
       result << "    s.specification_version = #{specification_version}"
       result << nil
 
-      result << "    if current_version >= 3 then"
+      result << "    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then"
 
       unless dependencies.empty? then
         dependencies.each do |dep|
@@ -895,16 +783,15 @@
       result.join "\n"
     end
 
-    # Validation and normalization methods ---------------------------
+    ##
+    # Checks that the specification contains all required fields, and does a
+    # very basic sanity check.
+    #
+    # Raises InvalidSpecificationException if the spec does not pass the
+    # checks..
 
-    # Checks that the specification contains all required fields, and
-    # does a very basic sanity check.
-    #
-    # Raises InvalidSpecificationException if the spec does not pass
-    # the checks..
     def validate
       extend Gem::UserInteraction
-
       normalize
 
       if rubygems_version != RubyGemsVersion then
@@ -959,13 +846,14 @@
       true
     end
 
+    ##
     # Normalize the list of files so that:
     # * All file lists have redundancies removed.
-    # * Files referenced in the extra_rdoc_files are included in the
-    #   package file list. 
+    # * Files referenced in the extra_rdoc_files are included in the package
+    #   file list. 
     #
-    # Also, the summary and description are converted to a normal
-    # format. 
+    # Also, the summary and description are converted to a normal format. 
+
     def normalize
       if defined?(@extra_rdoc_files) and @extra_rdoc_files then
         @extra_rdoc_files.uniq!
@@ -975,15 +863,12 @@
       @files.uniq! if @files
     end
 
-    # Dependency methods ---------------------------------------------
-    
-    # Return a list of all gems that have a dependency on this
-    # gemspec.  The list is structured with entries that conform to:
+    ##
+    # Return a list of all gems that have a dependency on this gemspec.  The
+    # list is structured with entries that conform to:
     #
     #   [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
-    #
-    # return:: [Array] [[dependent_gem, dependency, [list_of_satisfiers]]]
-    #
+
     def dependent_gems
       out = []
       Gem.source_index.each do |name,gem|
@@ -1004,8 +889,6 @@
       "#<Gem::Specification name=#{@name} version=#{@version}>"
     end
 
-    private
-
     def add_dependency_with_type(dependency, type, *requirements)
       requirements = if requirements.empty? then
                        Gem::Requirement.default
@@ -1022,6 +905,8 @@
       dependencies << dependency
     end
 
+    private :add_dependency_with_type
+
     def find_all_satisfiers(dep)
       Gem.source_index.each do |name,gem|
         if(gem.satisfies_requirement?(dep)) then
@@ -1030,8 +915,12 @@
       end
     end
 
-    # Return a string containing a Ruby code representation of the
-    # given object.
+    private :find_all_satisfiers
+
+    ##
+    # Return a string containing a Ruby code representation of the given
+    # object.
+
     def ruby_code(obj)
       case obj
       when String            then '%q{' + obj + '}'
@@ -1046,7 +935,327 @@
       else raise Exception, "ruby_code case not handled: #{obj.class}"
       end
     end
+    
+    private :ruby_code
 
+    # :section: Required gemspec attributes
+    
+    ##
+    # The version of RubyGems used to create this gem
+
+    required_attribute :rubygems_version, Gem::RubyGemsVersion
+
+    ##
+    # The Gem::Specification version of this gemspec
+
+    required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
+
+    ##
+    # This gem's name
+
+    required_attribute :name
+
+    ##
+    # This gem's version
+
+    required_attribute :version
+
+    ##
+    # The date this gem was created
+
+    required_attribute :date, TODAY
+
+    ##
+    # A short summary of this gem's description.  Displayed in `gem list -d`.
+
+    required_attribute :summary
+
+    ##
+    # Paths in the gem to add to $LOAD_PATH when this gem is activated
+
+    required_attribute :require_paths, ['lib']
+
+    # :section: Optional gemspec attributes
+
+    ##
+    # A contact email for this gem
+    
+    attribute :email
+
+    ##
+    # The URL of this gem's home page
+
+    attribute :homepage
+
+    ##
+    # The rubyforge project this gem lives under.  i.e. RubyGems'
+    # rubyforge_project is "rubygems".
+    
+    attribute :rubyforge_project
+
+    ##
+    # A long description of this gem
+
+    attribute :description
+
+    ##
+    # Autorequire was used by old RubyGems to automatically require a file.
+    # It no longer is supported.
+
+    attribute :autorequire
+
+    ##
+    # The default executable for this gem.
+
+    attribute :default_executable
+
+    ##
+    # The path in the gem for executable scripts
+
+    attribute :bindir, 'bin'
+
+    ##
+    # True if this gem is RDoc-compliant
+
+    attribute :has_rdoc, false
+
+    ##
+    # True if this gem supports RDoc
+
+    alias :has_rdoc? :has_rdoc
+
+    ##
+    # The ruby of version required by this gem
+
+    attribute :required_ruby_version, Gem::Requirement.default
+
+    ##
+    # The RubyGems version required by this gem
+
+    attribute :required_rubygems_version, Gem::Requirement.default
+
+    ##
+    # The platform this gem runs on.  See Gem::Platform for details.
+
+    attribute :platform, Gem::Platform::RUBY
+
+    ##
+    # The key used to sign this gem.  See Gem::Security for details.
+
+    attribute :signing_key, nil
+
+    ##
+    # The certificate chain used to sign this gem.  See Gem::Security for
+    # details.
+
+    attribute :cert_chain, []
+
+    ##
+    # A message that gets displayed after the gem is installed
+
+    attribute :post_install_message, nil
+
+    ##
+    # The list of authors who wrote this gem
+
+    array_attribute :authors
+
+    ##
+    # Files included in this gem
+
+    array_attribute :files
+
+    ##
+    # Test files included in this gem
+
+    array_attribute :test_files
+
+    ##
+    # An ARGV-style array of options to RDoc
+
+    array_attribute :rdoc_options
+
+    ##
+    # Extra files to add to RDoc
+
+    array_attribute :extra_rdoc_files
+
+    ##
+    # Executables included in the gem
+
+    array_attribute :executables
+
+    ##
+    # Extensions to build when installing the gem.  See
+    # Gem::Installer#build_extensions for valid values.
+
+    array_attribute :extensions
+
+    ##
+    # An array or things required by this gem.  Not used by anything
+    # presently.
+
+    array_attribute :requirements
+
+    ##
+    # A list of Gem::Dependency objects this gem depends on.  Only appendable.
+
+    array_attribute :dependencies
+
+    read_only :dependencies
+
+    # :section: Aliased gemspec attributes
+
+    ##
+    # Singular accessor for executables
+    
+    attribute_alias_singular :executable, :executables
+
+    ##
+    # Singular accessor for authors
+
+    attribute_alias_singular :author, :authors
+
+    ##
+    # Singular accessor for require_paths
+
+    attribute_alias_singular :require_path, :require_paths
+
+    ##
+    # Singular accessor for test_files
+
+    attribute_alias_singular :test_file, :test_files
+
+    overwrite_accessor :version= do |version|
+      @version = Version.create(version)
+    end
+
+    overwrite_accessor :platform do
+      @new_platform
+    end
+
+    overwrite_accessor :platform= do |platform|
+      if @original_platform.nil? or
+         @original_platform == Gem::Platform::RUBY then
+        @original_platform = platform
+      end
+
+      case platform
+      when Gem::Platform::CURRENT then
+        @new_platform = Gem::Platform.local
+        @original_platform = @new_platform.to_s
+
+      when Gem::Platform then
+        @new_platform = platform
+
+      # legacy constants
+      when nil, Gem::Platform::RUBY then
+        @new_platform = Gem::Platform::RUBY
+      when 'mswin32' then # was Gem::Platform::WIN32
+        @new_platform = Gem::Platform.new 'x86-mswin32'
+      when 'i586-linux' then # was Gem::Platform::LINUX_586
+        @new_platform = Gem::Platform.new 'x86-linux'
+      when 'powerpc-darwin' then # was Gem::Platform::DARWIN
+        @new_platform = Gem::Platform.new 'ppc-darwin'
+      else
+        @new_platform = Gem::Platform.new platform
+      end
+
+      @platform = @new_platform.to_s
+
+      @new_platform
+    end
+
+    overwrite_accessor :required_ruby_version= do |value|
+      @required_ruby_version = Gem::Requirement.create(value)
+    end
+
+    overwrite_accessor :required_rubygems_version= do |value|
+      @required_rubygems_version = Gem::Requirement.create(value)
+    end
+
+    overwrite_accessor :date= do |date|
+      # We want to end up with a Time object with one-day resolution.
+      # This is the cleanest, most-readable, faster-than-using-Date
+      # way to do it.
+      case date
+      when String then
+        @date = if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
+                  Time.local($1.to_i, $2.to_i, $3.to_i)
+                else
+                  require 'time'
+                  Time.parse date
+                end
+      when Time then
+        @date = Time.local(date.year, date.month, date.day)
+      when Date then
+        @date = Time.local(date.year, date.month, date.day)
+      else
+        @date = TODAY
+      end
+    end
+
+    overwrite_accessor :date do
+      self.date = nil if @date.nil?  # HACK Sets the default value for date
+      @date
+    end
+
+    overwrite_accessor :summary= do |str|
+      @summary = if str then
+                   str.strip.
+                   gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').
+                   gsub(/\n[ \t]*/, " ")
+                 end
+    end
+
+    overwrite_accessor :description= do |str|
+      @description = if str then
+                       str.strip.
+                       gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').
+                       gsub(/\n[ \t]*/, " ")
+                     end
+    end
+
+    overwrite_accessor :default_executable do
+      begin
+        if defined?(@default_executable) and @default_executable
+          result = @default_executable
+        elsif @executables and @executables.size == 1
+          result = Array(@executables).first
+        else
+          result = nil
+        end
+        result
+      rescue
+        nil
+      end
+    end
+
+    overwrite_accessor :test_files do
+      # Handle the possibility that we have @test_suite_file but not
+      # @test_files.  This will happen when an old gem is loaded via
+      # YAML.
+      if defined? @test_suite_file then
+        @test_files = [@test_suite_file].flatten
+        @test_suite_file = nil
+      end
+      if defined?(@test_files) and @test_files then
+        @test_files
+      else
+        @test_files = []
+      end
+    end
+
+    overwrite_accessor :files do
+      result = []
+      result.push(*@files) if defined?(@files)
+      result.push(*@test_files) if defined?(@test_files)
+      result.push(*(add_bindir(@executables)))
+      result.push(*@extra_rdoc_files) if defined?(@extra_rdoc_files)
+      result.push(*@extensions) if defined?(@extensions)
+      result.uniq.compact
+    end
+
   end
 
 end
Index: lib/rubygems/platform.rb
===================================================================
--- lib/rubygems/platform.rb	(revision 19546)
+++ lib/rubygems/platform.rb	(revision 19547)
@@ -13,23 +13,6 @@
 
   attr_accessor :version
 
-  DEPRECATED_CONSTS = [
-    :DARWIN,
-    :LINUX_586,
-    :MSWIN32,
-    :PPC_DARWIN,
-    :WIN32,
-    :X86_LINUX
-  ]
-
-  def self.const_missing(name) # TODO remove six months from 2007/12
-    if DEPRECATED_CONSTS.include? name then
-      raise NameError, "#{name} has been removed, use CURRENT instead"
-    else
-      super
-    end
-  end
-
   def self.local
     arch = Gem::ConfigMap[:arch]
     arch = "#{arch}_60" if arch =~ /mswin32$/
@@ -73,7 +56,7 @@
              else cpu
              end
 
-      if arch.length == 2 and arch.last =~ /^\d+$/ then # for command-line
+      if arch.length == 2 and arch.last =~ /^\d+(\.\d+)?$/ then # for command-line
         @os, @version = arch
         return
       end
Index: lib/rubygems/source_index.rb
===================================================================
--- lib/rubygems/source_index.rb	(revision 19546)
+++ lib/rubygems/source_index.rb	(revision 19547)
@@ -7,7 +7,9 @@
 require 'rubygems'
 require 'rubygems/user_interaction'
 require 'rubygems/specification'
-require 'rubygems/spec_fetcher'
+module Gem
+  autoload(:SpecFetcher, 'rubygems/spec_fetcher')
+end
 
 ##
 # The SourceIndex object indexes all the gems available from a
@@ -80,8 +82,14 @@
 
     def load_specification(file_name)
       begin
-        spec_code = File.read(file_name).untaint
+        spec_code = if RUBY_VERSION < '1.9' then
+                      File.read file_name
+                    else
+                      File.read file_name, :encoding => 'UTF-8'
+                    end.untaint
+
         gemspec = eval spec_code, binding, file_name
+
         if gemspec.is_a?(Gem::Specification)
           gemspec.loaded_from = file_name
           return gemspec
@@ -93,7 +101,7 @@
         alert_warning e
         alert_warning spec_code
       rescue Exception => e
-        alert_warning(e.inspect.to_s + "\n" + spec_code)
+        alert_warning "#{e.inspect}\n#{spec_code}"
         alert_warning "Invalid .gemspec format in '#{file_name}'"
       end
       return nil
@@ -230,7 +238,8 @@
   # Find a gem by an exact match on the short name.
 
   def find_name(gem_name, version_requirement = Gem::Requirement.default)
-    search(/^#{gem_name}$/, version_requirement)
+    dep = Gem::Dependency.new(/^#{gem_name}$/, version_requirement)
+    search dep
   end
 
   ##
@@ -246,7 +255,13 @@
     version_requirement = nil
     only_platform = false
 
-    case gem_pattern # TODO warn after 2008/03, remove three months after
+    # TODO - Remove support and warning for legacy arguments after 2008/11
+    unless Gem::Dependency === gem_pattern
+      warn "Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated"
+      warn "#{caller[0]} is outdated" 
+    end
+
+    case gem_pattern
     when Regexp then
       version_requirement = platform_only || Gem::Requirement.default
     when Gem::Dependency then
@@ -270,7 +285,7 @@
 
     specs = @gems.values.select do |spec|
       spec.name =~ gem_pattern and
-      version_requirement.satisfied_by? spec.version
+        version_requirement.satisfied_by? spec.version
     end
 
     if only_platform then
@@ -539,7 +554,7 @@
   # objects to load properly.
   Cache = SourceIndex
 
-  # :starddoc:
+  # :startdoc:
 
 end
 
Index: lib/rubygems/package/tar_reader.rb
===================================================================
--- lib/rubygems/package/tar_reader.rb	(revision 19546)
+++ lib/rubygems/package/tar_reader.rb	(revision 19547)
@@ -46,17 +46,17 @@
       yield entry
 
       skip = (512 - (size % 512)) % 512
+      pending = size - entry.bytes_read
 
-      if @io.respond_to? :seek then
+      begin
         # avoid reading...
-        @io.seek(size - entry.bytes_read, IO::SEEK_CUR)
-      else
-        pending = size - entry.bytes_read
-
+        @io.seek pending, IO::SEEK_CUR
+        pending = 0
+      rescue Errno::EINVAL, NameError
         while pending > 0 do
-          bread = @io.read([pending, 4096].min).size
+          bytes_read = @io.read([pending, 4096].min).size
           raise UnexpectedEOF if @io.eof?
-          pending -= bread
+          pending -= bytes_read
         end
       end
 
Index: lib/rubygems/remote_fetcher.rb
===================================================================
--- lib/rubygems/remote_fetcher.rb	(revision 19546)
+++ lib/rubygems/remote_fetcher.rb	(revision 19547)
@@ -78,7 +78,7 @@
     if File.writable?(install_dir)
       cache_dir = File.join install_dir, 'cache'
     else
-      cache_dir = File.join(ENV['HOME'], '.gem', 'cache')
+      cache_dir = File.join(Gem.user_dir, 'cache')
     end
 
     gem_file_name = "#{spec.full_name}.gem"
@@ -93,7 +93,7 @@
     scheme = nil if scheme =~ /^[a-z]$/i
 
     case scheme
-    when 'http' then
+    when 'http', 'https' then
       unless File.exist? local_gem_path then
         begin
           say "Downloading gem #{gem_file_name}" if
@@ -139,8 +139,8 @@
   # Downloads +uri+ and returns it as a String.
 
   def fetch_path(uri, mtime = nil, head = false)
-    data = open_uri_or_path(uri, mtime, head)
-    data = Gem.gunzip data if uri.to_s =~ /gz$/ and not head
+    data = open_uri_or_path uri, mtime, head
+    data = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
     data
   rescue FetchError
     raise
@@ -216,8 +216,9 @@
     connection = @connections[connection_id]
 
     if uri.scheme == 'https' and not connection.started? then
-      http_obj.use_ssl = true
-      http_obj.verify_mode = OpenSSL::SSL::VERIFY_NONE
+      require 'net/https'
+      connection.use_ssl = true
+      connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
     end
 
     connection.start unless connection.started?
@@ -241,9 +242,10 @@
     response   = request uri, fetch_type, last_modified
 
     case response
-    when Net::HTTPOK then
+    when Net::HTTPOK, Net::HTTPNotModified then
       head ? response : response.body
-    when Net::HTTPRedirection then
+    when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
+         Net::HTTPTemporaryRedirect then
       raise FetchError.new('too many redirects', uri) if depth > 10
 
       open_uri_or_path(response['Location'], last_modified, head, depth + 1)
@@ -274,6 +276,7 @@
     request.add_field 'Keep-Alive', '30'
 
     if last_modified then
+      last_modified = last_modified.utc
       request.add_field 'If-Modified-Since', last_modified.rfc2822
     end
 
@@ -282,9 +285,6 @@
     retried = false
     bad_response = false
 
-    # HACK work around EOFError bug in Net::HTTP
-    # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
-    # to install gems.
     begin
       @requests[connection.object_id] += 1
       response = connection.request request
@@ -297,6 +297,9 @@
 
       bad_response = true
       retry
+    # HACK work around EOFError bug in Net::HTTP
+    # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
+    # to install gems.
     rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET
       requests = @requests[connection.object_id]
       say "connection reset after #{requests} requests, retrying" if
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb	(revision 19546)
+++ lib/rubygems/installer.rb	(revision 19547)
@@ -20,6 +20,7 @@
 # filesystem including unpacking the gem into its gem dir, installing the
 # gemspec in the specifications dir, storing the cached gem in the cache dir,
 # and installing either wrappers or symlinks for executables.
+
 class Gem::Installer
 
   ##
@@ -31,8 +32,36 @@
 
   include Gem::RequirePathsBuilder
 
+  ##
+  # The directory a gem's executables will be installed into
+
+  attr_reader :bin_dir
+
+  ##
+  # The gem repository the gem will be installed into
+
+  attr_reader :gem_home
+
+  ##
+  # The Gem::Specification for the gem being installed
+
+  attr_reader :spec
+
+  @home_install_warning = false
+  @path_warning = false
+
   class << self
 
+    ##
+    # True if we've warned about ~/.gems install
+
+    attr_accessor :home_install_warning
+
+    ##
+    # True if we've warned about PATH not including Gem.bindir
+
+    attr_accessor :path_warning
+
     attr_writer :exec_format
 
     # Defaults to use Ruby's program prefix and suffix.
@@ -61,11 +90,12 @@
     @gem = gem
 
     options = {
-      :force => false,
-      :install_dir => Gem.dir,
-      :exec_format => false,
-      :env_shebang => false,
-      :bin_dir => nil
+      :bin_dir      => nil,
+      :env_shebang  => false,
+      :exec_format  => false,
+      :force        => false,
+      :install_dir  => Gem.dir,
+      :source_index => Gem.source_index,
     }.merge options
 
     @env_shebang = options[:env_shebang]
@@ -78,6 +108,7 @@
     @wrappers = options[:wrappers]
     @bin_dir = options[:bin_dir]
     @development = options[:development]
+    @source_index = options[:source_index]
 
     begin
       @format = Gem::Format.from_file_by_path @gem, @security_policy
@@ -85,30 +116,41 @@
       raise Gem::InstallError, "invalid gem format for #{@gem}"
     end
 
+    begin
+      FileUtils.mkdir_p @gem_home
+    rescue Errno::EACCESS, Errno::ENOTDIR
+      # We'll divert to ~/.gems below
+    end
+
     if not File.writable? @gem_home or
         # TODO: Shouldn't have to test for existence of bindir; tests need it.
-        (@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and 
-         not File.writable? Gem.bindir)
-      if options[:user_install] == false # You explicitly don't want to use ~
+        (@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and
+         not File.writable? Gem.bindir) then
+      if options[:user_install] == false then # You don't want to use ~
         raise Gem::FilePermissionError, @gem_home
-      elsif options[:user_install].nil?
-        say "Warning: falling back to user-level install since #{@gem_home} and #{@bin_dir} aren't both writable."
+      elsif options[:user_install].nil? then
+        unless self.class.home_install_warning then
+          alert_warning "Installing to ~/.gem since #{@gem_home} and\n\t  #{Gem.bindir} aren't both writable."
+          self.class.home_install_warning = true
+        end
       end
       options[:user_install] = true
     end
 
-    if options[:user_install]
-      @gem_home = File.join(ENV['HOME'], '.gem')
+    if options[:user_install] then
+      @gem_home = Gem.user_dir
 
-      user_bin_dir = File.join(@gem_home, 'gems', 'bin')
-      if !ENV['PATH'].split(':').include?(user_bin_dir)
-        say "You don't have #{user_bin_dir} in your PATH."
-        say "You won't be able to run gem-installed executables until you add it."
+      user_bin_dir = File.join(@gem_home, 'bin')
+      unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
+        unless self.class.path_warning then
+          alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t  gem executables will not run."
+          self.class.path_warning = true
+        end
       end
-      
-      Dir.mkdir @gem_home if ! File.directory? @gem_home
+
+      FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
       # If it's still not writable, you've got issues.
-      raise Gem::FilePermissionError, @gem_home if ! File.writable? @gem_home
+      raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
     end
 
     @spec = @format.spec
@@ -157,6 +199,10 @@
       end
     end
 
+    Gem.pre_install_hooks.each do |hook|
+      hook.call self
+    end
+
     FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
 
     Gem.ensure_gem_subdirectories @gem_home
@@ -181,8 +227,12 @@
     @spec.loaded_from = File.join(@gem_home, 'specifications',
                                   "#{@spec.full_name}.gemspec")
 
-    Gem.source_index.add_spec @spec
+    @source_index.add_spec @spec
 
+    Gem.post_install_hooks.each do |hook|
+      hook.call self
+    end
+
     return @spec
   rescue Zlib::GzipFile::Error
     raise Gem::InstallError, "gzip error installing #{@gem}"
@@ -204,10 +254,10 @@
   end
 
   ##
-  # True if the gems in Gem.source_index satisfy +dependency+.
+  # True if the gems in the source_index satisfy +dependency+.
 
   def installation_satisfies_dependency?(dependency)
-    Gem.source_index.find_name(dependency.name, dependency.version_requirements).size > 0
+    @source_index.find_name(dependency.name, dependency.version_requirements).size > 0
   end
 
   ##
Index: lib/rubygems/source_info_cache.rb
===================================================================
--- lib/rubygems/source_info_cache.rb	(revision 19546)
+++ lib/rubygems/source_info_cache.rb	(revision 19547)
@@ -284,6 +284,10 @@
 
     cache_data.map do |source_uri, sic_entry|
       next unless Gem.sources.include? source_uri
+      # TODO - Remove this gunk after 2008/11
+      unless pattern.kind_of?(Gem::Dependency)
+        pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) 
+      end
       sic_entry.source_index.search pattern, platform_only
     end.flatten.compact
   end
@@ -300,6 +304,11 @@
     cache_data.map do |source_uri, sic_entry|
       next unless Gem.sources.include? source_uri
 
+      # TODO - Remove this gunk after 2008/11
+      unless pattern.kind_of?(Gem::Dependency)
+        pattern = Gem::Dependency.new(pattern, Gem::Requirement.default) 
+      end
+
       sic_entry.source_index.search(pattern, only_platform).each do |spec|
         results << [spec, source_uri]
       end
Index: lib/rubygems/commands/specification_command.rb
===================================================================
--- lib/rubygems/commands/specification_command.rb	(revision 19546)
+++ lib/rubygems/commands/specification_command.rb	(revision 19547)
@@ -40,6 +40,7 @@
   def execute
     specs = []
     gem = get_one_gem_name
+    dep = Gem::Dependency.new gem, options[:version]
 
     if local? then
       if File.exist? gem then
@@ -47,12 +48,11 @@
       end
 
       if specs.empty? then
-        specs.push(*Gem.source_index.search(/\A#{gem}\z/, options[:version]))
+        specs.push(*Gem.source_index.search(dep))
       end
     end
 
     if remote? then
-      dep = Gem::Dependency.new gem, options[:version]
       found = Gem::SpecFetcher.fetcher.fetch dep
 
       specs.push(*found.map { |spec,| spec })
Index: lib/rubygems/commands/unpack_command.rb
===================================================================
--- lib/rubygems/commands/unpack_command.rb	(revision 19546)
+++ lib/rubygems/commands/unpack_command.rb	(revision 19547)
@@ -68,7 +68,7 @@
   def get_path(gemname, version_req)
     return gemname if gemname =~ /\.gem$/i
 
-    specs = Gem::source_index.search(/\A#{gemname}\z/, version_req)
+    specs = Gem::source_index.find_name gemname, version_req
 
     selected = specs.sort_by { |s| s.version }.last
 
Index: lib/rubygems/commands/update_command.rb
===================================================================
--- lib/rubygems/commands/update_command.rb	(revision 19546)
+++ lib/rubygems/commands/update_command.rb	(revision 19547)
@@ -45,6 +45,8 @@
   end
 
   def execute
+    hig = {}
+
     if options[:system] then
       say "Updating RubyGems"
 
@@ -52,16 +54,22 @@
         fail "No gem names are allowed with the --system option"
       end
 
-      options[:args] = ["rubygems-update"]
+      spec = Gem::Specification.new
+      spec.name = 'rubygems-update'
+      spec.version = Gem::Version.new Gem::RubyGemsVersion
+      spec.version = Gem::Version.new '1.1.1'
+      hig['rubygems-update'] = spec
+
+      options[:user_install] = false
     else
       say "Updating installed gems"
-    end
 
-    hig = {} # highest installed gems
+      hig = {} # highest installed gems
 
-    Gem.source_index.each do |name, spec|
-      if hig[spec.name].nil? or hig[spec.name].version < spec.version then
-        hig[spec.name] = spec
+      Gem.source_index.each do |name, spec|
+        if hig[spec.name].nil? or hig[spec.name].version < spec.version then
+          hig[spec.name] = spec
+        end
       end
     end
 
@@ -84,15 +92,15 @@
     end
 
     if gems_to_update.include? "rubygems-update" then
-      latest_ruby_gem = remote_gemspecs.select do |s|
-        s.name == 'rubygems-update'
-      end
+      Gem.source_index.refresh!
 
-      latest_ruby_gem = latest_ruby_gem.sort_by { |s| s.version }.last
+      update_gems = Gem.source_index.search 'rubygems-update'
 
-      say "Updating version of RubyGems to #{latest_ruby_gem.version}"
-      installed = do_rubygems_update latest_ruby_gem.version
+      latest_update_gem = update_gems.sort_by { |s| s.version }.last
 
+      say "Updating RubyGems to #{latest_update_gem.version}"
+      installed = do_rubygems_update latest_update_gem.version
+
       say "RubyGems system software updated" if installed
     else
       if updated.empty? then
@@ -103,6 +111,9 @@
     end
   end
 
+  ##
+  # Update the RubyGems software to +version+.
+
   def do_rubygems_update(version)
     args = []
     args.push '--prefix', Gem.prefix unless Gem.prefix.nil?
@@ -112,8 +123,6 @@
 
     update_dir = File.join Gem.dir, 'gems', "rubygems-update-#{version}"
 
-    success = false
-
     Dir.chdir update_dir do
       say "Installing RubyGems #{version}"
       setup_cmd = "#{Gem.ruby} setup.rb #{args.join ' '}"
Index: lib/rubygems/commands/rdoc_command.rb
===================================================================
--- lib/rubygems/commands/rdoc_command.rb	(revision 19546)
+++ lib/rubygems/commands/rdoc_command.rb	(revision 19547)
@@ -59,11 +59,15 @@
         if specs.empty?
           fail "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}"
         end
+
         if options[:include_ri]
           specs.each do |spec|
             Gem::DocManager.new(spec).generate_ri
           end
+
+          Gem::DocManager.update_ri_cache
         end
+
         if options[:include_rdoc]
           specs.each do |spec|
             Gem::DocManager.new(spec).generate_rdoc
@@ -73,6 +77,6 @@
         true
       end
     end
-    
+
   end
 end
Index: lib/rubygems/commands/lock_command.rb
===================================================================
--- lib/rubygems/commands/lock_command.rb	(revision 19546)
+++ lib/rubygems/commands/lock_command.rb	(revision 19547)
@@ -58,15 +58,15 @@
   end
 
   def complain(message)
-    if options.strict then
-      raise message
+    if options[:strict] then
+      raise Gem::Exception, message
     else
       say "# #{message}"
     end
   end
 
   def execute
-    say 'require "rubygems"'
+    say "require 'rubygems'"
 
     locked = {}
 
@@ -77,15 +77,20 @@
 
       spec = Gem::SourceIndex.load_specification spec_path(full_name)
 
+      if spec.nil? then
+        complain "Could not find gem #{full_name}, try using the full name"
+        next
+      end
+
       say "gem '#{spec.name}', '= #{spec.version}'" unless locked[spec.name]
       locked[spec.name] = true
 
       spec.runtime_dependencies.each do |dep|
         next if locked[dep.name]
-        candidates = Gem.source_index.search dep.name, dep.requirement_list
+        candidates = Gem.source_index.search dep
 
         if candidates.empty? then
-          complain "Unable to satisfy '#{dep}' from currently installed gems."
+          complain "Unable to satisfy '#{dep}' from currently installed gems"
         else
           pending << candidates.last.full_name
         end
@@ -94,7 +99,11 @@
   end
 
   def spec_path(gem_full_name)
-    File.join Gem.path, "specifications", "#{gem_full_name }.gemspec"
+    gemspecs = Gem.path.map do |path|
+      File.join path, "specifications", "#{gem_full_name}.gemspec"
+    end
+
+    gemspecs.find { |gemspec| File.exist? gemspec }
   end
 
 end
Index: lib/rubygems/commands/help_command.rb
===================================================================
--- lib/rubygems/commands/help_command.rb	(revision 19546)
+++ lib/rubygems/commands/help_command.rb	(revision 19547)
@@ -20,9 +20,9 @@
     gem install --remote rake --test --rdoc --ri
 
 * Install 'rake', but only version 0.3.1, even if dependencies
-  are not met, and into a specific directory:
+  are not met, and into a user-specific directory:
 
-    gem install rake --version 0.3.1 --force --install-dir $HOME/.gems
+    gem install rake --version 0.3.1 --force --user-install
 
 * List local gems whose name begins with 'D':
 
Index: lib/rubygems/commands/pristine_command.rb
===================================================================
--- lib/rubygems/commands/pristine_command.rb	(revision 19546)
+++ lib/rubygems/commands/pristine_command.rb	(revision 19547)
@@ -57,7 +57,7 @@
               end
             else
               gem_name = get_one_gem_name
-              Gem::SourceIndex.from_installed_gems.search(gem_name,
+              Gem::SourceIndex.from_installed_gems.find_name(gem_name,
                                                           options[:version])
             end
 
Index: lib/rubygems/commands/contents_command.rb
===================================================================
--- lib/rubygems/commands/contents_command.rb	(revision 19546)
+++ lib/rubygems/commands/contents_command.rb	(revision 19547)
@@ -51,7 +51,7 @@
 
     si = Gem::SourceIndex.from_gems_in(*s)
 
-    gem_spec = si.search(/\A#{gem}\z/, version).last
+    gem_spec = si.find_name(gem, version).last
 
     unless gem_spec then
       say "Unable to find gem '#{gem}' in #{path_kind}"
Index: lib/rubygems/commands/which_command.rb
===================================================================
--- lib/rubygems/commands/which_command.rb	(revision 19546)
+++ lib/rubygems/commands/which_command.rb	(revision 19547)
@@ -3,10 +3,10 @@
 
 class Gem::Commands::WhichCommand < Gem::Command
 
-  EXT = %w[.rb .rbw .so .dll] # HACK
+  EXT = %w[.rb .rbw .so .dll .bundle] # HACK
 
   def initialize
-    super 'which', 'Find the location of a library',
+    super 'which', 'Find the location of a library file you can require',
           :search_gems_first => false, :show_all => false
 
     add_option '-a', '--[no-]all', 'show all matching files' do |show_all, options|
@@ -52,7 +52,7 @@
       paths = find_paths arg, dirs
 
       if paths.empty? then
-        say "Can't find #{arg}"
+        say "Can't find ruby library file or shared library #{arg}"
       else
         say paths
       end
@@ -84,3 +84,4 @@
   end
 
 end
+
Index: lib/rubygems/commands/environment_command.rb
===================================================================
--- lib/rubygems/commands/environment_command.rb	(revision 19546)
+++ lib/rubygems/commands/environment_command.rb	(revision 19547)
@@ -18,6 +18,46 @@
     return args.gsub(/^\s+/, '')
   end
 
+  def description # :nodoc:
+    <<-EOF
+The RubyGems environment can be controlled through command line arguments,
+gemrc files, environment variables and built-in defaults.
+
+Command line argument defaults and some RubyGems defaults can be set in
+~/.gemrc file for individual users and a /etc/gemrc for all users.  A gemrc
+is a YAML file with the following YAML keys:
+
+  :sources: A YAML array of remote gem repositories to install gems from
+  :verbose: Verbosity of the gem command.  false, true, and :really are the
+            levels
+  :update_sources: Enable/disable automatic updating of repository metadata
+  :backtrace: Print backtrace when RubyGems encounters an error
+  :bulk_threshold: Switch to a bulk update when this many sources are out of
+                   date (legacy setting)
+  :gempath: The paths in which to look for gems
+  gem_command: A string containing arguments for the specified gem command
+
+Example:
+
+  :verbose: false
+  install: --no-wrappers
+  update: --no-wrappers
+
+RubyGems' default local repository can be overriden with the GEM_PATH and
+GEM_HOME environment variables.  GEM_HOME sets the default repository to
+install into.  GEM_PATH allows multiple local repositories to be searched for
+gems.
+
+If you are behind a proxy server, RubyGems uses the HTTP_PROXY,
+HTTP_PROXY_USER and HTTP_PROXY_PASS environment variables to discover the
+proxy server.
+
+If you are packaging RubyGems all of RubyGems' defaults are in
+lib/rubygems/defaults.rb.  You may override these in
+lib/rubygems/defaults/operating_system.rb
+    EOF
+  end
+
   def usage # :nodoc:
     "#{program_name} [arg]"
   end
Index: lib/rubygems/commands/query_command.rb
===================================================================
--- lib/rubygems/commands/query_command.rb	(revision 19546)
+++ lib/rubygems/commands/query_command.rb	(revision 19547)
@@ -59,7 +59,7 @@
       if name.source.empty? then
         alert_error "You must specify a gem name"
         exit_code |= 4
-      elsif installed? name.source, options[:version] then
+      elsif installed? name, options[:version] then
         say "true"
       else
         say "false"
@@ -69,12 +69,16 @@
       raise Gem::SystemExitException, exit_code
     end
 
+    dep = Gem::Dependency.new name, Gem::Requirement.default
+
     if local? then
-      say
-      say "*** LOCAL GEMS ***"
-      say
+      if ui.outs.tty? or both? then
+        say
+        say "*** LOCAL GEMS ***"
+        say
+      end
 
-      specs = Gem.source_index.search name
+      specs = Gem.source_index.search dep
 
       spec_tuples = specs.map do |spec|
         [[spec.name, spec.version, spec.original_platform, spec], :local]
@@ -84,13 +88,14 @@
     end
 
     if remote? then
-      say
-      say "*** REMOTE GEMS ***"
-      say
+      if ui.outs.tty? or both? then
+        say
+        say "*** REMOTE GEMS ***"
+        say
+      end
 
       all = options[:all]
 
-      dep = Gem::Dependency.new name, Gem::Requirement.default
       begin
         fetcher = Gem::SpecFetcher.fetcher
         spec_tuples = fetcher.find_matching dep, all, false
Index: lib/rubygems/commands/install_command.rb
===================================================================
--- lib/rubygems/commands/install_command.rb	(revision 19546)
+++ lib/rubygems/commands/install_command.rb	(revision 19547)
@@ -38,6 +38,19 @@
     "--no-test --install-dir #{Gem.dir}"
   end
 
+  def description # :nodoc:
+    <<-EOF
+The install command installs local or remote gem into a gem repository.
+
+For gems with executables ruby installs a wrapper file into the executable
+directory by deault.  This can be overridden with the --no-wrappers option.
+The wrapper allows you to choose among alternate gem versions using _version_.
+
+For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer
+version is also installed.
+    EOF
+  end
+
   def usage # :nodoc:
     "#{program_name} GEMNAME [GEMNAME ...] [options] -- --build-flags"
   end
@@ -106,6 +119,8 @@
       installed_gems.each do |gem|
         Gem::DocManager.new(gem, options[:rdoc_args]).generate_ri
       end
+
+      Gem::DocManager.update_ri_cache
     end
 
     if options[:generate_rdoc] then
Index: lib/rubygems/commands/outdated_command.rb
===================================================================
--- lib/rubygems/commands/outdated_command.rb	(revision 19546)
+++ lib/rubygems/commands/outdated_command.rb	(revision 19547)
@@ -19,7 +19,7 @@
     locals = Gem::SourceIndex.from_installed_gems
 
     locals.outdated.sort.each do |name|
-      local = locals.search(/^#{name}$/).last
+      local = locals.find_name(name).last
 
       dep = Gem::Dependency.new local.name, ">= #{local.version}"
       remotes = Gem::SpecFetcher.fetcher.fetch dep
Index: lib/rubygems/gem_path_searcher.rb
===================================================================
--- lib/rubygems/gem_path_searcher.rb	(revision 19546)
+++ lib/rubygems/gem_path_searcher.rb	(revision 19547)
@@ -6,15 +6,15 @@
 
 require 'rubygems'
 
-#
+##
 # GemPathSearcher has the capability to find loadable files inside
 # gems.  It generates data up front to speed up searches later.
-#
+
 class Gem::GemPathSearcher
 
-  #
+  ##
   # Initialise the data we need to make searches later.
-  #
+
   def initialize
     # We want a record of all the installed gemspecs, in the order
     # we wish to examine them.
@@ -27,7 +27,7 @@
     end
   end
 
-  # 
+  ##
   # Look in all the installed gems until a matching _path_ is found.
   # Return the _gemspec_ of the gem where it was found.  If no match
   # is found, return nil.
@@ -46,36 +46,52 @@
   # others), which may or may not already be attached to _file_.
   # This method doesn't care about the full filename that matches;
   # only that there is a match.
-  # 
+
   def find(path)
-    @gemspecs.each do |spec|
-      return spec if matching_file(spec, path)
+    @gemspecs.find do |spec| matching_file? spec, path end
+  end
+
+  ##
+  # Works like #find, but finds all gemspecs matching +path+.
+
+  def find_all(path)
+    @gemspecs.select do |spec|
+      matching_file? spec, path
     end
-    nil
   end
 
-  private
+  ##
+  # Attempts to find a matching path using the require_paths of the given
+  # +spec+.
 
-  # Attempts to find a matching path using the require_paths of the
-  # given _spec_.
-  #
-  # Some of the intermediate results are cached in @lib_dirs for
-  # speed.
-  def matching_file(spec, path)  # :doc:
+  def matching_file?(spec, path)
+    !matching_files(spec, path).empty?
+  end
+
+  ##
+  # Returns files matching +path+ in +spec+.
+  #--
+  # Some of the intermediate results are cached in @lib_dirs for speed.
+
+  def matching_files(spec, path)
     glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}"
-    return true unless Dir[glob].select { |f| File.file?(f.untaint) }.empty?
+    Dir[glob].select { |f| File.file? f.untaint }
   end
 
-  # Return a list of all installed gemspecs, sorted by alphabetical
-  # order and in reverse version order.
+  ##
+  # Return a list of all installed gemspecs, sorted by alphabetical order and
+  # in reverse version order.
+
   def init_gemspecs
     Gem.source_index.map { |_, spec| spec }.sort { |a,b|
       (a.name <=> b.name).nonzero? || (b.version <=> a.version)
     }
   end
 
+  ##
   # Returns library directories glob for a gemspec.  For example,
   #   '/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}'
+
   def lib_dirs_for(spec)
     "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}"
   end
Index: lib/rubygems/uninstaller.rb
===================================================================
--- lib/rubygems/uninstaller.rb	(revision 19546)
+++ lib/rubygems/uninstaller.rb	(revision 19547)
@@ -18,10 +18,24 @@
   include Gem::UserInteraction
 
   ##
-  # Constructs an Uninstaller instance
-  #
-  # gem:: [String] The Gem name to uninstall
+  # The directory a gem's executables will be installed into
 
+  attr_reader :bin_dir
+
+  ##
+  # The gem repository the gem will be installed into
+
+  attr_reader :gem_home
+
+  ##
+  # The Gem::Specification for the gem being uninstalled, only set during
+  # #uninstall_gem
+
+  attr_reader :spec
+
+  ##
+  # Constructs an uninstaller that will uninstall +gem+
+
   def initialize(gem, options = {})
     @gem = gem
     @version = options[:version] || Gem::Requirement.default
@@ -31,42 +45,63 @@
     @force_all = options[:all]
     @force_ignore = options[:ignore]
     @bin_dir = options[:bin_dir]
+
+    spec_dir = File.join @gem_home, 'specifications'
+    @source_index = Gem::SourceIndex.from_gems_in spec_dir
   end
 
   ##
-  # Performs the uninstall of the Gem.  This removes the spec, the
-  # Gem directory, and the cached .gem file,
+  # Performs the uninstall of the gem.  This removes the spec, the Gem
+  # directory, and the cached .gem file.
 
   def uninstall
-    list = Gem.source_index.search(/^#{@gem}$/, @version)
+    list = @source_index.find_name @gem, @version
 
     if list.empty? then
       raise Gem::InstallError, "Unknown gem #{@gem} #{@version}"
-    elsif list.size > 1 && @force_all
-      remove_all(list.dup)
-      remove_executables(list.last)
-    elsif list.size > 1
+
+    elsif list.size > 1 and @force_all then
+      remove_all list.dup
+
+    elsif list.size > 1 then
+      gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
+
       say
-      gem_names = list.collect {|gem| gem.full_name} + ["All versions"]
-      gem_name, index =
-        choose_from_list("Select gem to uninstall:", gem_names)
-      if index == list.size
-        remove_all(list.dup)
-        remove_executables(list.last)
-      elsif index >= 0 && index < list.size
-        to_remove = list[index]
-        remove(to_remove, list)
-        remove_executables(to_remove)
+      gem_name, index = choose_from_list "Select gem to uninstall:", gem_names
+
+      if index == list.size then
+        remove_all list.dup
+      elsif index >= 0 && index < list.size then
+        uninstall_gem list[index], list.dup
       else
         say "Error: must enter a number [1-#{list.size+1}]"
       end
     else
-      remove(list[0], list.dup)
-      remove_executables(list.last)
+      uninstall_gem list.first, list.dup
     end
   end
 
   ##
+  # Uninstalls gem +spec+
+
+  def uninstall_gem(spec, specs)
+    @spec = spec
+
+    Gem.pre_uninstall_hooks.each do |hook|
+      hook.call self
+    end
+
+    specs.each { |s| remove_executables s }
+    remove spec, specs
+
+    Gem.post_uninstall_hooks.each do |hook|
+      hook.call self
+    end
+
+    @spec = nil
+  end
+
+  ##
   # Removes installed executables and batch files (windows only) for
   # +gemspec+.
 
@@ -76,7 +111,7 @@
     if gemspec.executables.size > 0 then
       bindir = @bin_dir ? @bin_dir : (Gem.bindir @gem_home)
 
-      list = Gem.source_index.search(gemspec.name).delete_if { |spec|
+      list = @source_index.find_name(gemspec.name).delete_if { |spec|
         spec.version == gemspec.version
       }
 
@@ -118,7 +153,7 @@
   # NOTE: removes uninstalled gems from +list+.
 
   def remove_all(list)
-    list.dup.each { |spec| remove spec, list }
+    list.dup.each { |spec| uninstall_gem spec, list }
   end
 
   ##
@@ -185,8 +220,7 @@
   def dependencies_ok?(spec)
     return true if @force_ignore
 
-    source_index = Gem::SourceIndex.from_installed_gems
-    deplist = Gem::DependencyList.from_source_index source_index
+    deplist = Gem::DependencyList.from_source_index @source_index
     deplist.ok_to_remove?(spec.full_name) || ask_if_ok(spec)
   end
 
Index: lib/rubygems/rubygems_version.rb
===================================================================
--- lib/rubygems/rubygems_version.rb	(revision 19546)
+++ lib/rubygems/rubygems_version.rb	(revision 19547)
@@ -2,5 +2,5 @@
 # This file is auto-generated by build scripts.
 # See:  rake update_version
 module Gem
-  RubyGemsVersion = '1.2.0.1824'
+  RubyGemsVersion = '1.3.0'
 end
Index: lib/rubygems/defaults.rb
===================================================================
--- lib/rubygems/defaults.rb	(revision 19546)
+++ lib/rubygems/defaults.rb	(revision 19547)
@@ -1,36 +1,52 @@
 module Gem
 
-  # An Array of the default sources that come with RubyGems.
+  ##
+  # An Array of the default sources that come with RubyGems
+
   def self.default_sources
     %w[http://gems.rubyforge.org/]
   end
 
+  ##
   # Default home directory path to be used if an alternate value is not
-  # specified in the environment.
+  # specified in the environment
+
   def self.default_dir
     if defined? RUBY_FRAMEWORK_VERSION then
       File.join File.dirname(ConfigMap[:sitedir]), 'Gems',
                 ConfigMap[:ruby_version]
-    elsif defined? RUBY_ENGINE then
-      File.join ConfigMap[:libdir], RUBY_ENGINE, 'gems',
-                ConfigMap[:ruby_version]
     else
-      File.join ConfigMap[:libdir], 'ruby', 'gems', ConfigMap[:ruby_version]
+      File.join(ConfigMap[:libdir], ruby_engine, 'gems',
+                ConfigMap[:ruby_version])
     end
   end
 
-  # Default gem load path.
+  ##
+  # Path for gems in the user's home directory
+
+  def self.user_dir
+    File.join(Gem.user_home, '.gem', ruby_engine,
+              ConfigMap[:ruby_version])
+  end
+
+  ##
+  # Default gem load path
+
   def self.default_path
-    [File.join(ENV['HOME'], '.gem'), default_dir]
+    [user_dir, default_dir]
   end
 
-  # Deduce Ruby's --program-prefix and --program-suffix from its install name.
+  ##
+  # Deduce Ruby's --program-prefix and --program-suffix from its install name
+
   def self.default_exec_format
     baseruby = ConfigMap[:BASERUBY] || 'ruby'
     ConfigMap[:RUBY_INSTALL_NAME].sub(baseruby, '%s') rescue '%s'
   end
 
+  ##
   # The default directory for binaries
+
   def self.default_bindir
     if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
       '/usr/bin'
@@ -39,15 +55,30 @@
     end
   end
 
-  # The default system-wide source info cache directory.
+  ##
+  # The default system-wide source info cache directory
+
   def self.default_system_source_cache_dir
     File.join Gem.dir, 'source_cache'
   end
 
-  # The default user-specific source info cache directory.
+  ##
+  # The default user-specific source info cache directory
+
   def self.default_user_source_cache_dir
     File.join Gem.user_home, '.gem', 'source_cache'
   end
 
+  ##
+  # A wrapper around RUBY_ENGINE const that may not be defined
+
+  def self.ruby_engine
+    if defined? RUBY_ENGINE then
+      RUBY_ENGINE
+    else
+      'ruby'
+    end
+  end
+
 end
 
Index: lib/rubygems/test_utilities.rb
===================================================================
--- lib/rubygems/test_utilities.rb	(revision 19546)
+++ lib/rubygems/test_utilities.rb	(revision 19547)
@@ -34,16 +34,20 @@
     path = path.to_s
     @paths << path
     raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
-    data = @data[path]
 
-    if data.nil? then
-      raise Gem::RemoteFetcher::FetchError.new('no data', path)
+    unless @data.key? path then
+      raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
     end
 
+    data = @data[path]
+
     if data.respond_to?(:call) then
       data.call
     else
-      data = Gem.gunzip data if path.to_s =~ /gz$/ unless data.empty?
+      if path.to_s =~ /gz$/ and not data.nil? and not data.empty? then
+        data = Gem.gunzip data
+      end
+
       data
     end
   end
@@ -51,13 +55,15 @@
   def fetch_size(path)
     path = path.to_s
     @paths << path
+
     raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
-    data = @data[path]
 
-    if data.nil? then
-      raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", nil)
+    unless @data.key? path then
+      raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
     end
 
+    data = @data[path]
+
     data.respond_to?(:call) ? data.call : data.length
   end
 
Index: lib/rubygems.rb
===================================================================
--- lib/rubygems.rb	(revision 19546)
+++ lib/rubygems.rb	(revision 19547)
@@ -104,6 +104,11 @@
   @ruby = nil
   @sources = []
 
+  @post_install_hooks = []
+  @post_uninstall_hooks = []
+  @pre_uninstall_hooks = []
+  @pre_install_hooks = []
+
   ##
   # Activates an installed gem matching +gem+.  The gem must satisfy
   # +version_requirements+.
@@ -244,7 +249,10 @@
   def self.clear_paths
     @gem_home = nil
     @gem_path = nil
+    @user_home = nil
+
     @@source_index = nil
+
     MUTEX.synchronize do
       @searcher = nil
     end
@@ -261,9 +269,7 @@
   # The standard configuration object for gems.
 
   def self.configuration
-    return @configuration if @configuration
-    require 'rubygems/config_file'
-    @configuration = Gem::ConfigFile.new []
+    @configuration ||= Gem::ConfigFile.new []
   end
 
   ##
@@ -337,6 +343,22 @@
   end
 
   ##
+  # Returns a list of paths matching +file+ 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 does not search $LOAD_PATH for files, only gems.
+
+  def self.find_files(path)
+    specs = searcher.find_all path
+
+    specs.map do |spec|
+      searcher.matching_files spec, path
+    end.flatten
+  end
+
+  ##
   # Finds the user's home directory.
   #--
   # Some comments from the ruby-talk list regarding finding the home
@@ -353,7 +375,7 @@
     end
 
     if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
-      return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
+      return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
     end
 
     begin
@@ -466,13 +488,11 @@
 
   ##
   # manage_gems is useless and deprecated.  Don't call it anymore.
-  #--
-  # TODO warn w/ RubyGems 1.2.x release.
 
-  def self.manage_gems
-    #file, lineno = location_of_caller
+  def self.manage_gems # :nodoc:
+    file, lineno = location_of_caller
 
-    #warn "#{file}:#{lineno}:Warning: Gem#manage_gems is deprecated and will be removed on or after September 2008."
+    warn "#{file}:#{lineno}:Warning: Gem::manage_gems is deprecated and will be removed on or after March 2009."
   end
 
   ##
@@ -489,11 +509,7 @@
     @gem_path ||= nil
 
     unless @gem_path then
-      paths = if ENV['GEM_PATH'] then
-                [ENV['GEM_PATH']]
-              else
-                [default_path]
-              end
+      paths = [ENV['GEM_PATH'] || Gem.configuration.path || default_path]
 
       if defined?(APPLE_GEM_HOME) and not ENV['GEM_PATH'] then
         paths << APPLE_GEM_HOME
@@ -524,6 +540,40 @@
   end
 
   ##
+  # Adds a post-install hook that will be passed an Gem::Installer instance
+  # when Gem::Installer#install is called
+
+  def self.post_install(&hook)
+    @post_install_hooks << hook
+  end
+
+  ##
+  # Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance
+  # and the spec that was uninstalled when Gem::Uninstaller#uninstall is
+  # called
+
+  def self.post_uninstall(&hook)
+    @post_uninstall_hooks << hook
+  end
+
+  ##
+  # Adds a pre-install hook that will be passed an Gem::Installer instance
+  # when Gem::Installer#install is called
+
+  def self.pre_install(&hook)
+    @pre_install_hooks << hook
+  end
+
+  ##
+  # Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance
+  # and the spec that will be uninstalled when Gem::Uninstaller#uninstall is
+  # called
+
+  def self.pre_uninstall(&hook)
+    @pre_uninstall_hooks << hook
+  end
+
+  ##
   # The directory prefix this RubyGems was installed at.
 
   def self.prefix
@@ -600,6 +650,9 @@
       @ruby = File.join(ConfigMap[:bindir],
                         ConfigMap[:ruby_install_name])
       @ruby << ConfigMap[:EXEEXT]
+
+      # escape string in case path to ruby executable contain spaces.
+      @ruby.sub!(/.*\s.*/m, '"\&"')
     end
 
     @ruby
@@ -655,7 +708,13 @@
     end
 
     @gem_path.uniq!
-    @gem_path.each do |gp| ensure_gem_subdirectories(gp) end
+    @gem_path.each do |path|
+      if 0 == File.expand_path(path).index(Gem.user_home) and
+         Etc.getpwuid.uid != File::Stat.new(Gem.user_home).uid then
+        next # only create by matching user
+      end
+      ensure_gem_subdirectories path
+    end
   end
 
   private_class_method :set_paths
@@ -686,6 +745,14 @@
   end
 
   ##
+  # Need to be able to set the sources without calling
+  # Gem.sources.replace since that would cause an infinite loop.
+
+  def self.sources=(new_sources)
+    @sources = new_sources
+  end
+
+  ##
   # Glob pattern for require-able path suffixes.
 
   def self.suffix_pattern
@@ -731,6 +798,27 @@
 
     attr_reader :loaded_specs
 
+    ##
+    # The list of hooks to be run before Gem::Install#install does any work
+
+    attr_reader :post_install_hooks
+
+    ##
+    # The list of hooks to be run before Gem::Uninstall#uninstall does any
+    # work
+
+    attr_reader :post_uninstall_hooks
+
+    ##
+    # The list of hooks to be run after Gem::Install#install is finished
+
+    attr_reader :pre_install_hooks
+
+    ##
+    # The list of hooks to be run after Gem::Uninstall#uninstall is finished
+
+    attr_reader :pre_uninstall_hooks
+
     # :stopdoc:
 
     alias cache source_index # an alias for the old name
@@ -781,7 +869,10 @@
   end
 end
 
+require 'rubygems/config_file'
+
 if RUBY_VERSION < '1.9' then
   require 'rubygems/custom_require'
 end
 
+Gem.clear_paths
Index: test/rubygems/test_gem_commands_uninstall_command.rb
===================================================================
--- test/rubygems/test_gem_commands_uninstall_command.rb	(revision 0)
+++ test/rubygems/test_gem_commands_uninstall_command.rb	(revision 19547)
@@ -0,0 +1,60 @@
+require 'test/unit'
+require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities')
+require File.join(File.expand_path(File.dirname(__FILE__)),
+                  'gem_installer_test_case')
+require 'rubygems/commands/uninstall_command'
+
+class TestGemCommandsUninstallCommand < GemInstallerTestCase
+
+  def setup
+    super
+
+    ui = MockGemUi.new
+    util_setup_gem ui
+
+    use_ui ui do
+      @installer.install
+    end
+
+    @cmd = Gem::Commands::UninstallCommand.new
+    @cmd.options[:executables] = true
+    @executable = File.join(@gemhome, 'bin', 'executable')
+  end
+
+  def test_execute_removes_executable
+    if win_platform?
+      assert_equal true, File.exist?(@executable)
+    else
+      assert_equal true, File.symlink?(@executable)
+    end
+
+    # Evil hack to prevent false removal success
+    FileUtils.rm_f @executable
+    File.open(@executable, "wb+") {|f| f.puts "binary"}
+
+    @cmd.options[:args] = Array(@spec.name)
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    output = @ui.output.split "\n"
+    assert_match(/Removing executable/, output.shift)
+    assert_match(/Successfully uninstalled/, output.shift)
+    assert_equal false, File.exist?(@executable)
+    assert_nil output.shift, "UI output should have contained only two lines"
+  end
+
+  def test_execute_not_installed
+    @cmd.options[:args] = ["foo"]
+    e = assert_raise(Gem::InstallError) do
+      use_ui @ui do
+        @cmd.execute
+      end
+    end
+
+    assert_match(/\AUnknown gem foo >= 0$/, e.message)
+    output = @ui.output.split "\n"
+    assert output.empty?, "UI output should be empty after an uninstall error"
+  end
+end
+

Property changes on: test/rubygems/test_gem_commands_uninstall_command.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: test/rubygems/test_gem_spec_fetcher.rb
===================================================================
--- test/rubygems/test_gem_spec_fetcher.rb	(revision 19546)
+++ test/rubygems/test_gem_spec_fetcher.rb	(revision 19547)
@@ -67,7 +67,7 @@
   end
 
   def test_fetch_legacy_repo
-    @fetcher.data["#{@gem_repo}specs.#{Gem.marshal_version}.gz"] = nil
+    @fetcher.data.delete "#{@gem_repo}specs.#{Gem.marshal_version}.gz"
     @fetcher.data["#{@gem_repo}yaml"] = ''
     util_setup_source_info_cache @a1, @a2
 
@@ -259,6 +259,16 @@
     assert_equal specs, cached_specs
   end
 
+  def test_list_latest_all
+    specs = @sf.list false
+
+    assert_equal [@latest_specs], specs.values
+
+    specs = @sf.list true
+
+    assert_equal [@specs], specs.values, 'specs file not loaded'
+  end
+
   def test_load_specs
     specs = @sf.load_specs @uri, 'specs'
 
@@ -280,7 +290,7 @@
   end
 
   def test_load_specs_cached
-    @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = ''
+    @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = nil
     @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}"] =
       ' ' * Marshal.dump(@latest_specs).length
 
Index: test/rubygems/test_gem_source_info_cache.rb
===================================================================
--- test/rubygems/test_gem_source_info_cache.rb	(revision 19546)
+++ test/rubygems/test_gem_source_info_cache.rb	(revision 19547)
@@ -224,7 +224,8 @@
 
     @sic.set_cache_data @gem_repo => sice
     latest = @sic.latest_cache_data
-    gems = latest[@gem_repo].source_index.search('a').map { |s| s.full_name }
+    beginning_with_a = Gem::Dependency.new(/^a/, Gem::Requirement.default)
+    gems = latest[@gem_repo].source_index.search(beginning_with_a).map { |s| s.full_name }
 
     assert_equal %w[a-2 a_evil-9], gems
   end
Index: test/rubygems/test_gem_gem_path_searcher.rb
===================================================================
--- test/rubygems/test_gem_gem_path_searcher.rb	(revision 19546)
+++ test/rubygems/test_gem_gem_path_searcher.rb	(revision 19547)
@@ -5,10 +5,6 @@
 class Gem::GemPathSearcher
   attr_accessor :gemspecs
   attr_accessor :lib_dirs
-
-  public :init_gemspecs
-  public :matching_file
-  public :lib_dirs_for
 end
 
 class TestGemGemPathSearcher < RubyGemTestCase
@@ -40,6 +36,10 @@
     assert_equal @foo1, @gps.find('foo')
   end
 
+  def test_find_all
+    assert_equal [@foo1], @gps.find_all('foo')
+  end
+
   def test_init_gemspecs
     assert_equal [@bar2, @bar1, @foo2, @foo1], @gps.init_gemspecs
   end
@@ -51,10 +51,18 @@
     assert_equal expected, lib_dirs
   end
 
-  def test_matching_file
-    assert !@gps.matching_file(@foo1, 'bar')
-    assert @gps.matching_file(@foo1, 'foo')
+  def test_matching_file_eh
+    assert !@gps.matching_file?(@foo1, 'bar')
+    assert @gps.matching_file?(@foo1, 'foo')
   end
 
+  def test_matching_files
+    assert_equal [], @gps.matching_files(@foo1, 'bar')
+
+    expected = File.join @foo1.full_gem_path, 'lib', 'foo.rb'
+
+    assert_equal [expected], @gps.matching_files(@foo1, 'foo')
+  end
+
 end
 
Index: test/rubygems/test_gem_uninstaller.rb
===================================================================
--- test/rubygems/test_gem_uninstaller.rb	(revision 19546)
+++ test/rubygems/test_gem_uninstaller.rb	(revision 19547)
@@ -62,5 +62,26 @@
     assert_equal true, uninstaller.path_ok?(@spec)
   end
 
+  def test_uninstall
+    uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+
+    gem_dir = File.join @gemhome, 'gems', @spec.full_name
+
+    Gem.pre_uninstall do
+      assert File.exist?(gem_dir), 'gem_dir should exist'
+    end
+
+    Gem.post_uninstall do
+      assert !File.exist?(gem_dir), 'gem_dir should not exist'
+    end
+
+    uninstaller.uninstall
+
+    assert !File.exist?(gem_dir)
+
+    assert_same uninstaller, @pre_uninstall_hook_arg
+    assert_same uninstaller, @post_uninstall_hook_arg
+  end
+
 end
 
Index: test/rubygems/test_gem_ext_configure_builder.rb
===================================================================
--- test/rubygems/test_gem_ext_configure_builder.rb	(revision 19546)
+++ test/rubygems/test_gem_ext_configure_builder.rb	(revision 19547)
@@ -53,12 +53,13 @@
     expected = %r(configure failed:
 
 #{Regexp.escape sh_prefix_configure}#{Regexp.escape @dest_path}
-.*?: #{shell_error_msg})
+.*?: #{shell_error_msg}
+)
 
     assert_match expected, error.message
 
     assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift
-    assert_match %r(#{shell_error_msg}\n), output.shift
+    assert_match %r(#{shell_error_msg}), output.shift
     assert_equal true, output.empty?
   end
 
Index: test/rubygems/test_gem_commands_lock_command.rb
===================================================================
--- test/rubygems/test_gem_commands_lock_command.rb	(revision 0)
+++ test/rubygems/test_gem_commands_lock_command.rb	(revision 19547)
@@ -0,0 +1,69 @@
+require 'test/unit'
+require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities')
+require 'rubygems/commands/lock_command'
+
+class TestGemCommandsLockCommand < RubyGemTestCase
+
+  def setup
+    super
+
+    @a1 = quick_gem 'a', '1'
+    @b1 = quick_gem 'b', '1' do |s|
+      s.add_runtime_dependency 'a'
+    end
+
+    @d1 = quick_gem 'd', '1' do |s|
+      s.add_runtime_dependency 'z'
+    end
+
+    @cmd = Gem::Commands::LockCommand.new
+  end
+
+  def test_execute
+    @cmd.handle_options %w[b-1]
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    expected = <<-EXPECTED
+require 'rubygems'
+gem 'b', '= 1'
+gem 'a', '= 1'
+    EXPECTED
+
+    assert_equal expected, @ui.output
+    assert_equal '', @ui.error
+  end
+
+  def test_execute_missing_dependency
+    @cmd.handle_options %w[d-1]
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    expected = <<-EXPECTED
+require 'rubygems'
+gem 'd', '= 1'
+# Unable to satisfy 'z (>= 0, runtime)' from currently installed gems
+    EXPECTED
+
+    assert_equal expected, @ui.output
+    assert_equal '', @ui.error
+  end
+
+  def test_execute_strict
+    @cmd.handle_options %w[c-1 --strict]
+
+    e = assert_raise Gem::Exception do
+      use_ui @ui do
+        @cmd.execute
+      end
+    end
+
+    assert_equal 'Could not find gem c-1, try using the full name', e.message
+  end
+
+end
+

Property changes on: test/rubygems/test_gem_commands_lock_command.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: test/rubygems/test_gem_command_manager.rb
===================================================================
--- test/rubygems/test_gem_command_manager.rb	(revision 19546)
+++ test/rubygems/test_gem_command_manager.rb	(revision 19547)
@@ -31,7 +31,7 @@
   def test_run_interrupt
     use_ui @ui do
       @command_manager.register_command :interrupt
-      assert_raise MockGemUi::TermError do
+      assert_raises MockGemUi::TermError do
         @command_manager.run 'interrupt'
       end
       assert_equal '', ui.output
@@ -41,7 +41,7 @@
 
   def test_process_args_bad_arg
     use_ui @ui do
-      assert_raise(MockGemUi::TermError) {
+      assert_raises(MockGemUi::TermError) {
         @command_manager.process_args("--bad-arg")
       }
     end
Index: test/rubygems/test_gem_package_tar_header.rb
===================================================================
--- test/rubygems/test_gem_package_tar_header.rb	(revision 19546)
+++ test/rubygems/test_gem_package_tar_header.rb	(revision 19547)
@@ -62,19 +62,19 @@
   end
 
   def test_initialize_bad
-    assert_raise ArgumentError do
+    assert_raises ArgumentError do
       Gem::Package::TarHeader.new :name => '', :size => '', :mode => ''
     end
 
-    assert_raise ArgumentError do
+    assert_raises ArgumentError do
       Gem::Package::TarHeader.new :name => '', :size => '', :prefix => ''
     end
 
-    assert_raise ArgumentError do
+    assert_raises ArgumentError do
       Gem::Package::TarHeader.new :name => '', :prefix => '', :mode => ''
     end
 
-    assert_raise ArgumentError do
+    assert_raises ArgumentError do
       Gem::Package::TarHeader.new :prefix => '', :size => '', :mode => ''
     end
   end
Index: test/rubygems/test_gem_builder.rb
===================================================================
--- test/rubygems/test_gem_builder.rb	(revision 19546)
+++ test/rubygems/test_gem_builder.rb	(revision 19547)
@@ -25,7 +25,7 @@
   def test_build_validates
     builder = Gem::Builder.new Gem::Specification.new
 
-    assert_raise Gem::InvalidSpecificationException do
+    assert_raises Gem::InvalidSpecificationException do
       builder.build
     end
   end
Index: test/rubygems/test_gem_stream_ui.rb
===================================================================
--- test/rubygems/test_gem_stream_ui.rb	(revision 19546)
+++ test/rubygems/test_gem_stream_ui.rb	(revision 19547)
@@ -63,7 +63,7 @@
     @in.tty = false
 
     timeout(0.1) do
-      assert_raise(Gem::OperationNotSupportedError) do
+      assert_raises(Gem::OperationNotSupportedError) do
         @sui.ask_yes_no("do coconuts migrate?")
       end
     end
Index: test/rubygems/test_gem_remote_fetcher.rb
===================================================================
--- test/rubygems/test_gem_remote_fetcher.rb	(revision 19546)
+++ test/rubygems/test_gem_remote_fetcher.rb	(revision 19547)
@@ -268,15 +268,15 @@
     ensure
       File.chmod 0755, File.join(@gemhome, 'cache')
     end
-    
+
     def test_download_read_only
       File.chmod 0555, File.join(@gemhome, 'cache')
       File.chmod 0555, File.join(@gemhome)
 
       fetcher = util_fuck_with_fetcher File.read(@a1_gem)
       fetcher.download(@a1, 'http://gems.example.com')
-      assert File.exist?(File.join(@userhome, '.gem',
-                                   'cache', "#{@a1.full_name}.gem"))
+      assert File.exist?(File.join(Gem.user_dir, 'cache',
+                                   "#{@a1.full_name}.gem"))
     ensure
       File.chmod 0755, File.join(@gemhome)
       File.chmod 0755, File.join(@gemhome, 'cache')
@@ -391,6 +391,16 @@
     assert_equal 'foo', fetcher.fetch_path(@uri + 'foo.gz')
   end
 
+  def test_fetch_path_gzip_unmodified
+    fetcher = Gem::RemoteFetcher.new nil
+
+    def fetcher.open_uri_or_path(uri, mtime, head = nil)
+      nil
+    end
+
+    assert_equal nil, fetcher.fetch_path(@uri + 'foo.gz', Time.at(0))
+  end
+
   def test_fetch_path_io_error
     fetcher = Gem::RemoteFetcher.new nil
 
@@ -441,10 +451,10 @@
     fetcher = Gem::RemoteFetcher.new nil
 
     def fetcher.open_uri_or_path(uri, mtime, head = nil)
-      ''
+      nil
     end
 
-    assert_equal '', fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
+    assert_equal nil, fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
   end
 
   def test_get_proxy_from_env_empty
@@ -504,7 +514,7 @@
     def conn.request(req)
       unless defined? @requested then
         @requested = true
-        res = Net::HTTPRedirection.new nil, 301, nil
+        res = Net::HTTPMovedPermanently.new nil, 301, nil
         res.add_field 'Location', 'http://gems.example.com/real_path'
         res
       else
@@ -528,7 +538,7 @@
     conn = Object.new
     def conn.started?() true end
     def conn.request(req)
-      res = Net::HTTPRedirection.new nil, 301, nil
+      res = Net::HTTPMovedPermanently.new nil, 301, nil
       res.add_field 'Location', 'http://gems.example.com/redirect'
       res
     end
Index: test/rubygems/test_gem_config_file.rb
===================================================================
--- test/rubygems/test_gem_config_file.rb	(revision 19546)
+++ test/rubygems/test_gem_config_file.rb	(revision 19547)
@@ -57,6 +57,9 @@
       fp.puts ":sources:"
       fp.puts "  - http://more-gems.example.com"
       fp.puts "install: --wrappers"
+      fp.puts ":gempath:"
+      fp.puts "- /usr/ruby/1.8/lib/ruby/gems/1.8"
+      fp.puts "- /var/ruby/1.8/gem_home"
     end
 
     util_config_file
@@ -68,6 +71,8 @@
     assert_equal false, @cfg.update_sources
     assert_equal %w[http://more-gems.example.com], Gem.sources
     assert_equal '--wrappers', @cfg[:install]
+    assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'],
+                 @cfg.path)
   end
 
   def test_initialize_handle_arguments_config_file
Index: test/rubygems/test_gem.rb
===================================================================
--- test/rubygems/test_gem.rb	(revision 19546)
+++ test/rubygems/test_gem.rb	(revision 19547)
@@ -45,7 +45,12 @@
 
   def test_self_bindir_default_dir
     default = Gem.default_dir
-    bindir = (defined? RUBY_FRAMEWORK_VERSION) ? '/usr/bin' : Config::CONFIG['bindir']    
+    bindir = if defined?(RUBY_FRAMEWORK_VERSION) then
+               '/usr/bin'
+             else
+               Config::CONFIG['bindir']
+             end
+
     assert_equal bindir, Gem.bindir(default)
     assert_equal bindir, Gem.bindir(Pathname.new(default))
   end
@@ -218,6 +223,36 @@
     Gem.ssl_available = orig_Gem_ssl_available
   end
 
+  def test_self_find_files
+    foo1 = quick_gem 'foo', '1' do |s|
+      s.files << 'lib/foo/discover.rb'
+    end
+
+    foo2 = quick_gem 'foo', '2' do |s|
+      s.files << 'lib/foo/discover.rb'
+    end
+
+    path = File.join 'gems', foo1.full_name, 'lib', 'foo', 'discover.rb'
+    write_file(path) { |fp| fp.puts "# #{path}" }
+
+    path = File.join 'gems', foo2.full_name, 'lib', 'foo', 'discover.rb'
+    write_file(path) { |fp| fp.puts "# #{path}" }
+
+    @fetcher = Gem::FakeFetcher.new
+    Gem::RemoteFetcher.fetcher = @fetcher
+
+    Gem.source_index = util_setup_spec_fetcher foo1, foo2
+
+    Gem.searcher = nil
+
+    expected = [
+      File.join(foo1.full_gem_path, 'lib', 'foo', 'discover.rb'),
+      File.join(foo2.full_gem_path, 'lib', 'foo', 'discover.rb'),
+    ]
+
+    assert_equal expected, Gem.find_files('foo/discover').sort
+  end
+
   def test_self_latest_load_paths
     util_make_gems
 
@@ -261,20 +296,21 @@
   unless win_platform?
     def test_self_path_APPLE_GEM_HOME
       Gem.clear_paths
-      Dir.mktmpdir("apple_gem_home") {|d|
-        Gem.const_set :APPLE_GEM_HOME, d
-        assert Gem.path.include?(d)
-      }
+      apple_gem_home = File.join @tempdir, 'apple_gem_home'
+      Gem.const_set :APPLE_GEM_HOME, apple_gem_home
+
+      assert Gem.path.include?(apple_gem_home)
     ensure
       Gem.send :remove_const, :APPLE_GEM_HOME
     end
-  
+
     def test_self_path_APPLE_GEM_HOME_GEM_PATH
       Gem.clear_paths
       ENV['GEM_PATH'] = @gemhome
-      Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home'
-  
-      assert !Gem.path.include?('/tmp/apple_gem_home')
+      apple_gem_home = File.join @tempdir, 'apple_gem_home'
+      Gem.const_set :APPLE_GEM_HOME, apple_gem_home
+
+      assert !Gem.path.include?(apple_gem_home)
     ensure
       Gem.send :remove_const, :APPLE_GEM_HOME
     end
@@ -291,7 +327,7 @@
 
     assert_equal path_count + @additional.size, Gem.path.size,
                  "extra path components: #{Gem.path[2..-1].inspect}"
-    assert_match Gem.dir, Gem.path.last
+    assert_equal Gem.dir, Gem.path.last
   end
 
   def test_self_path_duplicate
@@ -390,6 +426,44 @@
                  Gem.required_location("a", "code.rb", "= 2")
   end
 
+  def test_self_ruby_escaping_spaces_in_path
+    orig_ruby = Gem.ruby
+    orig_bindir = Gem::ConfigMap[:bindir]
+    orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
+    orig_exe_ext = Gem::ConfigMap[:EXEEXT]
+
+    Gem::ConfigMap[:bindir] = "C:/Ruby 1.8/bin"
+    Gem::ConfigMap[:ruby_install_name] = "ruby"
+    Gem::ConfigMap[:EXEEXT] = ".exe"
+    Gem.instance_variable_set("@ruby", nil)
+
+    assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
+  ensure
+    Gem.instance_variable_set("@ruby", orig_ruby)
+    Gem::ConfigMap[:bindir] = orig_bindir
+    Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
+    Gem::ConfigMap[:EXEEXT] = orig_exe_ext
+  end
+
+  def test_self_ruby_path_without_spaces
+    orig_ruby = Gem.ruby
+    orig_bindir = Gem::ConfigMap[:bindir]
+    orig_ruby_install_name = Gem::ConfigMap[:ruby_install_name]
+    orig_exe_ext = Gem::ConfigMap[:EXEEXT]
+
+    Gem::ConfigMap[:bindir] = "C:/Ruby18/bin"
+    Gem::ConfigMap[:ruby_install_name] = "ruby"
+    Gem::ConfigMap[:EXEEXT] = ".exe"
+    Gem.instance_variable_set("@ruby", nil)
+
+    assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
+  ensure
+    Gem.instance_variable_set("@ruby", orig_ruby)
+    Gem::ConfigMap[:bindir] = orig_bindir
+    Gem::ConfigMap[:ruby_install_name] = orig_ruby_install_name
+    Gem::ConfigMap[:EXEEXT] = orig_exe_ext
+  end
+
   def test_self_ruby_version
     version = RUBY_VERSION.dup
     version << ".#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL
@@ -430,6 +504,11 @@
     assert_equal @additional + [Gem.dir], Gem.path
   end
 
+  def test_self_user_dir
+    assert_equal File.join(@userhome, '.gem', Gem.ruby_engine,
+                           Gem::ConfigMap[:ruby_version]), Gem.user_dir
+  end
+
   def test_self_user_home
     if ENV['HOME'] then
       assert_equal ENV['HOME'], Gem.user_home
@@ -438,6 +517,28 @@
     end
   end
 
+  def test_self_user_home_user_drive_and_path
+    Gem.clear_paths
+
+    # safe-keep env variables
+    orig_home, orig_user_profile = ENV['HOME'], ENV['USERPROFILE']
+    orig_user_drive, orig_user_path = ENV['HOMEDRIVE'], ENV['HOMEPATH']
+
+    # prepare the environment
+    ENV.delete('HOME')
+    ENV.delete('USERPROFILE')
+    ENV['HOMEDRIVE'] = 'Z:'
+    ENV['HOMEPATH'] = '\\Users\\RubyUser'
+
+    assert_equal "Z:\\Users\\RubyUser", Gem.user_home
+
+  ensure
+    ENV['HOME'] = orig_home
+    ENV['USERPROFILE'] = orig_user_profile
+    ENV['USERDRIVE'] = orig_user_drive
+    ENV['USERPATH'] = orig_user_path
+  end
+
   def util_ensure_gem_dirs
     Gem.ensure_gem_subdirectories @gemhome
     @additional.each do |dir|
Index: test/rubygems/test_gem_commands_query_command.rb
===================================================================
--- test/rubygems/test_gem_commands_query_command.rb	(revision 19546)
+++ test/rubygems/test_gem_commands_query_command.rb	(revision 19547)
@@ -180,7 +180,7 @@
     @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] =
       si.dump
 
-    @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = nil
+    @fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"
 
     @cmd.handle_options %w[-r]
 
@@ -265,6 +265,27 @@
     assert_equal '', @ui.error
   end
 
+  def test_execute_local_notty
+    @cmd.handle_options %w[]
+
+    @ui.outs.tty = false
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    expected = <<-EOF
+a (2, 1)
+a_evil (9)
+b (2)
+c (1.2)
+pl (1)
+    EOF
+
+    assert_equal expected, @ui.output
+    assert_equal '', @ui.error
+  end
+
   def test_execute_no_versions
     @cmd.handle_options %w[-r --no-versions]
 
@@ -284,5 +305,23 @@
     assert_equal '', @ui.error
   end
 
+  def test_execute_notty
+    @cmd.handle_options %w[-r]
+
+    @ui.outs.tty = false
+
+    use_ui @ui do
+      @cmd.execute
+    end
+
+    expected = <<-EOF
+a (2)
+pl (1)
+    EOF
+
+    assert_equal expected, @ui.output
+    assert_equal '', @ui.error
+  end
+
 end
 
Index: test/rubygems/test_gem_commands_install_command.rb
===================================================================
--- test/rubygems/test_gem_commands_install_command.rb	(revision 19546)
+++ test/rubygems/test_gem_commands_install_command.rb	(revision 19547)
@@ -43,7 +43,7 @@
       orig_dir = Dir.pwd
       begin
         Dir.chdir @tempdir
-        e = assert_raise Gem::SystemExitException do
+        e = assert_raises Gem::SystemExitException do
           @cmd.execute
         end
         assert_equal 0, e.exit_code
@@ -65,7 +65,7 @@
     @cmd.options[:args] = %w[no_such_gem]
 
     use_ui @ui do
-      e = assert_raise Gem::SystemExitException do
+      e = assert_raises Gem::SystemExitException do
         @cmd.execute
       end
       assert_equal 2, e.exit_code
@@ -91,7 +91,7 @@
     @cmd.options[:args] = %w[nonexistent]
 
     use_ui @ui do
-      e = assert_raise Gem::SystemExitException do
+      e = assert_raises Gem::SystemExitException do
         @cmd.execute
       end
       assert_equal 2, e.exit_code
@@ -114,7 +114,7 @@
     @cmd.options[:args] = [@a2.name]
 
     use_ui @ui do
-      e = assert_raise Gem::SystemExitException do
+      e = assert_raises Gem::SystemExitException do
         @cmd.execute
       end
       assert_equal 0, e.exit_code
@@ -146,7 +146,7 @@
       orig_dir = Dir.pwd
       begin
         Dir.chdir @tempdir
-        e = assert_raise Gem::SystemExitException do
+        e = assert_raises Gem::SystemExitException do
           @cmd.execute
         end
         assert_equal 0, e.exit_code
Index: test/rubygems/test_gem_commands_list_command.rb
===================================================================
--- test/rubygems/test_gem_commands_list_command.rb	(revision 0)
+++ test/rubygems/test_gem_commands_list_command.rb	(revision 19547)
@@ -0,0 +1,37 @@
+require 'test/unit'
+require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities')
+require 'rubygems/commands/list_command'
+
+class TestGemCommandsListCommand < RubyGemTestCase
+
+  def setup
+    super
+
+    @cmd = Gem::Commands::ListCommand.new
+
+    util_setup_fake_fetcher
+
+    @si = util_setup_spec_fetcher @a1, @a2, @pl1
+
+    @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+      raise Gem::RemoteFetcher::FetchError
+    end
+  end
+
+  def test_execute_installed
+    @cmd.handle_options %w[c --installed]
+
+    e = assert_raise Gem::SystemExitException do
+      use_ui @ui do
+        @cmd.execute
+      end
+    end
+
+    assert_equal 0, e.exit_code
+
+    assert_equal "true\n", @ui.output
+
+    assert_equal '', @ui.error
+  end
+
+end

Property changes on: test/rubygems/test_gem_commands_list_command.rb
___________________________________________________________________
Name: svn:eol-style
   + LF
Name: svn:keywords
   + Author Date Id Revision

Index: test/rubygems/test_gem_installer.rb
===================================================================
--- test/rubygems/test_gem_installer.rb	(revision 19546)
+++ test/rubygems/test_gem_installer.rb	(revision 19547)
@@ -70,7 +70,10 @@
 #{Gem.ruby}: No such file or directory -- extconf.rb (LoadError)
     EOF
 
-    assert_equal expected, File.read(gem_make_out)
+    assert_match %r%#{Regexp.escape Gem.ruby} extconf.rb%,
+                 File.read(gem_make_out)
+    assert_match %r%#{Regexp.escape Gem.ruby}: No such file%,
+                 File.read(gem_make_out)
   end
 
   def test_build_extensions_unsupported
@@ -287,7 +290,7 @@
     Dir.mkdir util_inst_bindir
     File.chmod 0000, util_inst_bindir
 
-    assert_raise Gem::FilePermissionError do
+    assert_raises Gem::FilePermissionError do
       @installer.generate_bin
     end
 
@@ -372,7 +375,7 @@
     Dir.mkdir util_inst_bindir
     File.chmod 0000, util_inst_bindir
 
-    assert_raise Gem::FilePermissionError do
+    assert_raises Gem::FilePermissionError do
       @installer.generate_bin
     end
 
@@ -529,6 +532,16 @@
     Dir.mkdir util_inst_bindir
     util_setup_gem
 
+    cache_file = File.join @gemhome, 'cache', "#{@spec.full_name}.gem"
+
+    Gem.pre_install do |installer|
+      assert !File.exist?(cache_file), 'cache file should not exist yet'
+    end
+
+    Gem.post_install do |installer|
+      assert File.exist?(cache_file), 'cache file should exist'
+    end
+
     build_rake_in do
       use_ui @ui do
         assert_equal @spec, @installer.install
@@ -552,6 +565,9 @@
 
     assert_equal spec_file, @spec.loaded_from
     assert File.exist?(spec_file)
+
+    assert_same @installer, @pre_install_hook_arg
+    assert_same @installer, @post_install_hook_arg
   end
 
   def test_install_bad_gem
@@ -586,6 +602,29 @@
     end
   end
 
+  def test_install_check_dependencies_install_dir
+    gemhome2 = "#{@gemhome}2"
+    @spec.add_dependency 'b'
+
+    b2 = quick_gem 'b', 2
+
+    FileUtils.mv @gemhome, gemhome2
+    Gem.source_index.gems.delete b2.full_name
+    source_index = Gem::SourceIndex.from_gems_in File.join(gemhome2,
+                                                           'specifications')
+
+    util_setup_gem
+
+    @installer = Gem::Installer.new @gem, :install_dir => gemhome2,
+                                    :source_index => source_index
+
+    use_ui @ui do
+      @installer.install
+    end
+
+    assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name))
+  end
+
   def test_install_force
     use_ui @ui do
       installer = Gem::Installer.new old_ruby_required, :force => true
@@ -641,13 +680,13 @@
     assert File.exist?(File.join(@gemhome, 'specifications',
                                  "#{@spec.full_name}.gemspec"))
   end
+
   unless win_platform? # File.chmod doesn't work
     def test_install_user_local_fallback
       Dir.mkdir util_inst_bindir
       File.chmod 0755, @userhome
       File.chmod 0000, util_inst_bindir
       File.chmod 0000, Gem.dir
-      install_dir = File.join @userhome, '.gem', 'gems', @spec.full_name
       @spec.executables = ["executable"]
 
       build_rake_in do
@@ -656,9 +695,10 @@
           @installer.install
         end
       end
-    
-      assert File.exist?(File.join(install_dir, 'lib', 'code.rb'))
-      assert File.exist?(File.join(@userhome, '.gem', 'bin', 'executable'))
+
+      assert File.exist?(File.join(Gem.user_dir, 'gems',
+                                   @spec.full_name, 'lib', 'code.rb'))
+      assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable'))
     ensure
       File.chmod 0755, Gem.dir
       File.chmod 0755, util_inst_bindir
@@ -676,13 +716,13 @@
           @installer.install
         end
       end
-      
-      assert File.exist?(File.join(@userhome, '.gem', 'bin', 'executable'))
+
+      assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable'))
     ensure
       File.chmod 0755, util_inst_bindir
     end
   end
-  
+
   def test_install_with_message
     @spec.post_install_message = 'I am a shiny gem!'
 
Index: test/rubygems/test_gem_ext_rake_builder.rb
===================================================================
--- test/rubygems/test_gem_ext_rake_builder.rb	(revision 19546)
+++ test/rubygems/test_gem_ext_rake_builder.rb	(revision 19547)
@@ -32,6 +32,8 @@
       end
     end
 
+    output = output.join "\n"
+
     expected = [
       "#{@@ruby} mkrf_conf.rb",
       "",
@@ -39,7 +41,9 @@
       "(in #{realdir})\n"
     ]
 
-    assert_equal expected, output
+    assert_no_match %r%^rake failed:%, output
+    assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output
+    assert_match %r%^#{Regexp.escape @@rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, output
   end
 
   def test_class_build_fail
@@ -69,7 +73,9 @@
 #{@@rake} RUBYARCHDIR=#{@dest_path} RUBYLIBDIR=#{@dest_path}
     EOF
 
-    assert_equal expected, error.message.split("\n")[0..4].join("\n")
+    assert_match %r%^rake failed:%, error.message
+    assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, error.message
+    assert_match %r%^#{Regexp.escape @@rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, error.message
   end
 
 end
Index: test/rubygems/gemutilities.rb
===================================================================
--- test/rubygems/gemutilities.rb	(revision 19546)
+++ test/rubygems/gemutilities.rb	(revision 19547)
@@ -19,6 +19,10 @@
 require File.join(File.expand_path(File.dirname(__FILE__)), 'mockgemui')
 
 module Gem
+  def self.searcher=(searcher)
+    MUTEX.synchronize do @searcher = searcher end
+  end
+
   def self.source_index=(si)
     @@source_index = si
   end
@@ -26,7 +30,7 @@
   def self.win_platform=(val)
     @@win_platform = val
   end
-  
+
   module DefaultUserInteraction
     @ui = MockGemUi.new
   end
@@ -89,6 +93,27 @@
                                               'private_key.pem')
     @public_cert = File.expand_path File.join(File.dirname(__FILE__),
                                               'public_cert.pem')
+
+    Gem.post_install_hooks.clear
+    Gem.post_uninstall_hooks.clear
+    Gem.pre_install_hooks.clear
+    Gem.pre_uninstall_hooks.clear
+
+    Gem.post_install do |installer|
+      @post_install_hook_arg = installer
+    end
+
+    Gem.post_uninstall do |uninstaller|
+      @post_uninstall_hook_arg = uninstaller
+    end
+
+    Gem.pre_install do |installer|
+      @pre_install_hook_arg = installer
+    end
+
+    Gem.pre_uninstall do |uninstaller|
+      @pre_uninstall_hook_arg = uninstaller
+    end
   end
 
   def teardown
@@ -435,7 +460,15 @@
   end
 
   @@ruby = rubybin
-  @@rake = ENV["rake"] || (@@ruby + " " + File.expand_path("../../../bin/rake", __FILE__))
+  env_rake = ENV['rake']
+  ruby19_rake = @@ruby + " " + File.expand_path("../../../bin/rake", __FILE__)
+  @@rake = if env_rake then
+             ENV["rake"]
+           elsif File.exist? ruby19_rake then
+             ruby19_rake
+           else
+             'rake'
+           end
 
 end
 
Index: test/rubygems/test_gem_platform.rb
===================================================================
--- test/rubygems/test_gem_platform.rb	(revision 19546)
+++ test/rubygems/test_gem_platform.rb	(revision 19547)
@@ -5,19 +5,6 @@
 
 class TestGemPlatform < RubyGemTestCase
 
-  def test_self_const_missing
-    consts = [:DARWIN, :LINUX_586, :MSWIN32, :PPC_DARWIN, :WIN32, :X86_LINUX]
-
-    consts.each do |const|
-      e = assert_raise NameError do
-        Gem::Platform.const_missing const
-      end
-
-      assert_equal "#{const} has been removed, use CURRENT instead",
-                   e.message
-    end
-  end
-
   def test_self_local
     util_set_arch 'i686-darwin8.10.1'
 
@@ -105,6 +92,12 @@
     platform = Gem::Platform.new 'i386-mswin32-80'
 
     assert_equal expected, platform.to_a, 'i386-mswin32-80'
+
+    expected = ['x86', 'solaris', '2.10']
+
+    platform = Gem::Platform.new 'i386-solaris-2.10'
+
+    assert_equal expected, platform.to_a, 'i386-solaris-2.10'
   end
 
   def test_initialize_mswin32_vc6
Index: test/rubygems/test_gem_source_index.rb
===================================================================
--- test/rubygems/test_gem_source_index.rb	(revision 19546)
+++ test/rubygems/test_gem_source_index.rb	(revision 19547)
@@ -64,6 +64,54 @@
     assert_equal a1.author, spec.author
   end
 
+  def test_self_load_specification_utf_8
+    spec_dir = File.join @gemhome, 'specifications'
+
+    FileUtils.rm_r spec_dir
+
+    FileUtils.mkdir_p spec_dir
+
+    spec_file = File.join spec_dir, "utf-8.gemspec"
+    spec_data = <<-SPEC
+Gem::Specification.new do |s|
+  s.name = %q{utf}
+  s.version = "8"
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0")
+  s.authors = ["\317\200"]
+  s.date = %q{2008-09-10}
+  s.description = %q{This is a test description}
+  s.email = %q{example@e...}
+  s.has_rdoc = true
+  s.homepage = %q{http://example.com}
+  s.require_paths = ["lib"]
+  s.rubygems_version = %q{1.2.0}
+  s.summary = %q{this is a summary}
+
+  if s.respond_to? :specification_version then
+    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+    s.specification_version = 2
+
+    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+    else
+    end
+  else
+  end
+end
+    SPEC
+
+    spec_data.force_encoding 'UTF-8'
+
+    File.open spec_file, 'w' do |io| io.write spec_data end
+
+    spec = Gem::SourceIndex.load_specification spec_file
+
+    pi = "\317\200"
+    pi.force_encoding 'UTF-8' if pi.respond_to? :force_encoding
+
+    assert_equal pi, spec.author
+  end if Gem.ruby_version > Gem::Version.new('1.9')
+
   def test_self_load_specification_exception
     spec_dir = File.join @gemhome, 'specifications'
 
@@ -437,6 +485,27 @@
     assert_equal [], missing
   end
 
+  def test_find_name
+    assert_equal [@a1, @a2], @source_index.find_name('a')
+    assert_equal [@a2], @source_index.find_name('a', '= 2')
+    assert_equal [], @source_index.find_name('bogusstring')
+    assert_equal [], @source_index.find_name('a', '= 3')
+
+    source_index = Gem::SourceIndex.new
+    source_index.add_spec @a1
+    source_index.add_spec @a2
+
+    assert_equal [@a1], source_index.find_name(@a1.name, '= 1')
+
+    r1 = Gem::Requirement.create '= 1'
+    assert_equal [@a1], source_index.find_name(@a1.name, r1)
+  end
+
+  def test_find_name_empty_cache
+    empty_source_index = Gem::SourceIndex.new({})
+    assert_equal [], empty_source_index.find_name("foo")
+  end
+
   def test_latest_specs
     p1_ruby = quick_gem 'p', '1'
     p1_platform = quick_gem 'p', '1' do |spec|
@@ -573,30 +642,14 @@
   end
 
   def test_search
-    assert_equal [@a1, @a2, @a_evil9], @source_index.search('a')
-    assert_equal [@a2], @source_index.search('a', '= 2')
+    requirement = Gem::Requirement.create '= 9'
+    with_version = Gem::Dependency.new(/^a/, requirement)
+    assert_equal [@a_evil9], @source_index.search(with_version)
 
-    assert_equal [], @source_index.search('bogusstring')
-    assert_equal [], @source_index.search('a', '= 3')
-
-    source_index = Gem::SourceIndex.new
-    source_index.add_spec @a1
-    source_index.add_spec @a2
-
-    assert_equal [@a1], source_index.search(@a1.name, '= 1')
-
-    r1 = Gem::Requirement.create '= 1'
-    assert_equal [@a1], source_index.search(@a1.name, r1)
-
-    dep = Gem::Dependency.new @a1.name, r1
-    assert_equal [@a1], source_index.search(dep)
+    with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default)
+    assert_equal [@a1, @a2, @a_evil9], @source_index.search(with_default)
   end
 
-  def test_search_empty_cache
-    empty_source_index = Gem::SourceIndex.new({})
-    assert_equal [], empty_source_index.search("foo")
-  end
-
   def test_search_platform
     util_set_arch 'x86-my_platform1'
 
Index: test/rubygems/mockgemui.rb
===================================================================
--- test/rubygems/mockgemui.rb	(revision 19546)
+++ test/rubygems/mockgemui.rb	(revision 19547)
@@ -12,8 +12,28 @@
 class MockGemUi < Gem::StreamUI
   class TermError < RuntimeError; end
 
-  def initialize(input="")
-    super(StringIO.new(input), StringIO.new, StringIO.new)
+  module TTY
+
+    attr_accessor :tty
+
+    def tty?()
+      @tty = true unless defined?(@tty)
+      @tty
+    end
+
+  end
+
+  def initialize(input = "")
+    ins = StringIO.new input
+    outs = StringIO.new
+    errs = StringIO.new
+
+    ins.extend TTY
+    outs.extend TTY
+    errs.extend TTY
+
+    super ins, outs, errs
+
     @terminated = false
   end
 
Index: test/rubygems/test_gem_commands_dependency_command.rb
===================================================================
--- test/rubygems/test_gem_commands_dependency_command.rb	(revision 19546)
+++ test/rubygems/test_gem_commands_dependency_command.rb	(revision 19547)
@@ -199,7 +199,7 @@
     @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] =
       si.dump
 
-    @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = nil
+    @fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"
 
     FileUtils.rm File.join(@gemhome, 'specifications',
                            "#{foo.full_name}.gemspec")
Index: test/rubygems/test_gem_local_remote_options.rb
===================================================================
--- test/rubygems/test_gem_local_remote_options.rb	(revision 19546)
+++ test/rubygems/test_gem_local_remote_options.rb	(revision 19547)
@@ -19,6 +19,18 @@
     assert @cmd.handles?(args)
   end
 
+  def test_both_eh
+    assert_equal false, @cmd.both?
+
+    @cmd.options[:domain] = :local
+
+    assert_equal false, @cmd.both?
+
+    @cmd.options[:domain] = :both
+
+    assert_equal true, @cmd.both?
+  end
+
   def test_local_eh
     assert_equal false, @cmd.local?
 
Index: test/rubygems/test_gem_specification.rb
===================================================================
--- test/rubygems/test_gem_specification.rb	(revision 19546)
+++ test/rubygems/test_gem_specification.rb	(revision 19547)
@@ -500,7 +500,7 @@
   end
 
   def test_has_rdoc_eh
-    assert_equal true, @a1.has_rdoc?
+    assert @a1.has_rdoc?
   end
 
   def test_hash
@@ -634,7 +634,10 @@
 
     ruby_code = @a2.to_ruby
 
-    expected = "Gem::Specification.new do |s|
+    expected = <<-SPEC
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
   s.name = %q{a}
   s.version = \"2\"
 
@@ -654,7 +657,7 @@
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
     s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
 
-    if current_version >= 3 then
+    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
       s.add_runtime_dependency(%q<b>, [\"= 1\"])
     else
       s.add_dependency(%q<b>, [\"= 1\"])
@@ -663,7 +666,7 @@
     s.add_dependency(%q<b>, [\"= 1\"])
   end
 end
-"
+    SPEC
 
     assert_equal expected, ruby_code
 
@@ -679,7 +682,10 @@
     local = Gem::Platform.local
     expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]"
 
-    expected = "Gem::Specification.new do |s|
+    expected = <<-SPEC
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
   s.name = %q{a}
   s.version = \"1\"
   s.platform = Gem::Platform.new(#{expected_platform})
@@ -706,7 +712,7 @@
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
     s.specification_version = 2
 
-    if current_version >= 3 then
+    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
       s.add_runtime_dependency(%q<rake>, [\"> 0.4\"])
       s.add_runtime_dependency(%q<jabber4r>, [\"> 0.0.0\"])
       s.add_runtime_dependency(%q<pqa>, [\"> 0.4\", \"<= 0.6\"])
@@ -721,7 +727,7 @@
     s.add_dependency(%q<pqa>, [\"> 0.4\", \"<= 0.6\"])
   end
 end
-"
+    SPEC
 
     assert_equal expected, ruby_code
 
Index: test/rubygems/test_gem_install_update_options.rb
===================================================================
--- test/rubygems/test_gem_install_update_options.rb	(revision 19546)
+++ test/rubygems/test_gem_install_update_options.rb	(revision 19547)
@@ -41,8 +41,8 @@
 
     @installer = Gem::Installer.new @gem, @cmd.options
     @installer.install
-    assert File.exist?(File.join(@userhome, '.gem', 'gems'))
-    assert File.exist?(File.join(@userhome, '.gem', 'gems', 
+    assert File.exist?(File.join(Gem.user_dir, 'gems'))
+    assert File.exist?(File.join(Gem.user_dir, 'gems',
                                  @spec.full_name))
   end
 
@@ -52,7 +52,7 @@
     File.chmod 0755, @userhome
     FileUtils.chmod 0000, @gemhome
 
-    assert_raise(Gem::FilePermissionError) do
+    assert_raises(Gem::FilePermissionError) do
       @installer = Gem::Installer.new @gem, @cmd.options
     end
   ensure
Index: test/rubygems/test_gem_version.rb
===================================================================
--- test/rubygems/test_gem_version.rb	(revision 19546)
+++ test/rubygems/test_gem_version.rb	(revision 19547)
@@ -107,7 +107,7 @@
 
   def test_illformed_requirements
     [ ">>> 1.3.5", "> blah" ].each do |rq|
-      assert_raise(ArgumentError, "req [#{rq}] should fail") {
+      assert_raises(ArgumentError, "req [#{rq}] should fail") {
         Gem::Version::Requirement.new(rq)
       }
     end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]