mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
* 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
This commit is contained in:
parent
d82e5cc4cc
commit
310d77d4b0
14 changed files with 311 additions and 212 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
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
|
||||
|
||||
##
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
||||
outdateds << local.name if latest and local.version < latest
|
||||
remotes, = fetcher.search_for_dependency dependency
|
||||
remotes = remotes.map { |n, _| n.version }
|
||||
|
||||
latest_remote = remotes.sort.last
|
||||
|
||||
yield [local_spec, latest_remote] if
|
||||
latest_remote and local_spec.version < latest_remote
|
||||
end
|
||||
|
||||
outdateds
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue