mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rubygems/commands/check_command.rb: Added --doctor and --dry-run
options to clean up after failed uninstallation. * test/rubygems/test_gem_commands_check_command.rb: Test for above. * lib/rubygems/commands/push_command.rb: Allow pushes from RubyGems 2.0.0.preview3 * lib/rubygems/commands/update_command.rb: Use Gem.ruby_version * lib/rubygems/dependency.rb: Update style. * lib/rubygems/installer.rb: Ensure installed gem specifications will be useable. Refactor. * test/rubygems/test_gem_installer.rb: ditto. * lib/rubygems/validator.rb: Fixed bug with unreadable files. * lib/rubygems.rb: Fixed broken methods. * test/rubygems/test_gem.rb: Test for above. * test/rubygems/test_gem_commands_push_command.rb: Fixed overridden Gem.latest_rubygems_version git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38564 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c47c095b97
commit
6fe32d7266
14 changed files with 739 additions and 153 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
Sun Dec 23 09:34:07 2012 Eric Hodel <drbrain@segment7.net>
|
||||
|
||||
* lib/rubygems/commands/check_command.rb: Added --doctor and --dry-run
|
||||
options to clean up after failed uninstallation.
|
||||
* test/rubygems/test_gem_commands_check_command.rb: Test for above.
|
||||
|
||||
* lib/rubygems/commands/push_command.rb: Allow pushes from RubyGems
|
||||
2.0.0.preview3
|
||||
|
||||
* lib/rubygems/commands/update_command.rb: Use Gem.ruby_version
|
||||
|
||||
* lib/rubygems/dependency.rb: Update style.
|
||||
|
||||
* lib/rubygems/installer.rb: Ensure installed gem specifications will
|
||||
be useable. Refactor.
|
||||
* test/rubygems/test_gem_installer.rb: ditto.
|
||||
|
||||
* lib/rubygems/validator.rb: Fixed bug with unreadable files.
|
||||
|
||||
* lib/rubygems.rb: Fixed broken methods.
|
||||
* test/rubygems/test_gem.rb: Test for above.
|
||||
|
||||
* test/rubygems/test_gem_commands_push_command.rb: Fixed overridden
|
||||
Gem.latest_rubygems_version
|
||||
|
||||
Sun Dec 23 01:52:01 2012 Akinori MUSHA <knu@iDaemons.org>
|
||||
|
||||
* io.c (rb_io_lines, rb_io_bytes, rb_io_chars, rb_io_codepoints):
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
require 'rbconfig'
|
||||
|
||||
module Gem
|
||||
VERSION = '2.0.0.preview2.2'
|
||||
VERSION = '2.0.0.preview3'
|
||||
end
|
||||
|
||||
# Must be first since it unloads the prelude from 1.9.2
|
||||
|
@ -123,7 +123,22 @@ module Gem
|
|||
/wince/i,
|
||||
]
|
||||
|
||||
GEM_DEP_FILES = %w!gem.deps.rb Gemfile Isolate!
|
||||
GEM_DEP_FILES = %w[
|
||||
gem.deps.rb
|
||||
Gemfile
|
||||
Isolate
|
||||
]
|
||||
|
||||
##
|
||||
# Subdirectories in a gem repository
|
||||
|
||||
REPOSITORY_SUBDIRECTORIES = %w[
|
||||
build_info
|
||||
cache
|
||||
doc
|
||||
gems
|
||||
specifications
|
||||
]
|
||||
|
||||
@@win_platform = nil
|
||||
|
||||
|
@ -388,7 +403,7 @@ module Gem
|
|||
|
||||
require 'fileutils'
|
||||
|
||||
%w[cache build_info doc gems specifications].each do |name|
|
||||
REPOSITORY_SUBDIRECTORIES.each do |name|
|
||||
subdir = File.join dir, name
|
||||
next if File.exist? subdir
|
||||
FileUtils.mkdir_p subdir rescue nil # in case of perms issues -- lame
|
||||
|
@ -750,33 +765,35 @@ module Gem
|
|||
@ruby
|
||||
end
|
||||
|
||||
# DOC: needs doc'd or :nodoc'd
|
||||
##
|
||||
# Returns the latest release-version specification for the gem +name+.
|
||||
|
||||
def self.latest_spec_for name
|
||||
dependency = Gem::Dependency.new name
|
||||
fetcher = Gem::SpecFetcher.fetcher
|
||||
spec_tuples = fetcher.find_matching dependency
|
||||
dependency = Gem::Dependency.new name
|
||||
fetcher = Gem::SpecFetcher.fetcher
|
||||
spec_tuples, = fetcher.spec_for_dependency dependency
|
||||
|
||||
match = spec_tuples.select { |(n, _, p), _|
|
||||
n == name and Gem::Platform.match p
|
||||
}.sort_by { |(_, version, _), _|
|
||||
version
|
||||
}.last
|
||||
spec, = spec_tuples.first
|
||||
|
||||
match and fetcher.fetch_spec(*match)
|
||||
spec
|
||||
end
|
||||
|
||||
# DOC: needs doc'd or :nodoc'd
|
||||
##
|
||||
# Returns the latest release version of RubyGems.
|
||||
|
||||
def self.latest_rubygems_version
|
||||
latest_version_for('rubygems-update') or
|
||||
raise "Can't find 'rubygems-update' in any repo. Check `gem source list`."
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the version of the latest release-version of gem +name+
|
||||
|
||||
def self.latest_version_for name
|
||||
spec = latest_spec_for name
|
||||
spec and spec.version
|
||||
end
|
||||
|
||||
# DOC: needs doc'd or :nodoc'd
|
||||
def self.latest_rubygems_version
|
||||
latest_version_for("rubygems-update") or
|
||||
raise "Can't find 'rubygems-update' in any repo. Check `gem source list`."
|
||||
end
|
||||
|
||||
##
|
||||
# A Gem::Version for the currently running ruby.
|
||||
|
||||
|
|
|
@ -1,25 +1,44 @@
|
|||
require 'rubygems/command'
|
||||
require 'rubygems/version_option'
|
||||
require 'rubygems/validator'
|
||||
require 'rubygems/doctor'
|
||||
|
||||
class Gem::Commands::CheckCommand < Gem::Command
|
||||
|
||||
include Gem::VersionOption
|
||||
|
||||
def initialize
|
||||
super 'check', 'Check installed gems',
|
||||
:alien => true
|
||||
super 'check', 'Check a gem repository for added or missing files',
|
||||
:alien => true, :doctor => false, :dry_run => false, :gems => true
|
||||
|
||||
add_option('-a', '--alien', "Report 'unmanaged' or rogue files in the",
|
||||
"gem repository") do |value, options|
|
||||
options[:alien] = true
|
||||
add_option('-a', '--[no-]alien',
|
||||
'Report "unmanaged" or rogue files in the',
|
||||
'gem repository') do |value, options|
|
||||
options[:alien] = value
|
||||
end
|
||||
|
||||
add_option('--[no-]doctor',
|
||||
'Clean up uninstalled gems and broken',
|
||||
'specifications') do |value, options|
|
||||
options[:doctor] = value
|
||||
end
|
||||
|
||||
add_option('--[no-]dry-run',
|
||||
'Do not remove files, only report what',
|
||||
'would be removed') do |value, options|
|
||||
options[:dry_run] = value
|
||||
end
|
||||
|
||||
add_option('--[no-]gems',
|
||||
'Check installed gems for problems') do |value, options|
|
||||
options[:gems] = value
|
||||
end
|
||||
|
||||
add_version_option 'check'
|
||||
end
|
||||
|
||||
def execute
|
||||
say "Checking gems..."
|
||||
def check_gems
|
||||
say 'Checking gems...'
|
||||
say
|
||||
gems = get_all_gem_names rescue []
|
||||
|
||||
|
@ -37,4 +56,31 @@ class Gem::Commands::CheckCommand < Gem::Command
|
|||
end
|
||||
end
|
||||
|
||||
def doctor
|
||||
say 'Checking for files from uninstalled gems...'
|
||||
say
|
||||
|
||||
Gem.path.each do |gem_repo|
|
||||
doctor = Gem::Doctor.new gem_repo, options[:dry_run]
|
||||
doctor.doctor
|
||||
end
|
||||
end
|
||||
|
||||
def execute
|
||||
check_gems if options[:gems]
|
||||
doctor if options[:doctor]
|
||||
end
|
||||
|
||||
def arguments # :nodoc:
|
||||
'GEMNAME name of gem to check'
|
||||
end
|
||||
|
||||
def defaults_str # :nodoc:
|
||||
'--gems --alien'
|
||||
end
|
||||
|
||||
def usage # :nodoc:
|
||||
"#{program_name} [OPTIONS] [GEMNAME ...]"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -40,9 +40,17 @@ class Gem::Commands::PushCommand < Gem::Command
|
|||
def send_gem name
|
||||
args = [:post, "api/v1/gems"]
|
||||
|
||||
latest_rubygems_version = Gem.latest_rubygems_version
|
||||
|
||||
if Gem.latest_rubygems_version < Gem::Version.new(Gem::VERSION) then
|
||||
alert_error "Using beta/unreleased version of rubygems. Not pushing."
|
||||
if latest_rubygems_version < Gem.rubygems_version and
|
||||
Gem.rubygems_version.prerelease? and
|
||||
Gem::Version.new('2.0.0.preview3') != Gem.rubygems_version then
|
||||
alert_error <<-ERROR
|
||||
You are using a beta release of RubyGems (#{Gem::VERSION}) which is not
|
||||
allowed to push gems. Please downgrade or upgrade to a release version.
|
||||
|
||||
The latest released RubyGems version is #{latest_rubygems_version}
|
||||
ERROR
|
||||
terminate_interaction 1
|
||||
end
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
|
|||
|
||||
gems_to_update = which_to_update hig, options[:args], :system
|
||||
name, up_ver = gems_to_update.first
|
||||
current_ver = Gem::Version.new Gem::VERSION
|
||||
current_ver = Gem.rubygems_version
|
||||
|
||||
target = if options[:system] == true then
|
||||
up_ver
|
||||
|
|
|
@ -10,14 +10,14 @@ class Gem::Dependency
|
|||
#--
|
||||
# When this list is updated, be sure to change
|
||||
# Gem::Specification::CURRENT_SPECIFICATION_VERSION as well.
|
||||
|
||||
#
|
||||
# REFACTOR: This type of constant, TYPES, indicates we might want
|
||||
# two classes, used via inheretance or duck typing.
|
||||
# two classes, used via inheritance or duck typing.
|
||||
|
||||
TYPES = [
|
||||
:development,
|
||||
:runtime,
|
||||
]
|
||||
:development,
|
||||
:runtime,
|
||||
]
|
||||
|
||||
##
|
||||
# Dependency name or regular expression.
|
||||
|
|
124
lib/rubygems/doctor.rb
Normal file
124
lib/rubygems/doctor.rb
Normal file
|
@ -0,0 +1,124 @@
|
|||
require 'rubygems'
|
||||
require 'rubygems/user_interaction'
|
||||
require 'pathname'
|
||||
|
||||
##
|
||||
# Cleans up after a partially-failed uninstall or for an invalid
|
||||
# Gem::Specification.
|
||||
#
|
||||
# If a specification was removed by hand this will remove any remaining files.
|
||||
#
|
||||
# If a corrupt specification was installed this will clean up warnings by
|
||||
# removing the bogus specification.
|
||||
|
||||
class Gem::Doctor
|
||||
|
||||
include Gem::UserInteraction
|
||||
|
||||
##
|
||||
# Maps a gem subdirectory to the files that are expected to exist in the
|
||||
# subdirectory.
|
||||
|
||||
REPOSITORY_EXTENSION_MAP = { # :nodoc:
|
||||
'build_info' => '.info',
|
||||
'cache' => '.gem',
|
||||
'doc' => '',
|
||||
'gems' => '',
|
||||
'specifications' => '.gemspec'
|
||||
}
|
||||
|
||||
raise 'Update REPOSITORY_EXTENSION_MAP' unless
|
||||
Gem::REPOSITORY_SUBDIRECTORIES == REPOSITORY_EXTENSION_MAP.keys.sort
|
||||
|
||||
##
|
||||
# Creates a new Gem::Doctor that will clean up +gem_repository+. Only one
|
||||
# gem repository may be cleaned at a time.
|
||||
#
|
||||
# If +dry_run+ is true no files or directories will be removed.
|
||||
|
||||
def initialize gem_repository, dry_run = false
|
||||
@gem_repository = Pathname(gem_repository)
|
||||
@dry_run = dry_run
|
||||
|
||||
@installed_specs = nil
|
||||
end
|
||||
|
||||
##
|
||||
# Specs installed in this gem repository
|
||||
|
||||
def installed_specs # :nodoc:
|
||||
@installed_specs ||= Gem::Specification.map { |s| s.full_name }
|
||||
end
|
||||
|
||||
##
|
||||
# Are we doctoring a gem repository?
|
||||
|
||||
def gem_repository?
|
||||
not installed_specs.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Cleans up uninstalled files and invalid gem specifications
|
||||
|
||||
def doctor
|
||||
@orig_home = Gem.dir
|
||||
@orig_path = Gem.path
|
||||
|
||||
say "Checking #{@gem_repository}"
|
||||
|
||||
Gem.use_paths @gem_repository.to_s
|
||||
|
||||
unless gem_repository? then
|
||||
say 'This directory does not appear to be a RubyGems repository, ' +
|
||||
'skipping'
|
||||
say
|
||||
return
|
||||
end
|
||||
|
||||
doctor_children
|
||||
|
||||
say
|
||||
ensure
|
||||
Gem.use_paths @orig_home, *@orig_path
|
||||
end
|
||||
|
||||
##
|
||||
# Cleans up children of this gem repository
|
||||
|
||||
def doctor_children # :nodoc:
|
||||
REPOSITORY_EXTENSION_MAP.each do |sub_directory, extension|
|
||||
doctor_child sub_directory, extension
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Removes files in +sub_directory+ with +extension+
|
||||
|
||||
def doctor_child sub_directory, extension # :nodoc:
|
||||
directory = @gem_repository + sub_directory
|
||||
|
||||
directory.each_child do |child|
|
||||
next unless child.exist?
|
||||
|
||||
basename = child.basename(extension).to_s
|
||||
next if installed_specs.include? basename
|
||||
next if /^rubygems-\d/ =~ basename
|
||||
next if 'specifications' == sub_directory and 'default' == basename
|
||||
|
||||
type = child.directory? ? 'directory' : 'file'
|
||||
|
||||
action = if @dry_run then
|
||||
'Extra'
|
||||
else
|
||||
child.rmtree
|
||||
'Removed'
|
||||
end
|
||||
|
||||
say "#{action} #{type} #{sub_directory}/#{child.basename}"
|
||||
end
|
||||
rescue Errno::ENOENT
|
||||
# ignore
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -202,47 +202,24 @@ class Gem::Installer
|
|||
# specifications/<gem-version>.gemspec #=> the Gem::Specification
|
||||
|
||||
def install
|
||||
verify_gem_home(options[:unpack])
|
||||
|
||||
# If we're forcing the install then disable security unless the security
|
||||
# policy says that we only install signed gems.
|
||||
@security_policy = nil if @force and @security_policy and
|
||||
not @security_policy.only_signed
|
||||
|
||||
unless @force
|
||||
ensure_required_ruby_version_met
|
||||
ensure_required_rubygems_version_met
|
||||
ensure_dependencies_met unless @ignore_dependencies
|
||||
end
|
||||
pre_install_checks
|
||||
|
||||
run_pre_install_hooks
|
||||
|
||||
Gem.ensure_gem_subdirectories gem_home
|
||||
|
||||
# Completely remove any previous gem files
|
||||
FileUtils.rm_rf(gem_dir)
|
||||
FileUtils.rm_rf gem_dir
|
||||
|
||||
FileUtils.mkdir_p gem_dir
|
||||
|
||||
extract_files
|
||||
build_extensions
|
||||
|
||||
build_extensions
|
||||
write_build_info_file
|
||||
run_post_build_hooks
|
||||
|
||||
generate_bin
|
||||
write_spec
|
||||
|
||||
unless @build_args.empty?
|
||||
File.open spec.build_info_file, "w" do |f|
|
||||
@build_args.each { |a| f.puts a }
|
||||
end
|
||||
end
|
||||
|
||||
# TODO should be always cache the file? Other classes have options
|
||||
# to controls if caching is done.
|
||||
cache_file = File.join(gem_home, "cache", "#{spec.full_name}.gem")
|
||||
|
||||
FileUtils.cp gem, cache_file unless File.exist? cache_file
|
||||
write_cache_file
|
||||
|
||||
say spec.post_install_message unless spec.post_install_message.nil?
|
||||
|
||||
|
@ -255,7 +232,7 @@ class Gem::Installer
|
|||
spec
|
||||
|
||||
# TODO This rescue is in the wrong place. What is raising this exception?
|
||||
# move this rescue to arround the code that actually might raise it.
|
||||
# move this rescue to around the code that actually might raise it.
|
||||
rescue Zlib::GzipFile::Error
|
||||
raise Gem::InstallError, "gzip error installing #{gem}"
|
||||
end
|
||||
|
@ -506,6 +483,21 @@ class Gem::Installer
|
|||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Ensures the Gem::Specification written out for this gem is loadable upon
|
||||
# installation.
|
||||
|
||||
def ensure_loadable_spec
|
||||
ruby = spec.to_ruby_for_cache
|
||||
|
||||
begin
|
||||
eval ruby
|
||||
rescue StandardError, SyntaxError => e
|
||||
raise Gem::InstallError,
|
||||
"The specification for #{spec.full_name} is corrupt (#{e.class})"
|
||||
end
|
||||
end
|
||||
|
||||
# DOC: Missing docs or :nodoc:.
|
||||
def ensure_required_ruby_version_met
|
||||
if rrv = spec.required_ruby_version then
|
||||
|
@ -736,5 +728,59 @@ EOF
|
|||
def dir
|
||||
gem_dir.to_s
|
||||
end
|
||||
|
||||
##
|
||||
# Performs various checks before installing the gem such as the install
|
||||
# repository is writable and its directories exist, required ruby and
|
||||
# rubygems versions are met and that dependencies are installed.
|
||||
#
|
||||
# Version and dependency checks are skipped if this install is forced.
|
||||
#
|
||||
# The dependent check will be skipped this install is ignoring dependencies.
|
||||
|
||||
def pre_install_checks
|
||||
verify_gem_home options[:unpack]
|
||||
|
||||
# If we're forcing the install then disable security unless the security
|
||||
# policy says that we only install signed gems.
|
||||
@security_policy = nil if
|
||||
@force and @security_policy and not @security_policy.only_signed
|
||||
|
||||
ensure_loadable_spec
|
||||
|
||||
Gem.ensure_gem_subdirectories gem_home
|
||||
|
||||
return true if @force
|
||||
|
||||
ensure_required_ruby_version_met
|
||||
ensure_required_rubygems_version_met
|
||||
ensure_dependencies_met unless @ignore_dependencies
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Writes the file containing the arguments for building this gem's
|
||||
# extensions.
|
||||
|
||||
def write_build_info_file
|
||||
return if @build_args.empty?
|
||||
|
||||
open spec.build_info_file, 'w' do |io|
|
||||
@build_args.each do |arg|
|
||||
io.puts arg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Writes the .gem file to the cache directory
|
||||
|
||||
def write_cache_file
|
||||
cache_file = File.join gem_home, 'cache', spec.file_name
|
||||
|
||||
FileUtils.cp @gem, cache_file unless File.exist? cache_file
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -58,13 +58,11 @@ class Gem::Validator
|
|||
public
|
||||
|
||||
ErrorData = Struct.new :path, :problem do
|
||||
|
||||
def <=> other
|
||||
return nil unless self.class === other
|
||||
|
||||
[path, problem] <=> [other.path, other.problem]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -121,7 +119,6 @@ class Gem::Validator
|
|||
File.readable? File.join(gem_directory, file_name)
|
||||
}
|
||||
|
||||
unreadable.map! { |entry, _| entry['path'] }
|
||||
unreadable.sort.each do |path|
|
||||
errors[gem_name][path] = "Unreadable file"
|
||||
end
|
||||
|
@ -153,7 +150,9 @@ class Gem::Validator
|
|||
end
|
||||
|
||||
errors.each do |name, subhash|
|
||||
errors[name] = subhash.map { |path, msg| ErrorData.new(path, msg) }.sort
|
||||
errors[name] = subhash.map do |path, msg|
|
||||
ErrorData.new path, msg
|
||||
end.sort
|
||||
end
|
||||
|
||||
errors
|
||||
|
|
|
@ -774,6 +774,45 @@ class TestGem < Gem::TestCase
|
|||
assert_equal cwd, $LOAD_PATH.shift
|
||||
end
|
||||
|
||||
def test_self_latest_spec_for
|
||||
a1 = quick_spec 'a', 1
|
||||
a2 = quick_spec 'a', 2
|
||||
a3a = quick_spec 'a', '3.a'
|
||||
|
||||
util_setup_fake_fetcher
|
||||
util_setup_spec_fetcher a1, a2, a3a
|
||||
|
||||
spec = Gem.latest_spec_for 'a'
|
||||
|
||||
assert_equal a2, spec
|
||||
end
|
||||
|
||||
def test_self_latest_rubygems_version
|
||||
r1 = quick_spec 'rubygems-update', '1.8.23'
|
||||
r2 = quick_spec 'rubygems-update', '1.8.24'
|
||||
r3 = quick_spec 'rubygems-update', '2.0.0.preview3'
|
||||
|
||||
util_setup_fake_fetcher
|
||||
util_setup_spec_fetcher r1, r2, r3
|
||||
|
||||
version = Gem.latest_rubygems_version
|
||||
|
||||
assert_equal Gem::Version.new('1.8.24'), version
|
||||
end
|
||||
|
||||
def test_self_latest_version_for
|
||||
a1 = quick_spec 'a', 1
|
||||
a2 = quick_spec 'a', 2
|
||||
a3a = quick_spec 'a', '3.a'
|
||||
|
||||
util_setup_fake_fetcher
|
||||
util_setup_spec_fetcher a1, a2, a3a
|
||||
|
||||
version = Gem.latest_version_for 'a'
|
||||
|
||||
assert_equal Gem::Version.new(2), version
|
||||
end
|
||||
|
||||
def test_self_loaded_specs
|
||||
foo = quick_spec 'foo'
|
||||
install_gem foo
|
||||
|
|
|
@ -9,10 +9,60 @@ class TestGemCommandsCheckCommand < Gem::TestCase
|
|||
@cmd = Gem::Commands::CheckCommand.new
|
||||
end
|
||||
|
||||
def gem name
|
||||
spec = quick_gem name do |gem|
|
||||
gem.files = %W[lib/#{name}.rb Rakefile]
|
||||
end
|
||||
|
||||
write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
|
||||
write_file File.join(*%W[gems #{spec.full_name} Rakefile])
|
||||
|
||||
spec
|
||||
end
|
||||
|
||||
def test_initialize
|
||||
assert_equal "check", @cmd.command
|
||||
assert_equal "gem check", @cmd.program_name
|
||||
assert_match(/Check/, @cmd.summary)
|
||||
end
|
||||
|
||||
def test_handle_options
|
||||
@cmd.handle_options %w[--no-alien --no-gems --doctor --dry-run]
|
||||
|
||||
assert @cmd.options[:doctor]
|
||||
refute @cmd.options[:alien]
|
||||
assert @cmd.options[:dry_run]
|
||||
refute @cmd.options[:gems]
|
||||
end
|
||||
|
||||
def test_handle_options_defaults
|
||||
@cmd.handle_options []
|
||||
|
||||
assert @cmd.options[:alien]
|
||||
assert @cmd.options[:gems]
|
||||
refute @cmd.options[:doctor]
|
||||
refute @cmd.options[:dry_run]
|
||||
end
|
||||
|
||||
def test_doctor
|
||||
a = gem 'a'
|
||||
b = gem 'b'
|
||||
|
||||
FileUtils.rm b.spec_file
|
||||
|
||||
assert_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
|
||||
Gem.use_paths @gemhome
|
||||
|
||||
capture_io do
|
||||
use_ui @ui do
|
||||
@cmd.doctor
|
||||
end
|
||||
end
|
||||
|
||||
refute_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
require 'rubygems/test_case'
|
||||
require 'rubygems/commands/push_command'
|
||||
|
||||
module Gem
|
||||
class << self; remove_method :latest_rubygems_version; end
|
||||
|
||||
def self.latest_rubygems_version
|
||||
Gem::Version.new Gem::VERSION
|
||||
end
|
||||
end
|
||||
|
||||
class TestGemCommandsPushCommand < Gem::TestCase
|
||||
|
||||
def setup
|
||||
|
@ -33,6 +25,23 @@ class TestGemCommandsPushCommand < Gem::TestCase
|
|||
Gem::RemoteFetcher.fetcher = @fetcher
|
||||
|
||||
@cmd = Gem::Commands::PushCommand.new
|
||||
|
||||
class << Gem
|
||||
alias_method :orig_latest_rubygems_version, :latest_rubygems_version
|
||||
|
||||
def latest_rubygems_version
|
||||
Gem.rubygems_version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def teardown
|
||||
super
|
||||
|
||||
class << Gem
|
||||
remove_method :latest_rubygems_version
|
||||
alias_method :latest_rubygems_version, :orig_latest_rubygems_version
|
||||
end
|
||||
end
|
||||
|
||||
def send_battery
|
||||
|
|
168
test/rubygems/test_gem_doctor.rb
Normal file
168
test/rubygems/test_gem_doctor.rb
Normal file
|
@ -0,0 +1,168 @@
|
|||
require 'rubygems/test_case'
|
||||
require 'rubygems/doctor'
|
||||
|
||||
class TestGemDoctor < Gem::TestCase
|
||||
|
||||
def gem name
|
||||
spec = quick_gem name do |gem|
|
||||
gem.files = %W[lib/#{name}.rb Rakefile]
|
||||
end
|
||||
|
||||
write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
|
||||
write_file File.join(*%W[gems #{spec.full_name} Rakefile])
|
||||
|
||||
spec
|
||||
end
|
||||
|
||||
def test_doctor
|
||||
a = gem 'a'
|
||||
b = gem 'b'
|
||||
c = gem 'c'
|
||||
|
||||
Gem.use_paths @userhome, @gemhome
|
||||
|
||||
FileUtils.rm b.spec_file
|
||||
|
||||
open c.spec_file, 'w' do |io|
|
||||
io.write 'this will raise an exception when evaluated.'
|
||||
end
|
||||
|
||||
assert_path_exists File.join(a.gem_dir, 'Rakefile')
|
||||
assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb')
|
||||
|
||||
assert_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
|
||||
assert_path_exists c.gem_dir
|
||||
assert_path_exists c.spec_file
|
||||
|
||||
doctor = Gem::Doctor.new @gemhome
|
||||
|
||||
capture_io do
|
||||
use_ui @ui do
|
||||
doctor.doctor
|
||||
end
|
||||
end
|
||||
|
||||
assert_path_exists File.join(a.gem_dir, 'Rakefile')
|
||||
assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb')
|
||||
|
||||
refute_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
|
||||
refute_path_exists c.gem_dir
|
||||
refute_path_exists c.spec_file
|
||||
|
||||
expected = <<-OUTPUT
|
||||
Checking #{@gemhome}
|
||||
Removed directory gems/b-2
|
||||
Removed directory gems/c-2
|
||||
Removed file specifications/c-2.gemspec
|
||||
|
||||
OUTPUT
|
||||
|
||||
assert_equal expected, @ui.output
|
||||
|
||||
assert_equal Gem.dir, @userhome
|
||||
assert_equal Gem.path, [@gemhome, @userhome]
|
||||
end
|
||||
|
||||
def test_doctor_dry_run
|
||||
a = gem 'a'
|
||||
b = gem 'b'
|
||||
c = gem 'c'
|
||||
|
||||
Gem.use_paths @userhome, @gemhome
|
||||
|
||||
FileUtils.rm b.spec_file
|
||||
|
||||
open c.spec_file, 'w' do |io|
|
||||
io.write 'this will raise an exception when evaluated.'
|
||||
end
|
||||
|
||||
assert_path_exists File.join(a.gem_dir, 'Rakefile')
|
||||
assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb')
|
||||
|
||||
assert_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
|
||||
assert_path_exists c.gem_dir
|
||||
assert_path_exists c.spec_file
|
||||
|
||||
doctor = Gem::Doctor.new @gemhome, true
|
||||
|
||||
capture_io do
|
||||
use_ui @ui do
|
||||
doctor.doctor
|
||||
end
|
||||
end
|
||||
|
||||
assert_path_exists File.join(a.gem_dir, 'Rakefile')
|
||||
assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb')
|
||||
|
||||
assert_path_exists b.gem_dir
|
||||
refute_path_exists b.spec_file
|
||||
|
||||
assert_path_exists c.gem_dir
|
||||
assert_path_exists c.spec_file
|
||||
|
||||
expected = <<-OUTPUT
|
||||
Checking #{@gemhome}
|
||||
Extra directory gems/b-2
|
||||
Extra directory gems/c-2
|
||||
Extra file specifications/c-2.gemspec
|
||||
|
||||
OUTPUT
|
||||
|
||||
assert_equal expected, @ui.output
|
||||
|
||||
assert_equal Gem.dir, @userhome
|
||||
assert_equal Gem.path, [@gemhome, @userhome]
|
||||
end
|
||||
|
||||
def test_doctor_non_gem_home
|
||||
other_dir = File.join @tempdir, 'other', 'dir'
|
||||
|
||||
FileUtils.mkdir_p other_dir
|
||||
|
||||
doctor = Gem::Doctor.new @tempdir
|
||||
|
||||
capture_io do
|
||||
use_ui @ui do
|
||||
doctor.doctor
|
||||
end
|
||||
end
|
||||
|
||||
assert_path_exists other_dir
|
||||
|
||||
expected = <<-OUTPUT
|
||||
Checking #{@tempdir}
|
||||
This directory does not appear to be a RubyGems repository, skipping
|
||||
|
||||
OUTPUT
|
||||
|
||||
assert_equal expected, @ui.output
|
||||
end
|
||||
|
||||
def test_doctor_child_missing
|
||||
doctor = Gem::Doctor.new @gemhome
|
||||
|
||||
doctor.doctor_child 'missing', ''
|
||||
|
||||
assert true # count
|
||||
end
|
||||
|
||||
def test_gem_repository_eh
|
||||
doctor = Gem::Doctor.new @gemhome
|
||||
|
||||
refute doctor.gem_repository?, 'no gems installed'
|
||||
|
||||
quick_spec 'a'
|
||||
|
||||
doctor = Gem::Doctor.new @gemhome
|
||||
|
||||
assert doctor.gem_repository?, 'gems installed'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -245,6 +245,34 @@ load Gem.bin_path('a', 'executable', version)
|
|||
assert_equal 'a requires b (> 2)', e.message
|
||||
end
|
||||
|
||||
def test_ensure_loadable_spec
|
||||
a, a_gem = util_gem 'a', 2 do |s|
|
||||
s.add_dependency 'garbage ~> 5'
|
||||
end
|
||||
|
||||
installer = Gem::Installer.new a_gem
|
||||
|
||||
e = assert_raises Gem::InstallError do
|
||||
installer.ensure_loadable_spec
|
||||
end
|
||||
|
||||
assert_equal "The specification for #{a.full_name} is corrupt " +
|
||||
"(SyntaxError)", e.message
|
||||
end
|
||||
|
||||
def test_ensure_loadable_spec_security_policy
|
||||
a, a_gem = util_gem 'a', 2 do |s|
|
||||
s.add_dependency 'garbage ~> 5'
|
||||
end
|
||||
|
||||
policy = Gem::Security::HighSecurity
|
||||
installer = Gem::Installer.new a_gem, :security_policy => policy
|
||||
|
||||
assert_raises Gem::Security::Exception do
|
||||
installer.ensure_loadable_spec
|
||||
end
|
||||
end
|
||||
|
||||
def test_extract_files
|
||||
@installer.extract_files
|
||||
|
||||
|
@ -818,45 +846,6 @@ load Gem.bin_path('a', 'executable', version)
|
|||
"code.rb from prior install of same gem shouldn't remain here")
|
||||
end
|
||||
|
||||
def test_install_check_dependencies
|
||||
@spec.add_dependency 'b', '> 5'
|
||||
util_setup_gem
|
||||
|
||||
use_ui @ui do
|
||||
assert_raises Gem::InstallError do
|
||||
@installer.install
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_install_check_dependencies_install_dir
|
||||
gemhome2 = "#{@gemhome}2"
|
||||
@spec.add_dependency 'd'
|
||||
|
||||
quick_gem 'd', 2
|
||||
|
||||
FileUtils.mv @gemhome, gemhome2
|
||||
|
||||
# Don't leak any already activated gems into the installer, require
|
||||
# that it work everything out on it's own.
|
||||
Gem::Specification.reset
|
||||
|
||||
util_setup_gem
|
||||
|
||||
@installer = Gem::Installer.new @gem, :install_dir => gemhome2
|
||||
|
||||
gem_home = Gem.dir
|
||||
|
||||
build_rake_in do
|
||||
use_ui @ui do
|
||||
@installer.install
|
||||
end
|
||||
end
|
||||
|
||||
assert File.exist?(File.join(gemhome2, 'gems', @spec.full_name))
|
||||
assert_equal gem_home, Gem.dir
|
||||
end
|
||||
|
||||
def test_install_force
|
||||
use_ui @ui do
|
||||
installer = Gem::Installer.new old_ruby_required, :force => true
|
||||
|
@ -867,30 +856,6 @@ load Gem.bin_path('a', 'executable', version)
|
|||
assert File.exist?(gem_dir)
|
||||
end
|
||||
|
||||
def test_install_ignore_dependencies
|
||||
Dir.mkdir util_inst_bindir
|
||||
@spec.add_dependency 'b', '> 5'
|
||||
util_setup_gem
|
||||
@installer.ignore_dependencies = true
|
||||
|
||||
build_rake_in do
|
||||
use_ui @ui do
|
||||
assert_equal @spec, @installer.install
|
||||
end
|
||||
end
|
||||
|
||||
gemdir = File.join @gemhome, 'gems', @spec.full_name
|
||||
assert File.exist?(gemdir)
|
||||
|
||||
exe = File.join(gemdir, 'bin', 'executable')
|
||||
assert File.exist?(exe)
|
||||
exe_mode = File.stat(exe).mode & 0111
|
||||
assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
|
||||
assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
|
||||
|
||||
assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
|
||||
end
|
||||
|
||||
def test_install_missing_dirs
|
||||
FileUtils.rm_f File.join(Gem.dir, 'cache')
|
||||
FileUtils.rm_f File.join(Gem.dir, 'docs')
|
||||
|
@ -999,18 +964,78 @@ load Gem.bin_path('a', 'executable', version)
|
|||
assert_match %r|I am a shiny gem!|, @ui.output
|
||||
end
|
||||
|
||||
def test_install_wrong_ruby_version
|
||||
def test_installation_satisfies_dependency_eh
|
||||
quick_spec 'a'
|
||||
|
||||
dep = Gem::Dependency.new 'a', '>= 2'
|
||||
assert @installer.installation_satisfies_dependency?(dep)
|
||||
|
||||
dep = Gem::Dependency.new 'a', '> 2'
|
||||
refute @installer.installation_satisfies_dependency?(dep)
|
||||
end
|
||||
|
||||
def test_pre_install_checks_dependencies
|
||||
@spec.add_dependency 'b', '> 5'
|
||||
util_setup_gem
|
||||
|
||||
use_ui @ui do
|
||||
assert_raises Gem::InstallError do
|
||||
@installer.install
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_pre_install_checks_dependencies_ignore
|
||||
@spec.add_dependency 'b', '> 5'
|
||||
@installer.ignore_dependencies = true
|
||||
|
||||
build_rake_in do
|
||||
use_ui @ui do
|
||||
assert @installer.pre_install_checks
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_pre_install_checks_dependencies_install_dir
|
||||
gemhome2 = "#{@gemhome}2"
|
||||
@spec.add_dependency 'd'
|
||||
|
||||
quick_gem 'd', 2
|
||||
|
||||
gem = File.join @gemhome, @spec.file_name
|
||||
|
||||
FileUtils.mv @gemhome, gemhome2
|
||||
FileUtils.mkdir @gemhome
|
||||
|
||||
FileUtils.mv File.join(gemhome2, 'cache', @spec.file_name), gem
|
||||
|
||||
# Don't leak any already activated gems into the installer, require
|
||||
# that it work everything out on it's own.
|
||||
Gem::Specification.reset
|
||||
|
||||
installer = Gem::Installer.new gem, :install_dir => gemhome2
|
||||
|
||||
gem_home = Gem.dir
|
||||
|
||||
build_rake_in do
|
||||
use_ui @ui do
|
||||
assert installer.pre_install_checks
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_pre_install_checks_ruby_version
|
||||
use_ui @ui do
|
||||
installer = Gem::Installer.new old_ruby_required
|
||||
e = assert_raises Gem::InstallError do
|
||||
installer.install
|
||||
installer.pre_install_checks
|
||||
end
|
||||
assert_equal 'old_ruby_required requires Ruby version = 1.4.6.',
|
||||
e.message
|
||||
end
|
||||
end
|
||||
|
||||
def test_install_wrong_rubygems_version
|
||||
def test_pre_install_checks_wrong_rubygems_version
|
||||
spec = quick_spec 'old_rubygems_required', '1' do |s|
|
||||
s.required_rubygems_version = '< 0'
|
||||
end
|
||||
|
@ -1022,23 +1047,13 @@ load Gem.bin_path('a', 'executable', version)
|
|||
use_ui @ui do
|
||||
@installer = Gem::Installer.new gem
|
||||
e = assert_raises Gem::InstallError do
|
||||
@installer.install
|
||||
@installer.pre_install_checks
|
||||
end
|
||||
assert_equal 'old_rubygems_required requires RubyGems version < 0. ' +
|
||||
"Try 'gem update --system' to update RubyGems itself.", e.message
|
||||
end
|
||||
end
|
||||
|
||||
def test_installation_satisfies_dependency_eh
|
||||
quick_spec 'a'
|
||||
|
||||
dep = Gem::Dependency.new 'a', '>= 2'
|
||||
assert @installer.installation_satisfies_dependency?(dep)
|
||||
|
||||
dep = Gem::Dependency.new 'a', '> 2'
|
||||
refute @installer.installation_satisfies_dependency?(dep)
|
||||
end
|
||||
|
||||
def test_shebang
|
||||
util_make_exec @spec, "#!/usr/bin/ruby"
|
||||
|
||||
|
@ -1190,6 +1205,46 @@ load Gem.bin_path('a', 'executable', version)
|
|||
assert File.exist?(File.join(dest, 'bin', 'executable'))
|
||||
end
|
||||
|
||||
def test_write_build_args
|
||||
refute_path_exists @spec.build_info_file
|
||||
|
||||
@installer.build_args = %w[
|
||||
--with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
|
||||
]
|
||||
|
||||
@installer.write_build_info_file
|
||||
|
||||
assert_path_exists @spec.build_info_file
|
||||
|
||||
expected = "--with-libyaml-dir\n/usr/local/Cellar/libyaml/0.1.4\n"
|
||||
|
||||
assert_equal expected, File.read(@spec.build_info_file)
|
||||
end
|
||||
|
||||
def test_write_build_args_empty
|
||||
refute_path_exists @spec.build_info_file
|
||||
|
||||
@installer.write_build_info_file
|
||||
|
||||
refute_path_exists @spec.build_info_file
|
||||
end
|
||||
|
||||
def test_write_cache_file
|
||||
cache_file = File.join @gemhome, 'cache', @spec.file_name
|
||||
gem = File.join @gemhome, @spec.file_name
|
||||
|
||||
FileUtils.mv cache_file, gem
|
||||
refute_path_exists cache_file
|
||||
|
||||
installer = Gem::Installer.new gem
|
||||
installer.spec = @spec
|
||||
installer.gem_home = @gemhome
|
||||
|
||||
installer.write_cache_file
|
||||
|
||||
assert_path_exists cache_file
|
||||
end
|
||||
|
||||
def test_write_spec
|
||||
FileUtils.rm @spec.spec_file
|
||||
refute File.exist?(@spec.spec_file)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue