1require 'rubygems/command'
2require 'rubygems/version_option'
3require 'rubygems/uninstaller'
4
5##
6# Gem uninstaller command line tool
7#
8# See `gem help uninstall`
9
10class Gem::Commands::UninstallCommand < Gem::Command
11
12  include Gem::VersionOption
13
14  def initialize
15    super 'uninstall', 'Uninstall gems from the local repository',
16          :version => Gem::Requirement.default, :user_install => true,
17          :check_dev => false
18
19    add_option('-a', '--[no-]all',
20      'Uninstall all matching versions'
21      ) do |value, options|
22      options[:all] = value
23    end
24
25    add_option('-I', '--[no-]ignore-dependencies',
26               'Ignore dependency requirements while',
27               'uninstalling') do |value, options|
28      options[:ignore] = value
29    end
30
31    add_option('-D', '--[no-]-check-development',
32               'Check development dependencies while uninstalling',
33               '(default: false)') do |value, options|
34      options[:check_dev] = value
35    end
36
37    add_option('-x', '--[no-]executables',
38                 'Uninstall applicable executables without',
39                 'confirmation') do |value, options|
40      options[:executables] = value
41    end
42
43    add_option('-i', '--install-dir DIR',
44               'Directory to uninstall gem from') do |value, options|
45      options[:install_dir] = File.expand_path(value)
46    end
47
48    add_option('-n', '--bindir DIR',
49               'Directory to remove binaries from') do |value, options|
50      options[:bin_dir] = File.expand_path(value)
51    end
52
53    add_option('--[no-]user-install',
54               'Uninstall from user\'s home directory',
55               'in addition to GEM_HOME.') do |value, options|
56      options[:user_install] = value
57    end
58
59    add_option('--[no-]format-executable',
60               'Assume executable names match Ruby\'s prefix and suffix.') do |value, options|
61      options[:format_executable] = value
62    end
63
64    add_option('--[no-]force',
65               'Uninstall all versions of the named gems',
66               'ignoring dependencies') do |value, options|
67      options[:force] = value
68    end
69
70    add_version_option
71    add_platform_option
72  end
73
74  def arguments # :nodoc:
75    "GEMNAME       name of gem to uninstall"
76  end
77
78  def defaults_str # :nodoc:
79    "--version '#{Gem::Requirement.default}' --no-force " +
80    "--install-dir #{Gem.dir}\n" +
81    "--user-install"
82  end
83
84  def usage # :nodoc:
85    "#{program_name} GEMNAME [GEMNAME ...]"
86  end
87
88  def execute
89    # REFACTOR: stolen from cleanup_command
90    deplist = Gem::DependencyList.new
91    get_all_gem_names.uniq.each do |name|
92      Gem::Specification.find_all_by_name(name).each do |spec|
93        deplist.add spec
94      end
95    end
96
97    deps = deplist.strongly_connected_components.flatten.reverse
98
99    deps.map(&:name).uniq.each do |gem_name|
100      begin
101        Gem::Uninstaller.new(gem_name, options).uninstall
102      rescue Gem::GemNotInHomeException => e
103        spec = e.spec
104        alert("In order to remove #{spec.name}, please execute:\n" +
105              "\tgem uninstall #{spec.name} --install-dir=#{spec.installation_path}")
106      end
107    end
108  end
109
110end
111
112