| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | require 'formula' | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:47 -04:00
										 |  |  | require 'keg' | 
					
						
							| 
									
										
										
										
											2012-04-30 15:10:51 -05:00
										 |  |  | require 'bottles' | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew extend self | 
					
						
							| 
									
										
										
										
											2012-03-06 20:12:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |   def cleanup | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:39 -05:00
										 |  |  |     return unless HOMEBREW_CELLAR.directory? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     if ARGV.named.empty? | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:39 -05:00
										 |  |  |       cleanup_cellar | 
					
						
							|  |  |  |       cleanup_cache | 
					
						
							| 
									
										
										
										
											2013-06-21 15:42:14 -05:00
										 |  |  |       unless ARGV.dry_run? | 
					
						
							|  |  |  |         cleanup_lockfiles | 
					
						
							|  |  |  |         rm_DS_Store | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:35 -05:00
										 |  |  |       ARGV.formulae.each { |f| cleanup_formula(f) } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:39 -05:00
										 |  |  |   def cleanup_cellar | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |     HOMEBREW_CELLAR.subdirs.each do |rack| | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |       begin | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |         cleanup_formula Formula.factory(rack.basename.to_s) | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |       rescue FormulaUnavailableError | 
					
						
							|  |  |  |         # Don't complain about directories from DIY installs | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cleanup_formula f | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |     if f.installed? | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:38 -05:00
										 |  |  |       eligible_kegs = f.rack.subdirs.map { |d| Keg.new(d) }.select { |k| f.version > k.version } | 
					
						
							|  |  |  |       eligible_kegs.each do |keg| | 
					
						
							|  |  |  |         if f.can_cleanup? | 
					
						
							|  |  |  |           cleanup_keg(keg) | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           opoo "Skipping (old) keg-only: #{keg}" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |     elsif f.rack.subdirs.length > 1
 | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |       # If the cellar only has one version installed, don't complain | 
					
						
							|  |  |  |       # that we can't tell which one to keep. | 
					
						
							| 
									
										
										
										
											2011-03-11 13:36:26 -08:00
										 |  |  |       opoo "Skipping #{f.name}: most recent version #{f.version} not installed" | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:38 -05:00
										 |  |  |   def cleanup_keg keg | 
					
						
							|  |  |  |     if keg.linked? | 
					
						
							|  |  |  |       opoo "Skipping (old) #{keg} due to it being linked" | 
					
						
							|  |  |  |     elsif ARGV.dry_run? | 
					
						
							|  |  |  |       puts "Would remove: #{keg}" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       puts "Removing: #{keg}..." | 
					
						
							|  |  |  |       keg.rmtree | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |   def cleanup_cache | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:38 -05:00
										 |  |  |     HOMEBREW_CACHE.children.select(&:file?).each do |file| | 
					
						
							| 
									
										
										
										
											2013-06-06 12:34:47 -05:00
										 |  |  |       next unless (version = file.version) | 
					
						
							|  |  |  |       next unless (name = file.basename.to_s[/(.*)-(?:#{Regexp.escape(version)})/, 1]) | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:39 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       begin | 
					
						
							|  |  |  |         f = Formula.factory(name) | 
					
						
							|  |  |  |       rescue FormulaUnavailableError | 
					
						
							|  |  |  |         next | 
					
						
							| 
									
										
										
										
											2012-03-06 20:12:42 +00:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:39 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if f.version > version || ARGV.switch?('s') && !f.installed? || bottle_file_outdated?(f, file) | 
					
						
							|  |  |  |         cleanup_cached_file(file) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cleanup_cached_file file | 
					
						
							|  |  |  |     if ARGV.dry_run? | 
					
						
							|  |  |  |       puts "Would remove: #{file}" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       puts "Removing: #{file}..." | 
					
						
							|  |  |  |       file.unlink | 
					
						
							| 
									
										
										
										
											2012-03-06 20:12:42 +00:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-21 15:42:14 -05:00
										 |  |  |   def cleanup_lockfiles | 
					
						
							| 
									
										
										
										
											2013-06-21 18:37:52 -05:00
										 |  |  |     return unless HOMEBREW_CACHE_FORMULA.directory? | 
					
						
							| 
									
										
										
										
											2013-06-21 15:42:14 -05:00
										 |  |  |     candidates = HOMEBREW_CACHE_FORMULA.children | 
					
						
							|  |  |  |     lockfiles  = candidates.select { |f| f.file? && f.extname == '.brewing' } | 
					
						
							|  |  |  |     lockfiles.select(&:readable?).each do |file| | 
					
						
							|  |  |  |       file.open.flock(File::LOCK_EX | File::LOCK_NB) and file.unlink | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-10 16:06:24 -04:00
										 |  |  |   def rm_DS_Store | 
					
						
							| 
									
										
										
										
											2013-01-26 14:11:03 +00:00
										 |  |  |     system "find #{HOMEBREW_PREFIX} -name .DS_Store -delete 2>/dev/null" | 
					
						
							| 
									
										
										
										
											2012-08-10 16:06:24 -04:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-11 20:22:54 +01:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Formula | 
					
						
							|  |  |  |   def can_cleanup? | 
					
						
							|  |  |  |     # It used to be the case that keg-only kegs could not be cleaned up, because | 
					
						
							|  |  |  |     # older brews were built against the full path to the keg-only keg. Then we | 
					
						
							|  |  |  |     # introduced the opt symlink, and built against that instead. So provided | 
					
						
							|  |  |  |     # no brew exists that was built against an old-style keg-only keg, we can | 
					
						
							|  |  |  |     # remove it. | 
					
						
							| 
									
										
										
										
											2012-09-11 14:22:56 -05:00
										 |  |  |     if not keg_only? or ARGV.force? | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:47 -04:00
										 |  |  |       true | 
					
						
							|  |  |  |     elsif opt_prefix.directory? | 
					
						
							|  |  |  |       # SHA records were added to INSTALL_RECEIPTS the same day as opt symlinks | 
					
						
							|  |  |  |       !Formula.installed. | 
					
						
							| 
									
										
										
										
											2012-12-19 12:00:05 -06:00
										 |  |  |         select{ |ff| ff.deps.map{ |d| d.to_s }.include? name }. | 
					
						
							| 
									
										
										
										
											2013-05-15 12:45:36 -05:00
										 |  |  |         map{ |ff| ff.rack.subdirs rescue [] }. | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:47 -04:00
										 |  |  |         flatten. | 
					
						
							| 
									
										
										
										
											2012-09-20 16:47:00 -05:00
										 |  |  |         map{ |keg_path| Tab.for_keg(keg_path).send("HEAD") }. | 
					
						
							| 
									
										
										
										
											2012-08-10 16:33:47 -04:00
										 |  |  |         include? nil | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |