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

ruby-changes:30205

From: drbrain <ko1@a...>
Date: Wed, 31 Jul 2013 07:10:37 +0900 (JST)
Subject: [ruby-changes:30205] drbrain:r42257 (trunk): * lib/rubygems: Import RubyGems from master as of commit 523551c

drbrain	2013-07-31 07:10:21 +0900 (Wed, 31 Jul 2013)

  New Revision: 42257

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

  Log:
    * lib/rubygems:  Import RubyGems from master as of commit 523551c
    * test/rubygems:  ditto.

  Modified files:
    trunk/ChangeLog
    trunk/lib/rubygems/commands/outdated_command.rb
    trunk/lib/rubygems/ext/builder.rb
    trunk/lib/rubygems/installer.rb
    trunk/lib/rubygems/remote_fetcher.rb
    trunk/lib/rubygems/security.rb
    trunk/lib/rubygems/specification.rb
    trunk/lib/rubygems.rb
    trunk/test/rubygems/encrypted_private_key.pem
    trunk/test/rubygems/test_gem_ext_builder.rb
    trunk/test/rubygems/test_gem_installer.rb
    trunk/test/rubygems/test_gem_package.rb
    trunk/test/rubygems/test_gem_security.rb
    trunk/test/rubygems/test_gem_specification.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42256)
+++ ChangeLog	(revision 42257)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Jul 31 07:09:07 2013  Eric Hodel  <drbrain@s...>
+
+	* lib/rubygems:  Import RubyGems from master as of commit 523551c
+	* test/rubygems:  ditto.
+
 Tue Jul 30 22:21:54 2013  Masaki Matsushita  <glass.saga@g...>
 
 	* test/ruby/test_hash.rb: add a test for enumeration order of Hash.
Index: lib/rubygems/ext/builder.rb
===================================================================
--- lib/rubygems/ext/builder.rb	(revision 42256)
+++ lib/rubygems/ext/builder.rb	(revision 42257)
@@ -4,8 +4,23 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/ext/builder.rb#L4
 # See LICENSE.txt for permissions.
 #++
 
+require 'rubygems/user_interaction'
+require 'thread'
+
 class Gem::Ext::Builder
 
+  include Gem::UserInteraction
+
+  ##
+  # The builder shells-out to run various commands after changing the
+  # directory.  This means multiple installations cannot be allowed to build
+  # extensions in parallel as they may change each other's directories leading
+  # to broken extensions or failed installations.
+
+  CHDIR_MUTEX = Mutex.new # :nodoc:
+
+  attr_accessor :build_args # :nodoc:
+
   def self.class_name
     name =~ /Ext::(.*)Builder/
     $1.downcase
@@ -63,5 +78,108 @@ class Gem::Ext::Builder https://github.com/ruby/ruby/blob/trunk/lib/rubygems/ext/builder.rb#L78
     end
   end
 
