summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-30 22:10:21 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-07-30 22:10:21 +0000
commit310d77d4b05d1aa166616ca323ebcc7f67bc7378 (patch)
treec778eba7300c7eec523962d80f973d1ab1f18a4e /lib
parentd82e5cc4cc0c3340a9fa92f795751d495e13efe1 (diff)
* lib/rubygems: Import RubyGems from master as of commit 523551c
* test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/commands/outdated_command.rb14
-rw-r--r--lib/rubygems/ext/builder.rb118
-rw-r--r--lib/rubygems/installer.rb67
-rw-r--r--lib/rubygems/remote_fetcher.rb2
-rw-r--r--lib/rubygems/security.rb2
-rw-r--r--lib/rubygems/specification.rb36
7 files changed, 157 insertions, 84 deletions
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 0c9dc759b4..55658201f1 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
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
diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb
index 887faab0a2..196d0d67e6 100644
--- a/lib/rubygems/commands/outdated_command.rb
+++ b/lib/rubygems/commands/outdated_command.rb
@@ -16,18 +16,8 @@ class Gem::Commands::OutdatedCommand < Gem::Command
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
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index ee390578ae..8c05723573 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -4,8 +4,23 @@
# 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
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
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index f8a520d344..49ad7dfae5 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -661,73 +661,20 @@ TEXT
# 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'
-
- 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
+ def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
+ builder = Gem::Ext::Builder.new spec, @build_args
- raise ExtensionBuildError, message, backtrace
+ builder.build_error build_dir, output, backtrace
end
##
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb
index 6abd6bd9db..f00555a1e2 100644
--- a/lib/rubygems/remote_fetcher.rb
+++ b/lib/rubygems/remote_fetcher.rb
@@ -325,7 +325,7 @@ class Gem::RemoteFetcher
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
diff --git a/lib/rubygems/security.rb b/lib/rubygems/security.rb
index ef0ff12cda..bfd6fd225b 100644
--- a/lib/rubygems/security.rb
+++ b/lib/rubygems/security.rb
@@ -368,7 +368,7 @@ module Gem::Security
# 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
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 78f62c7a89..d2d48c8501 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -1016,25 +1016,43 @@ class Gem::Specification < Gem::BasicSpecification
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 }
- outdateds << local.name if latest and local.version < latest
+ latest_remote = remotes.sort.last
+
+ yield [local_spec, latest_remote] if
+ latest_remote and local_spec.version < latest_remote
end
- outdateds
+ nil
end
##