| 
									
										
										
										
											2016-10-25 23:59:55 +01:00
										 |  |  | #:  * `uninstall`, `rm`, `remove` [`--force`] [`--ignore-dependencies`] <formula>: | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #:    Uninstall <formula>. | 
					
						
							|  |  |  | #: | 
					
						
							| 
									
										
										
										
											2017-04-02 10:14:21 +01:00
										 |  |  | #:    If `--force` (or `-f`) is passed, and there are multiple versions of <formula> | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | #:    installed, delete all installed versions. | 
					
						
							| 
									
										
										
										
											2016-10-25 23:59:55 +01:00
										 |  |  | #: | 
					
						
							|  |  |  | #:    If `--ignore-dependencies` is passed, uninstalling won't fail, even if | 
					
						
							|  |  |  | #:    formulae depending on <formula> would still be installed. | 
					
						
							| 
									
										
										
										
											2016-04-08 16:28:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  | require "keg" | 
					
						
							|  |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2016-09-30 19:34:14 +01:00
										 |  |  | require "diagnostic" | 
					
						
							| 
									
										
										
										
											2015-08-09 14:57:15 +03:00
										 |  |  | require "migrator" | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  | require "cli_parser" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-18 22:41:47 -05:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2016-09-26 01:44:51 +02:00
										 |  |  |   module_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  |   def uninstall_args | 
					
						
							|  |  |  |     Homebrew::CLI::Parser.new do | 
					
						
							|  |  |  |       usage_banner <<~EOS | 
					
						
							|  |  |  |         `uninstall`, `rm`, `remove` [<options>] <formula> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Uninstall <formula>. | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |       switch :force, | 
					
						
							|  |  |  |         description: "Delete all installed versions of the <formula>" | 
					
						
							|  |  |  |       switch "--ignore-dependencies", | 
					
						
							|  |  |  |         description: "Dont fail uninstall, even if <formula> is a dependency of any installed "\ | 
					
						
							|  |  |  |                      "formulae." | 
					
						
							|  |  |  |       switch :debug | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   def uninstall | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  |     uninstall_args.parse | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     raise KegUnspecifiedError if args.remaining.empty? | 
					
						
							| 
									
										
										
										
											2012-02-04 00:01:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  |     kegs_by_rack = if args.force? | 
					
						
							| 
									
										
										
										
											2016-10-25 23:48:34 +01:00
										 |  |  |       Hash[ARGV.named.map do |name| | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |         rack = Formulary.to_rack(name) | 
					
						
							| 
									
										
										
										
											2016-11-11 13:15:46 +00:00
										 |  |  |         next unless rack.directory? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |         [rack, rack.subdirs.map { |d| Keg.new(d) }] | 
					
						
							| 
									
										
										
										
											2016-10-25 23:48:34 +01:00
										 |  |  |       end] | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |       ARGV.kegs.group_by(&:rack) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |     handle_unsatisfied_dependents(kegs_by_rack) | 
					
						
							|  |  |  |     return if Homebrew.failed? | 
					
						
							| 
									
										
										
										
											2016-09-28 19:21:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |     kegs_by_rack.each do |rack, kegs| | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  |       if args.force? | 
					
						
							| 
									
										
										
										
											2015-08-09 14:57:15 +03:00
										 |  |  |         name = rack.basename | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-06 13:43:41 +00:00
										 |  |  |         if rack.directory? | 
					
						
							| 
									
										
										
										
											2015-04-09 15:18:25 +08:00
										 |  |  |           puts "Uninstalling #{name}... (#{rack.abv})" | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |           kegs.each do |keg| | 
					
						
							| 
									
										
										
										
											2014-06-23 22:00:33 -05:00
										 |  |  |             keg.unlink | 
					
						
							|  |  |  |             keg.uninstall | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-17 21:22:29 +08:00
										 |  |  |         rm_pin rack | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |       else | 
					
						
							|  |  |  |         kegs.each do |keg| | 
					
						
							| 
									
										
										
										
											2018-02-05 09:31:17 +00:00
										 |  |  |           begin | 
					
						
							|  |  |  |             f = Formulary.from_rack(rack) | 
					
						
							|  |  |  |             if f.pinned? | 
					
						
							|  |  |  |               onoe "#{f.full_name} is pinned. You must unpin it to uninstall." | 
					
						
							|  |  |  |               next | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           rescue | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |           keg.lock do | 
					
						
							|  |  |  |             puts "Uninstalling #{keg}... (#{keg.abv})" | 
					
						
							|  |  |  |             keg.unlink | 
					
						
							|  |  |  |             keg.uninstall | 
					
						
							|  |  |  |             rack = keg.rack | 
					
						
							|  |  |  |             rm_pin rack | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if rack.directory? | 
					
						
							|  |  |  |               versions = rack.subdirs.map(&:basename) | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |               puts "#{keg.name} #{versions.to_sentence} #{"is".pluralize(versions.count)} still installed." | 
					
						
							| 
									
										
										
										
											2016-09-28 19:14:33 +01:00
										 |  |  |               puts "Remove all versions with `brew uninstall --force #{keg.name}`." | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   rescue MultipleVersionsInstalledError => e | 
					
						
							| 
									
										
										
										
											2012-04-30 14:08:59 +10:00
										 |  |  |     ofail e | 
					
						
							| 
									
										
										
										
											2015-08-17 16:55:59 +02:00
										 |  |  |     puts "Use `brew uninstall --force #{e.name}` to remove all versions." | 
					
						
							| 
									
										
										
										
											2015-08-17 22:56:00 +08:00
										 |  |  |   ensure | 
					
						
							|  |  |  |     # If we delete Cellar/newname, then Cellar/oldname symlink | 
					
						
							|  |  |  |     # can become broken and we have to remove it. | 
					
						
							| 
									
										
										
										
											2015-10-17 03:57:40 +08:00
										 |  |  |     if HOMEBREW_CELLAR.directory? | 
					
						
							| 
									
										
										
										
											2015-10-17 03:59:28 +08:00
										 |  |  |       HOMEBREW_CELLAR.children.each do |rack| | 
					
						
							|  |  |  |         rack.unlink if rack.symlink? && !rack.resolved_path_exists? | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-10-17 03:57:40 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |   def handle_unsatisfied_dependents(kegs_by_rack) | 
					
						
							| 
									
										
										
										
											2018-11-11 17:43:31 +05:30
										 |  |  |     return if args.ignore_dependencies? | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     all_kegs = kegs_by_rack.values.flatten(1) | 
					
						
							|  |  |  |     check_for_dependents all_kegs | 
					
						
							| 
									
										
										
										
											2016-11-18 09:34:58 +00:00
										 |  |  |   rescue MethodDeprecatedError | 
					
						
							|  |  |  |     # Silently ignore deprecations when uninstalling. | 
					
						
							|  |  |  |     nil | 
					
						
							| 
									
										
										
										
											2016-10-25 23:53:10 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 20:55:24 +01:00
										 |  |  |   def check_for_dependents(kegs) | 
					
						
							| 
									
										
										
										
											2016-10-05 22:22:32 +01:00
										 |  |  |     return false unless result = Keg.find_some_installed_dependents(kegs) | 
					
						
							| 
									
										
										
										
											2016-09-30 19:34:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |     if ARGV.homebrew_developer? | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |       DeveloperDependentsMessage.new(*result).output | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |       NondeveloperDependentsMessage.new(*result).output | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-09-30 19:34:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |   class DependentsMessage | 
					
						
							| 
									
										
										
										
											2016-11-14 13:39:17 +00:00
										 |  |  |     attr_reader :reqs, :deps | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def initialize(requireds, dependents) | 
					
						
							| 
									
										
										
										
											2016-11-15 21:56:42 +00:00
										 |  |  |       @reqs = requireds | 
					
						
							|  |  |  |       @deps = dependents | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def sample_command | 
					
						
							| 
									
										
										
										
											2016-12-30 17:45:37 +00:00
										 |  |  |       "brew uninstall --ignore-dependencies #{ARGV.named.join(" ")}" | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-14 13:39:17 +00:00
										 |  |  |     def are_required_by_deps | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |       "#{"is".pluralize(reqs.count)} required by #{deps.to_sentence}, " \ | 
					
						
							|  |  |  |       "which #{"is".pluralize(deps.count)} currently installed" | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-11-11 20:08:26 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |   class DeveloperDependentsMessage < DependentsMessage | 
					
						
							|  |  |  |     def output | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       opoo <<~EOS | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |         #{reqs.to_sentence} #{are_required_by_deps}. | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |         You can silence this warning with: | 
					
						
							|  |  |  |           #{sample_command} | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class NondeveloperDependentsMessage < DependentsMessage | 
					
						
							|  |  |  |     def output | 
					
						
							| 
									
										
										
										
											2017-10-15 02:28:32 +02:00
										 |  |  |       ofail <<~EOS | 
					
						
							| 
									
										
										
										
											2018-09-17 20:11:11 +02:00
										 |  |  |         Refusing to uninstall #{reqs.to_sentence} | 
					
						
							|  |  |  |         because #{"it".pluralize(reqs.count)} #{are_required_by_deps}. | 
					
						
							| 
									
										
										
										
											2016-11-14 13:09:40 +00:00
										 |  |  |         You can override this and force removal with: | 
					
						
							|  |  |  |           #{sample_command} | 
					
						
							|  |  |  |       EOS | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-09-30 19:34:14 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def rm_pin(rack) | 
					
						
							| 
									
										
										
										
											2016-09-10 10:24:57 +01:00
										 |  |  |     Formulary.from_rack(rack).unpin | 
					
						
							|  |  |  |   rescue | 
					
						
							|  |  |  |     nil | 
					
						
							| 
									
										
										
										
											2013-03-31 21:28:20 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | end |