diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-12-23 00:35:09 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-12-23 00:35:09 +0000 |
commit | 6fe32d72667945605ef710395706e04491bfd86a (patch) | |
tree | 7fe4b8f779ff75067b45f48502864fb05787cee7 /lib/rubygems/doctor.rb | |
parent | c47c095b9740e7c19d6fdca29ab661c1089221d4 (diff) | |
download | ruby-6fe32d72667945605ef710395706e04491bfd86a.tar.gz |
* 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
Diffstat (limited to 'lib/rubygems/doctor.rb')
-rw-r--r-- | lib/rubygems/doctor.rb | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/rubygems/doctor.rb b/lib/rubygems/doctor.rb new file mode 100644 index 0000000000..198c758b00 --- /dev/null +++ b/lib/rubygems/doctor.rb @@ -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 + |