+  ##
+  # Creates a new extension builder for +spec+ using the given +build_args+.
+  # The gem for +spec+ is unpacked in +gem_dir+.
+
+  def initialize spec, build_args
+    @spec       = spec
+    @build_args = build_args
+    @gem_dir    = spec.gem_dir
+
+    @ran_rake   = nil
+  end
+
+  ##
+  # Chooses the extension builder class for +extension+
+
+  def builder_for extension # :nodoc:
+    case extension
+    when /extconf/ then
+      Gem::Ext::ExtConfBuilder
+    when /configure/ then
+      Gem::Ext::ConfigureBuilder
+    when /rakefile/i, /mkrf_conf/i then
+      @ran_rake = true
+      Gem::Ext::RakeBuilder
+    when /CMakeLists.txt/ then
+      Gem::Ext::CmakeBuilder
+    else
+      extension_dir = File.join @gem_dir, File.dirname(extension)
+
+      message = "No builder for extension '#{extension}'"
+      build_error extension_dir, message
+    end
+  end
+
+  ##
+  # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
+
+  def build_error build_dir, output, backtrace = nil # :nodoc:
+    gem_make_out = File.join build_dir, 'gem_make.out'
+
+    open gem_make_out, 'wb' do |io| io.puts output end
+
+    message = <<-EOF
+ERROR: Failed to build gem native extension.
+
+    #{output}
+
+Gem files will remain installed in #{@gem_dir} for inspection.
+Results logged to #{gem_make_out}
+EOF
+
+    raise Gem::Installer::ExtensionBuildError, message, backtrace
+  end
+
+  def build_extension extension, dest_path # :nodoc:
+    results = []
+
+    extension ||= '' # I wish I knew why this line existed
+    extension_dir = File.join @gem_dir, File.dirname(extension)
+
+    builder = builder_for extension
+
+    begin
+      FileUtils.mkdir_p dest_path
+
+      CHDIR_MUTEX.synchronize do
+        Dir.chdir extension_dir do
+          results = builder.build(extension, @gem_dir, dest_path,
+                                  results, @build_args)
+
+          say results.join("\n") if Gem.configuration.really_verbose
+        end
+      end
+    rescue
+      build_error extension_dir, results.join("\n"), $@
+    end
+  end
+
+  ##
+  # Builds extensions.  Valid types of extensions are extconf.rb files,
+  # configure scripts and rakefiles or mkrf_conf files.
+
+  def build_extensions
+    return if @spec.extensions.empty?
+
+    if @build_args.empty?
+      say "Building native extensions.  This could take a while..."
+    else
+      say "Building native extensions with: '#{@build_args.join ' '}'"
+      say "This could take a while..."
+    end
+
+    dest_path = File.join @gem_dir, @spec.require_paths.first
+
+    @ran_rake = false # only run rake once
+
+    @spec.extensions.each do |extension|
+      break if @ran_rake
+
+      build_extension extension, dest_path
+    end
+  end
+
 end
 
Index: lib/rubygems/specification.rb
===================================================================
--- lib/rubygems/specification.rb	(revision 42256)
+++ lib/rubygems/specification.rb	(revision 42257)
@@ -1016,25 +1016,43 @@ class Gem::Specification < Gem::BasicSpe https://github.com/ruby/ruby/blob/trunk/lib/rubygems/specification.rb#L1016
   end
 
   ##
-  # Return a list of all outdated specifications. This method is HEAVY
+  # Return a list of all outdated local gem names.  This method is HEAVY
   # as it must go fetch specifications from the server.
+  #
+  # Use outdated_and_latest_version if you wish to retrieve the latest remote
+  # version as well.
 
   def self.outdated
-    outdateds = []
+    outdated_and_latest_version.map { |local, _| local.name }
+  end
+
+  ##
+  # Enumerates the outdated local gems yielding the local specification and
+  # the latest remote version.
+  #
+  # This method may take some time to return as it must check each local gem
+  # against the server's index.
+
+  def self.outdated_and_latest_version
+    return enum_for __method__ unless block_given?
 
     # TODO: maybe we should switch to rubygems' version service?
     fetcher = Gem::SpecFetcher.fetcher
 
-    latest_specs(true).each do |local|
-      dependency = Gem::Dependency.new local.name, ">= #{local.version}"
-      remotes, _   = fetcher.search_for_dependency dependency
-      remotes      = remotes.map { |n, _| n.version }
-      latest       = remotes.sort.last
+    latest_specs(true).each do |local_spec|
+      dependency =
+        Gem::Dependency.new local_spec.name, ">= #{local_spec.version}"
+
+      remotes, = fetcher.search_for_dependency dependency
+      remotes  = remotes.map { |n, _| n.version }
+
+      latest_remote = remotes.sort.last
 
-      outdateds << local.name if latest and local.version < latest
+      yield [local_spec, latest_remote] if
+        latest_remote and local_spec.version < latest_remote
     end
 
-    outdateds
+    nil
   end
 
   ##
Index: lib/rubygems/commands/outdated_command.rb
===================================================================
--- lib/rubygems/commands/outdated_command.rb	(revision 42256)
+++ lib/rubygems/commands/outdated_command.rb	(revision 42257)
@@ -16,18 +16,8 @@ class Gem::Commands::OutdatedCommand < G https://github.com/ruby/ruby/blob/trunk/lib/rubygems/commands/outdated_command.rb#L16
   end
 
   def execute
-    Gem::Specification.outdated.sort.each do |name|
-      local   = Gem::Specification.find_all_by_name(name).max
-      dep     = Gem::Dependency.new local.name, ">= #{local.version}"
-      remotes, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
-
-      next if remotes.empty?
-
-      remotes.sort! { |a,b| a[0].version <=> b[0].version }
-
-      highest = remotes.last.first
-
-      say "#{local.name} (#{local.version} < #{highest.version})"
+    Gem::Specification.outdated_and_latest_version.each do |spec, remote_version|
+      say "#{spec.name} (#{spec.version} < #{remote_version})"
     end
   end
 end
