| 
									
										
										
										
											2016-04-25 17:57:51 +01:00
										 |  |  | require "utils/bottles" | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  | require "formula" | 
					
						
							| 
									
										
										
										
											2018-09-03 19:39:07 +01:00
										 |  |  | require "cask/cask_loader" | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  | require "set" | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  | module CleanupRefinement | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |   LATEST_CASK_DAYS = 7
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 01:55:43 +02:00
										 |  |  |   refine Enumerator do | 
					
						
							|  |  |  |     def parallel | 
					
						
							|  |  |  |       queue = Queue.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       each do |element| | 
					
						
							|  |  |  |         queue.enq(element) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       workers = (0...Hardware::CPU.cores).map do | 
					
						
							|  |  |  |         Thread.new do | 
					
						
							|  |  |  |           Kernel.loop do | 
					
						
							|  |  |  |             begin | 
					
						
							|  |  |  |               yield queue.deq(true) | 
					
						
							|  |  |  |             rescue ThreadError | 
					
						
							|  |  |  |               break # if queue is empty | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       workers.each(&:join) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |   refine Pathname do | 
					
						
							|  |  |  |     def incomplete? | 
					
						
							|  |  |  |       extname.end_with?(".incomplete") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def nested_cache? | 
					
						
							| 
									
										
										
										
											2018-09-03 18:59:53 +10:00
										 |  |  |       directory? && %w[cargo_cache go_cache glide_home java_cache npm_cache gclient_cache].include?(basename.to_s) | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 05:19:20 +01:00
										 |  |  |     def go_cache_directory? | 
					
						
							|  |  |  |       # Go makes its cache contents read-only to ensure cache integrity, | 
					
						
							|  |  |  |       # which makes sense but is something we need to undo for cleanup. | 
					
						
							|  |  |  |       directory? && %w[go_cache].include?(basename.to_s) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |     def prune?(days) | 
					
						
							|  |  |  |       return false unless days | 
					
						
							|  |  |  |       return true if days.zero? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-01 06:42:47 +02:00
										 |  |  |       return true if symlink? && !exist? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |       # TODO: Replace with ActiveSupport's `.days.ago`. | 
					
						
							|  |  |  |       mtime < ((@time ||= Time.now) - days * 60 * 60 * 24) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stale?(scrub = false) | 
					
						
							| 
									
										
										
										
											2018-08-29 01:34:40 +02:00
										 |  |  |       return false unless resolved_path.file? | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |       stale_formula?(scrub) || stale_cask?(scrub) | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stale_formula?(scrub) | 
					
						
							|  |  |  |       return false unless HOMEBREW_CELLAR.directory? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       version = if to_s.match?(Pathname::BOTTLE_EXTNAME_RX) | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |           Utils::Bottles.resolve_version(self) | 
					
						
							|  |  |  |         rescue | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |           nil | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 05:08:50 +02:00
										 |  |  |       version ||= basename.to_s[/\A.*(?:\-\-.*?)*\-\-(.*?)#{Regexp.escape(extname)}\Z/, 1] | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       version ||= basename.to_s[/\A.*\-\-?(.*?)#{Regexp.escape(extname)}\Z/, 1] | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |       return false unless version | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       version = Version.new(version) | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 05:08:50 +02:00
										 |  |  |       return false unless formula_name = basename.to_s[/\A(.*?)(?:\-\-.*?)*\-\-?(?:#{Regexp.escape(version)})/, 1] | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       formula = begin | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |         Formulary.from_rack(HOMEBREW_CELLAR/formula_name) | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |       rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError | 
					
						
							|  |  |  |         return false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       resource_name = basename.to_s[/\A.*?\-\-(.*?)\-\-?(?:#{Regexp.escape(version)})/, 1] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 05:08:50 +02:00
										 |  |  |       if resource_name == "patch" | 
					
						
							| 
									
										
										
										
											2018-08-12 19:54:08 +02:00
										 |  |  |         patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version) | 
					
						
							| 
									
										
										
										
											2018-08-10 05:08:50 +02:00
										 |  |  |         return true unless patch_hashes&.include?(Checksum.new(:sha256, version.to_s)) | 
					
						
							|  |  |  |       elsif resource_name && resource_version = formula.stable&.resources&.dig(resource_name)&.version | 
					
						
							|  |  |  |         return true if resource_version != version | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       elsif version.is_a?(PkgVersion) | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |         return true if formula.pkg_version > version | 
					
						
							|  |  |  |       elsif formula.version > version | 
					
						
							|  |  |  |         return true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true if scrub && !formula.installed? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true if Utils::Bottles.file_outdated?(formula, self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def stale_cask?(scrub) | 
					
						
							|  |  |  |       return false unless name = basename.to_s[/\A(.*?)\-\-/, 1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cask = begin | 
					
						
							| 
									
										
										
										
											2018-09-06 08:29:14 +02:00
										 |  |  |         Cask::CaskLoader.load(name) | 
					
						
							|  |  |  |       rescue Cask::CaskUnavailableError | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |         return false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       unless basename.to_s.match?(/\A#{Regexp.escape(name)}\-\-#{Regexp.escape(cask.version)}\b/) | 
					
						
							|  |  |  |         return true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return true if scrub && !cask.versions.include?(cask.version) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if cask.version.latest? | 
					
						
							|  |  |  |         # TODO: Replace with ActiveSupport's `.days.ago`. | 
					
						
							|  |  |  |         return mtime < ((@time ||= Time.now) - LATEST_CASK_DAYS * 60 * 60 * 24) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using CleanupRefinement | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |   class Cleanup | 
					
						
							|  |  |  |     extend Predicable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attr_predicate :dry_run?, :scrub? | 
					
						
							|  |  |  |     attr_reader :args, :days, :cache | 
					
						
							|  |  |  |     attr_reader :disk_cleanup_size | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def initialize(*args, dry_run: false, scrub: false, days: nil, cache: HOMEBREW_CACHE) | 
					
						
							|  |  |  |       @disk_cleanup_size = 0
 | 
					
						
							|  |  |  |       @args = args | 
					
						
							|  |  |  |       @dry_run = dry_run | 
					
						
							|  |  |  |       @scrub = scrub | 
					
						
							|  |  |  |       @days = days | 
					
						
							|  |  |  |       @cache = cache | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       @cleaned_up_paths = Set.new | 
					
						
							| 
									
										
										
										
											2017-08-13 04:21:07 +05:30
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |     def clean! | 
					
						
							|  |  |  |       if args.empty? | 
					
						
							| 
									
										
										
										
											2018-08-11 17:23:46 +02:00
										 |  |  |         cleanup_lockfiles | 
					
						
							|  |  |  |         Formula.installed.sort_by(&:name).each do |formula| | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |           cleanup_formula(formula) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         cleanup_cache | 
					
						
							|  |  |  |         cleanup_logs | 
					
						
							| 
									
										
										
										
											2018-08-11 17:23:35 +02:00
										 |  |  |         return if dry_run? | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |         rm_ds_store | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         args.each do |arg| | 
					
						
							|  |  |  |           formula = begin | 
					
						
							|  |  |  |             Formula[arg] | 
					
						
							|  |  |  |           rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError | 
					
						
							|  |  |  |             nil | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           cask = begin | 
					
						
							| 
									
										
										
										
											2018-09-06 08:29:14 +02:00
										 |  |  |             Cask::CaskLoader.load(arg) | 
					
						
							|  |  |  |           rescue Cask::CaskUnavailableError | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |             nil | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2017-03-21 04:13:13 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |           cleanup_formula(formula) if formula | 
					
						
							|  |  |  |           cleanup_cask(cask) if cask | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 04:13:13 -05:00
										 |  |  |     def unremovable_kegs | 
					
						
							|  |  |  |       @unremovable_kegs ||= [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def cleanup_formula(formula) | 
					
						
							|  |  |  |       formula.eligible_kegs_for_cleanup.each(&method(:cleanup_keg)) | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |       cleanup_cache(Pathname.glob(cache/"#{formula.name}--*")) | 
					
						
							| 
									
										
										
										
											2018-08-09 01:55:43 +02:00
										 |  |  |       rm_ds_store([formula.rack]) | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  |       cleanup_lockfiles(FormulaLock.new(formula.name).path) | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |     def cleanup_cask(cask) | 
					
						
							|  |  |  |       cleanup_cache(Pathname.glob(cache/"Cask/#{cask.token}--*")) | 
					
						
							| 
									
										
										
										
											2018-08-09 01:55:43 +02:00
										 |  |  |       rm_ds_store([cask.caskroom_path]) | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  |       cleanup_lockfiles(CaskLock.new(cask.token).path) | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 04:13:13 -05:00
										 |  |  |     def cleanup_keg(keg) | 
					
						
							|  |  |  |       cleanup_path(keg) { keg.uninstall } | 
					
						
							|  |  |  |     rescue Errno::EACCES => e | 
					
						
							|  |  |  |       opoo e.message | 
					
						
							|  |  |  |       unremovable_kegs << keg | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |     DEFAULT_LOG_DAYS = 14
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 04:13:13 -05:00
										 |  |  |     def cleanup_logs | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       return unless HOMEBREW_LOGS.directory? | 
					
						
							|  |  |  |       HOMEBREW_LOGS.subdirs.each do |dir| | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |         cleanup_path(dir) { dir.rmtree } if dir.prune?(days || DEFAULT_LOG_DAYS) | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 04:11:54 +02:00
										 |  |  |     def cleanup_unreferenced_downloads | 
					
						
							|  |  |  |       return if dry_run? | 
					
						
							|  |  |  |       return unless (cache/"downloads").directory? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-27 17:45:01 +02:00
										 |  |  |       # We can't use `.reject(&:incomplete?) here due to the refinement scope. | 
					
						
							| 
									
										
										
										
											2018-08-10 04:11:54 +02:00
										 |  |  |       downloads = (cache/"downloads").children.reject { |path| path.incomplete? } # rubocop:disable Style/SymbolProc | 
					
						
							|  |  |  |       referenced_downloads = [cache, cache/"Cask"].select(&:directory?) | 
					
						
							|  |  |  |                                                   .flat_map(&:children) | 
					
						
							|  |  |  |                                                   .select(&:symlink?) | 
					
						
							|  |  |  |                                                   .map(&:resolved_path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (downloads - referenced_downloads).each(&:unlink) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |     def cleanup_cache(entries = nil) | 
					
						
							|  |  |  |       entries ||= [cache, cache/"Cask"].select(&:directory?).flat_map(&:children) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       entries.each do |path| | 
					
						
							| 
									
										
										
										
											2018-08-30 05:19:20 +01:00
										 |  |  |         FileUtils.chmod_R 0755, path if path.go_cache_directory? && !dry_run? | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |         next cleanup_path(path) { path.unlink } if path.incomplete? | 
					
						
							|  |  |  |         next cleanup_path(path) { FileUtils.rm_rf path } if path.nested_cache? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |         if path.prune?(days) | 
					
						
							| 
									
										
										
										
											2018-08-25 22:06:24 +02:00
										 |  |  |           if path.file? || path.symlink? | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |             cleanup_path(path) { path.unlink } | 
					
						
							|  |  |  |           elsif path.directory? && path.to_s.include?("--") | 
					
						
							|  |  |  |             cleanup_path(path) { FileUtils.rm_rf path } | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |           next | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |         next cleanup_path(path) { path.unlink } if path.stale?(scrub?) | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-08-10 04:11:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       cleanup_unreferenced_downloads | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 04:13:13 -05:00
										 |  |  |     def cleanup_path(path) | 
					
						
							| 
									
										
										
										
											2018-08-10 00:54:03 +02:00
										 |  |  |       return unless @cleaned_up_paths.add?(path) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 09:43:38 +02:00
										 |  |  |       disk_usage = path.disk_usage | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 11:20:53 +02:00
										 |  |  |       if dry_run? | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |         puts "Would remove: #{path} (#{path.abv})" | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         puts "Removing: #{path}... (#{path.abv})" | 
					
						
							|  |  |  |         yield | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 22:23:55 +02:00
										 |  |  |       @disk_cleanup_size += disk_usage | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  |     def cleanup_lockfiles(*lockfiles) | 
					
						
							| 
									
										
										
										
											2018-08-16 05:55:17 +02:00
										 |  |  |       return if dry_run? | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 05:55:17 +02:00
										 |  |  |       if lockfiles.empty? && HOMEBREW_LOCK_DIR.directory? | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  |         lockfiles = HOMEBREW_LOCK_DIR.children.select(&:file?) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       lockfiles.each do |file| | 
					
						
							|  |  |  |         next unless file.readable? | 
					
						
							| 
									
										
										
										
											2018-08-09 16:46:39 +02:00
										 |  |  |         next unless file.open(File::RDWR).flock(File::LOCK_EX | File::LOCK_NB) | 
					
						
							| 
									
										
										
										
											2018-08-11 17:23:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         begin | 
					
						
							| 
									
										
										
										
											2018-08-16 05:55:17 +02:00
										 |  |  |           file.unlink | 
					
						
							| 
									
										
										
										
											2018-08-11 17:23:35 +02:00
										 |  |  |         ensure | 
					
						
							|  |  |  |           file.open(File::RDWR).flock(File::LOCK_UN) if file.exist? | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 01:55:43 +02:00
										 |  |  |     def rm_ds_store(dirs = nil) | 
					
						
							|  |  |  |       dirs ||= %w[Caskroom Cellar Frameworks Library bin etc include lib opt sbin share var] | 
					
						
							|  |  |  |                .map { |path| HOMEBREW_PREFIX/path } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       dirs.select(&:directory?).each.parallel do |dir| | 
					
						
							|  |  |  |         system_command "find", args: [dir, "-name", ".DS_Store", "-delete"], print_stderr: false | 
					
						
							| 
									
										
										
										
											2015-12-29 12:57:48 +01:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |