lib/rubygems/commands/cleanup_command.rb in rubygems-update-2.0.0.preview2.2 vs lib/rubygems/commands/cleanup_command.rb in rubygems-update-2.0.0.rc.1
- old
+ new
@@ -10,10 +10,18 @@
:force => false, :install_dir => Gem.dir
add_option('-d', '--dryrun', "") do |value, options|
options[:dryrun] = true
end
+
+ @candidate_gems = nil
+ @default_gems = []
+ @full = nil
+ @gems_to_cleanup = nil
+ @original_home = nil
+ @original_path = nil
+ @primary_gems = nil
end
def arguments # :nodoc:
"GEMNAME name of gem to cleanup"
end
@@ -36,82 +44,122 @@
"#{program_name} [GEMNAME ...]"
end
def execute
say "Cleaning up installed gems..."
- primary_gems = {}
- Gem::Specification.each do |spec|
- if primary_gems[spec.name].nil? or
- primary_gems[spec.name].version < spec.version then
- primary_gems[spec.name] = spec
+ if options[:args].empty? then
+ done = false
+ last_set = nil
+
+ until done do
+ clean_gems
+
+ this_set = @gems_to_cleanup.map { |spec| spec.full_name }.sort
+
+ done = this_set.empty? || last_set == this_set
+
+ last_set = this_set
end
+ else
+ clean_gems
end
- candidate_gems = unless options[:args].empty? then
- options[:args].map do |gem_name|
- Gem::Specification.find_all_by_name gem_name
- end.flatten
- else
- Gem::Specification.to_a
- end
+ say "Clean Up Complete"
- gems_to_cleanup = candidate_gems.select { |spec|
- !spec.default_gem? and
- primary_gems[spec.name].version != spec.version
- }
+ if Gem.configuration.really_verbose then
+ skipped = @default_gems.map { |spec| spec.full_name }
- full = Gem::DependencyList.from_specs
+ say "Skipped default gems: #{skipped.join ', '}"
+ end
+ end
+ def clean_gems
+ get_primary_gems
+ get_candidate_gems
+ get_gems_to_cleanup
+
+ @full = Gem::DependencyList.from_specs
+
deplist = Gem::DependencyList.new
- gems_to_cleanup.uniq.each do |spec| deplist.add spec end
+ @gems_to_cleanup.each do |spec| deplist.add spec end
- deps = deplist.strongly_connected_components.flatten.reverse
+ deps = deplist.strongly_connected_components.flatten
- original_home = Gem.dir
- original_path = Gem.path
+ @original_home = Gem.dir
+ @original_path = Gem.path
- deps.each do |spec|
- next unless full.ok_to_remove?(spec.full_name)
+ deps.reverse_each do |spec|
+ uninstall_dep spec
+ end
- if options[:dryrun] then
- say "Dry Run Mode: Would uninstall #{spec.full_name}"
- else
- say "Attempting to uninstall #{spec.full_name}"
+ Gem::Specification.reset
+ end
- options[:args] = [spec.name]
+ def get_candidate_gems
+ @candidate_gems = unless options[:args].empty? then
+ options[:args].map do |gem_name|
+ Gem::Specification.find_all_by_name gem_name
+ end.flatten
+ else
+ Gem::Specification.to_a
+ end
+ end
- uninstall_options = {
- :executables => false,
- :version => "= #{spec.version}",
- }
+ def get_gems_to_cleanup
+ gems_to_cleanup = @candidate_gems.select { |spec|
+ @primary_gems[spec.name].version != spec.version
+ }
- uninstall_options[:user_install] = Gem.user_dir == spec.base_dir
+ default_gems, gems_to_cleanup = gems_to_cleanup.partition { |spec|
+ spec.default_gem?
+ }
- uninstaller = Gem::Uninstaller.new spec.name, uninstall_options
+ @default_gems += default_gems
+ @default_gems.uniq!
+ @gems_to_cleanup = gems_to_cleanup.uniq
+ end
- begin
- uninstaller.uninstall
- rescue Gem::DependencyRemovalException, Gem::InstallError,
- Gem::GemNotInHomeException, Gem::FilePermissionError => e
- say "Unable to uninstall #{spec.full_name}:"
- say "\t#{e.class}: #{e.message}"
- end
+ def get_primary_gems
+ @primary_gems = {}
+
+ Gem::Specification.each do |spec|
+ if @primary_gems[spec.name].nil? or
+ @primary_gems[spec.name].version < spec.version then
+ @primary_gems[spec.name] = spec
end
+ end
+ end
- # Restore path Gem::Uninstaller may have change
- Gem.use_paths(original_home, *original_path)
+ def uninstall_dep spec
+ return unless @full.ok_to_remove?(spec.full_name)
+
+ if options[:dryrun] then
+ say "Dry Run Mode: Would uninstall #{spec.full_name}"
+ return
end
- say "Clean Up Complete"
+ say "Attempting to uninstall #{spec.full_name}"
- if Gem.configuration.really_verbose then
- skipped = candidate_gems.
- select { |spec| spec.default_gem? }.
- map { |spec| spec.full_name}
+ uninstall_options = {
+ :executables => false,
+ :version => "= #{spec.version}",
+ }
- say "Skipped default gems: #{skipped.join ', '}"
+ uninstall_options[:user_install] = Gem.user_dir == spec.base_dir
+
+ uninstaller = Gem::Uninstaller.new spec.name, uninstall_options
+
+ begin
+ uninstaller.uninstall
+ rescue Gem::DependencyRemovalException, Gem::InstallError,
+ Gem::GemNotInHomeException, Gem::FilePermissionError => e
+ say "Unable to uninstall #{spec.full_name}:"
+ say "\t#{e.class}: #{e.message}"
end
+ ensure
+ # Restore path Gem::Uninstaller may have changed
+ Gem.use_paths @original_home, *@original_path
end
end