Index: lib/rubygems/remote_fetcher.rb
===================================================================
--- lib/rubygems/remote_fetcher.rb	(revision 42256)
+++ lib/rubygems/remote_fetcher.rb	(revision 42257)
@@ -325,7 +325,7 @@ class Gem::RemoteFetcher https://github.com/ruby/ruby/blob/trunk/lib/rubygems/remote_fetcher.rb#L325
 
   def request(uri, request_class, last_modified = nil)
     request = Gem::Request.new uri, request_class, last_modified, @proxy
-
+    
     request.fetch do |req|
       yield req if block_given?
     end
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb	(revision 42256)
+++ lib/rubygems/installer.rb	(revision 42257)
@@ -661,73 +661,20 @@ TEXT https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L661
   # configure scripts and rakefiles or mkrf_conf files.
 
   def build_extensions
-    return if spec.extensions.empty?
+    builder = Gem::Ext::Builder.new spec, @build_args
 
-    if @build_args.empty?
-      say "Building native extensions.  This could take a while..."
-    else
-      say "Building native extensions with: '#{@build_args.join(' ')}'"
-      say "This could take a while..."
-    end
-
-    dest_path = File.join gem_dir, spec.require_paths.first
-    ran_rake = false # only run rake once
-
-    spec.extensions.each do |extension|
-      break if ran_rake
-      results = []
-
-      extension ||= ""
-      extension_dir = File.join gem_dir, File.dirname(extension)
-
-      builder = case extension
-                when /extconf/ then
-                  Gem::Ext::ExtConfBuilder
-                when /configure/ then
-                  Gem::Ext::ConfigureBuilder
-                when /rakefile/i, /mkrf_conf/i then
-                  ran_rake = true
-                  Gem::Ext::RakeBuilder
-                when /CMakeLists.txt/ then
-                  Gem::Ext::CmakeBuilder
-                else
-                  message = "No builder for extension '#{extension}'"
-                  extension_build_error extension_dir, message
-                end
-
-      begin
-        FileUtils.mkdir_p dest_path
-
-        Dir.chdir extension_dir do
-          results = builder.build(extension, gem_dir, dest_path,
-                                  results, @build_args)
-
-          say results.join("\n") if Gem.configuration.really_verbose
-        end
-      rescue
-        extension_build_error(extension_dir, results.join("\n"), $@)
-      end
-    end
+    builder.build_extensions
   end
 
   ##
   # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
+  #
+  # TODO:  Delete this for RubyGems 3.  It remains for API compatibility
 
-  def extension_build_error(build_dir, output, backtrace = nil)
-    gem_make_out = File.join build_dir, 'gem_make.out'
+  def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
+    builder = Gem::Ext::Builder.new spec, @build_args
 
-    open gem_make_out, 'wb' do |io| io.puts output end
-
-    message = <<-EOF
-ERROR: Failed to build gem native extension.
-
-    #{output}
-
-Gem files will remain installed in #{gem_dir} for inspection.
-Results logged to #{gem_make_out}
-EOF
-
-    raise ExtensionBuildError, message, backtrace
+    builder.build_error build_dir, output, backtrace
   end
 
   ##
Index: lib/rubygems/security.rb
===================================================================
--- lib/rubygems/security.rb	(revision 42256)
+++ lib/rubygems/security.rb	(revision 42257)
@@ -368,7 +368,7 @@ module Gem::Security https://github.com/ruby/ruby/blob/trunk/lib/rubygems/security.rb#L368
   # Cipher used to encrypt the key pair used to sign gems.
   # Must be in the list returned by OpenSSL::Cipher.ciphers
 
-  KEY_CIPHER = OpenSSL::Cipher.new('aes256') if defined?(OpenSSL::Cipher)
+  KEY_CIPHER = OpenSSL::Cipher.new('AES-256-CBC') if defined?(OpenSSL::Cipher)
 
   ##
   # One year in seconds
