diff --git a/Library/Homebrew/cleanup.rb b/Library/Homebrew/cleanup.rb index 53f3ee3a2cb729c49ae108dcc665340bba737cfd..432efa2a382f060867c9544b5388c96bee4b1cfc 100644 --- a/Library/Homebrew/cleanup.rb +++ b/Library/Homebrew/cleanup.rb @@ -152,13 +152,13 @@ module Homebrew def clean! if args.empty? - cleanup_lockfiles Formula.installed.sort_by(&:name).each do |formula| cleanup_formula(formula) end cleanup_cache cleanup_logs cleanup_portable_ruby + cleanup_lockfiles return if dry_run? cleanup_old_cache_db @@ -221,14 +221,27 @@ module Homebrew return if dry_run? return unless (cache/"downloads").directory? - # We can't use `.reject(&:incomplete?) here due to the refinement scope. - downloads = (cache/"downloads").children.reject { |path| path.incomplete? } # rubocop:disable Style/SymbolProc + downloads = (cache/"downloads").children + referenced_downloads = [cache, cache/"Cask"].select(&:directory?) .flat_map(&:children) .select(&:symlink?) .map(&:resolved_path) - (downloads - referenced_downloads).each(&:unlink) + (downloads - referenced_downloads).each do |download| + if download.incomplete? + begin + LockFile.new(download.basename).with_lock do + download.unlink + end + rescue OperationInProgressError + # Skip incomplete downloads which are still in progress. + next + end + else + download.unlink + end + end end def cleanup_cache(entries = nil) diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index 89a79c6e0b193dfcd3df1e3c1c3ba40784e18819..2c8cff34c5b6f414ab22235f113353863f23d616 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -277,6 +277,9 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy end def fetch + download_lock = LockFile.new(temporary_path.basename) + download_lock.lock + urls = [url, *mirrors] begin @@ -308,6 +311,8 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy puts "Trying a mirror..." retry end + ensure + download_lock.unlock end def clear_cache