diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/rubygems/doctor.rb |
Fresh start
Diffstat (limited to 'jni/ruby/lib/rubygems/doctor.rb')
-rw-r--r-- | jni/ruby/lib/rubygems/doctor.rb | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/jni/ruby/lib/rubygems/doctor.rb b/jni/ruby/lib/rubygems/doctor.rb new file mode 100644 index 0000000..3c71fd5 --- /dev/null +++ b/jni/ruby/lib/rubygems/doctor.rb @@ -0,0 +1,131 @@ +require 'rubygems' +require 'rubygems/user_interaction' + +## +# 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: + ['specifications', '.gemspec'], + ['build_info', '.info'], + ['cache', '.gem'], + ['doc', ''], + ['extensions', ''], + ['gems', ''], + ] + + missing = + Gem::REPOSITORY_SUBDIRECTORIES.sort - + REPOSITORY_EXTENSION_MAP.map { |(k,_)| k }.sort + + raise "Update REPOSITORY_EXTENSION_MAP, missing: #{missing.join ', '}" unless + missing.empty? + + ## + # 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 = 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 = File.join(@gem_repository, sub_directory) + + Dir.entries(directory).sort.each do |ent| + next if ent == "." || ent == ".." + + child = File.join(directory, ent) + next unless File.exist?(child) + + basename = File.basename(child, extension) + next if installed_specs.include? basename + next if /^rubygems-\d/ =~ basename + next if 'specifications' == sub_directory and 'default' == basename + + type = File.directory?(child) ? 'directory' : 'file' + + action = if @dry_run then + 'Extra' + else + FileUtils.rm_r(child) + 'Removed' + end + + say "#{action} #{type} #{sub_directory}/#{File.basename(child)}" + end + rescue Errno::ENOENT + # ignore + end + +end + |