Index: lib/rubygems.rb
===================================================================
--- lib/rubygems.rb	(revision 42256)
+++ lib/rubygems.rb	(revision 42257)
@@ -8,7 +8,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems.rb#L8
 require 'rbconfig'
 
 module Gem
-  VERSION = '2.1.0'
+  VERSION = '2.1.0.rc.1'
 end
 
 # Must be first since it unloads the prelude from 1.9.2
Index: test/rubygems/test_gem_package.rb
===================================================================
--- test/rubygems/test_gem_package.rb	(revision 42256)
+++ test/rubygems/test_gem_package.rb	(revision 42257)
@@ -64,13 +64,16 @@ class TestGemPackage < Gem::Package::Tar https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_package.rb#L64
     reader = Gem::Package::TarReader.new gem_io
 
     checksums = nil
+    tar       = nil
 
     reader.each_entry do |entry|
       case entry.full_name
-      when 'checksums.yaml.gz'
+      when 'checksums.yaml.gz' then
         Zlib::GzipReader.wrap entry do |io|
           checksums = io.read
         end
+      when 'data.tar.gz' then
+        tar = entry.read
       end
     end
 
@@ -83,22 +86,17 @@ class TestGemPackage < Gem::Package::Tar https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_package.rb#L86
     metadata_sha1   = Digest::SHA1.hexdigest s.string
     metadata_sha512 = Digest::SHA512.hexdigest s.string
 
-    data_digests = nil
-    util_tar do |tar|
-      data_digests = package.add_contents tar
-    end
-
     expected = {
       'SHA512' => {
         'metadata.gz' => metadata_sha512,
-        'data.tar.gz' => data_digests['SHA512'].hexdigest,
+        'data.tar.gz' => Digest::SHA512.hexdigest(tar),
       }
     }
 
     if defined?(OpenSSL::Digest) then
       expected['SHA1'] = {
         'metadata.gz' => metadata_sha1,
-        'data.tar.gz' => data_digests['SHA1'].hexdigest,
+        'data.tar.gz' => Digest::SHA1.hexdigest(tar),
       }
     end
 
Index: test/rubygems/test_gem_specification.rb
===================================================================
--- test/rubygems/test_gem_specification.rb	(revision 42256)
+++ test/rubygems/test_gem_specification.rb	(revision 42257)
@@ -828,6 +828,25 @@ dependencies: [] https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_specification.rb#L828
     assert_equal %w[a], Gem::Specification.outdated
   end
 
+  def test_self_outdated_and_latest_remotes
+    util_clear_gems
+    util_setup_fake_fetcher true
+
+    a4 = quick_gem @a1.name, '4'
+    util_build_gem a4
+    b3 = quick_gem @b2.name, '3'
+    util_build_gem b3
+    util_setup_spec_fetcher @a1, @a2, @a3a, a4, @b2, b3
+
+    Gem::Specification.remove_spec @a1
+    Gem::Specification.remove_spec @a2
+    Gem::Specification.remove_spec a4
+    Gem::Specification.remove_spec b3
+
+    assert_equal [[@a3a, a4.version], [@b2, b3.version]],
+                 Gem::Specification.outdated_and_latest_version.to_a
+  end
+
   DATA_PATH = File.expand_path "../data", __FILE__
 
   def test_handles_private_null_type
Index: test/rubygems/test_gem_ext_builder.rb
===================================================================
--- test/rubygems/test_gem_ext_builder.rb	(revision 42256)
+++ test/rubygems/test_gem_ext_builder.rb	(revision 42257)
@@ -1,5 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_ext_builder.rb#L1
 require 'rubygems/test_case'
 require 'rubygems/ext'
+require 'rubygems/installer'
 
 class TestGemExtBuilder < Gem::TestCase
 
@@ -13,6 +14,10 @@ class TestGemExtBuilder < Gem::TestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_ext_builder.rb#L14
     FileUtils.mkdir_p @dest_path
 
     @orig_DESTDIR = ENV['DESTDIR']
+
+    @spec = quick_spec 'a'
+
+    @builder = Gem::Ext::Builder.new @spec, ''
   end
 
   def teardown
@@ -54,5 +59,93 @@ install: https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_ext_builder.rb#L59
     assert_match %r%^install: destination$%, results
   end
 
+  def test_build_extensions_none
+    use_ui @ui do
+      @builder.build_extensions
+    end
+
+    assert_equal '', @ui.output
+    assert_equal '', @ui.error
+
+    refute File.exist?('gem_make.out')
+  end
+
+  def test_build_extensions_extconf_bad
+    @spec.extensions << 'extconf.rb'
+
+    e = assert_raises Gem::Installer::ExtensionBuildError do
+      use_ui @ui do
+        @builder.build_extensions
+      end
+    end
+
+    assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
+
+    assert_equal "Building native extensions.  This could take a while...\n",
+                 @ui.output
+    assert_equal '', @ui.error
+
+    gem_make_out = File.join @gemhome, 'gems', @spec.full_name, '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
+    FileUtils.mkdir_p @spec.gem_dir
+    gem_make_out = File.join @spec.gem_dir, 'gem_make.out'
+    @spec.extensions << nil
+
+    e = assert_raises Gem::Installer::ExtensionBuildError do
+      use_ui @ui do
+        @builder.build_extensions
+      end
+    end
+
+    assert_match(/^\s*No builder for extension ''$/, e.message)
+
+    assert_equal "Building native extensions.  This could take a while...\n",
+                 @ui.output
+    assert_equal '', @ui.error
+
+    assert_equal "No builder for extension ''\n", File.read(gem_make_out)
+  ensure
+    FileUtils.rm_f gem_make_out
+  end
+
+  def test_build_extensions_with_build_args
+    args = ["--aa", "--bb"]
+    @builder.build_args = args
+    @spec.extensions << 'extconf.rb'
+
+    FileUtils.mkdir_p @spec.gem_dir
+
+    open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f|
+      f.write <<-'RUBY'
+        puts "IN EXTCONF"
+        extconf_args = File.join File.dirname(__FILE__), 'extconf_args'
+        File.open extconf_args, 'w' do |f|
+          f.puts ARGV.inspect
+        end
+
+        File.open 'Makefile', 'w' do |f|
+          f.puts "default:\n\techo built"
+          f.puts "install:\n\techo installed"
+        end
+      RUBY
+    end
+
+    use_ui @ui do
+      @builder.build_extensions
+    end
+
+    path = File.join @spec.gem_dir, "extconf_args"
+
+    assert_equal args.inspect, File.read(path).strip
+    assert File.directory? File.join(@spec.gem_dir, 'lib')
+  end
+
 end
 
Index: test/rubygems/test_gem_installer.rb
===================================================================
--- test/rubygems/test_gem_installer.rb	(revision 42256)
+++ test/rubygems/test_gem_installer.rb	(revision 42257)
@@ -55,95 +55,6 @@ load Gem.bin_path('a', 'executable', ver https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L55
     assert_equal expected, wrapper
   end
 
-  def test_build_extensions_none
-    use_ui @ui do
-      @installer.build_extensions
-    end
-
-    assert_equal '', @ui.output
-    assert_equal '', @ui.error
-
-    refute File.exist?('gem_make.out')
-  end
-
-  def test_build_extensions_extconf_bad
-    @installer.spec = @spec
-    @spec.extensions << 'extconf.rb'
-
-    e = assert_raises Gem::Installer::ExtensionBuildError do
-      use_ui @ui do
-        @installer.build_extensions
-      end
-    end
-
-    assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
-
-    assert_equal "Building native extensions.  This could take a while...\n",
-                 @ui.output
-    assert_equal '', @ui.error
-
-    gem_make_out = File.join @gemhome, 'gems', @spec.full_name, '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
-    @installer.spec = @spec
-    FileUtils.mkdir_p @spec.gem_dir
-    gem_make_out = File.join @spec.gem_dir, 'gem_make.out'
-    @spec.extensions << nil
-
-    e = assert_raises Gem::Installer::ExtensionBuildError do
-      use_ui @ui do
-        @installer.build_extensions
-      end
-    end
-
-    assert_match(/^\s*No builder for extension ''$/, e.message)
-
-    assert_equal "Building native extensions.  This could take a while...\n",
-                 @ui.output
-    assert_equal '', @ui.error
-
-    assert_equal "No builder for extension ''\n", File.read(gem_make_out)
-  ensure
-    FileUtils.rm_f gem_make_out
-  end
-
-  def test_build_extensions_with_build_args
-    args = ["--aa", "--bb"]
-    @installer.build_args = args
-    @installer.spec = @s (... truncated)

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

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