Refactor and document Cleanup.

This commit is contained in:
Markus Reiter 2020-08-17 03:52:17 +02:00
parent 7d78949479
commit 5402500635
2 changed files with 111 additions and 106 deletions

View File

@ -6,126 +6,131 @@ require "formula"
require "cask/cask_loader" require "cask/cask_loader"
require "set" require "set"
CLEANUP_DEFAULT_DAYS = 30 module Homebrew
# Helper class for cleaning up the Homebrew cache.
#
# @api private
class Cleanup
CLEANUP_DEFAULT_DAYS = 30
private_constant :CLEANUP_DEFAULT_DAYS
module CleanupRefinement # `Pathname` refinement with helper functions for cleaning up files.
refine Pathname do module CleanupRefinement
def incomplete? refine Pathname do
extname.end_with?(".incomplete") def incomplete?
end extname.end_with?(".incomplete")
end
def nested_cache? def nested_cache?
directory? && %w[ directory? && %w[
cargo_cache cargo_cache
go_cache go_cache
go_mod_cache go_mod_cache
glide_home glide_home
java_cache java_cache
npm_cache npm_cache
gclient_cache gclient_cache
].include?(basename.to_s) ].include?(basename.to_s)
end end
def go_cache_directory? def go_cache_directory?
# Go makes its cache contents read-only to ensure cache integrity, # Go makes its cache contents read-only to ensure cache integrity,
# which makes sense but is something we need to undo for cleanup. # which makes sense but is something we need to undo for cleanup.
directory? && %w[go_cache go_mod_cache].include?(basename.to_s) directory? && %w[go_cache go_mod_cache].include?(basename.to_s)
end end
def prune?(days) def prune?(days)
return false unless days return false unless days
return true if days.zero? return true if days.zero?
return true if symlink? && !exist? return true if symlink? && !exist?
mtime < days.days.ago && ctime < days.days.ago mtime < days.days.ago && ctime < days.days.ago
end end
def stale?(scrub = false) def stale?(scrub = false)
return false unless resolved_path.file? return false unless resolved_path.file?
if dirname.basename.to_s == "Cask" if dirname.basename.to_s == "Cask"
stale_cask?(scrub) stale_cask?(scrub)
else else
stale_formula?(scrub) stale_formula?(scrub)
end end
end end
private private
def stale_formula?(scrub) def stale_formula?(scrub)
return false unless HOMEBREW_CELLAR.directory? return false unless HOMEBREW_CELLAR.directory?
version = if to_s.match?(Pathname::BOTTLE_EXTNAME_RX) version = if to_s.match?(Pathname::BOTTLE_EXTNAME_RX)
begin begin
Utils::Bottles.resolve_version(self) Utils::Bottles.resolve_version(self)
rescue rescue
nil nil
end
end
version ||= basename.to_s[/\A.*(?:--.*?)*--(.*?)#{Regexp.escape(extname)}\Z/, 1]
version ||= basename.to_s[/\A.*--?(.*?)#{Regexp.escape(extname)}\Z/, 1]
return false unless version
version = Version.new(version)
return false unless formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1]
formula = begin
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
return false
end
resource_name = basename.to_s[/\A.*?--(.*?)--?(?:#{Regexp.escape(version)})/, 1]
if resource_name == "patch"
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
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
elsif version.is_a?(PkgVersion)
return true if formula.pkg_version > version
elsif formula.version > version
return true
end
return true if scrub && !formula.latest_version_installed?
return true if Utils::Bottles.file_outdated?(formula, self)
false
end
def stale_cask?(scrub)
return false unless name = basename.to_s[/\A(.*?)--/, 1]
cask = begin
Cask::CaskLoader.load(name)
rescue Cask::CaskError
return false
end
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
return true if scrub && !cask.versions.include?(cask.version)
if cask.version.latest?
return mtime < CLEANUP_DEFAULT_DAYS.days.ago &&
ctime < CLEANUP_DEFAULT_DAYS.days.ago
end
false
end end
end end
version ||= basename.to_s[/\A.*(?:--.*?)*--(.*?)#{Regexp.escape(extname)}\Z/, 1]
version ||= basename.to_s[/\A.*--?(.*?)#{Regexp.escape(extname)}\Z/, 1]
return false unless version
version = Version.new(version)
return false unless formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1]
formula = begin
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
return false
end
resource_name = basename.to_s[/\A.*?--(.*?)--?(?:#{Regexp.escape(version)})/, 1]
if resource_name == "patch"
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
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
elsif version.is_a?(PkgVersion)
return true if formula.pkg_version > version
elsif formula.version > version
return true
end
return true if scrub && !formula.latest_version_installed?
return true if Utils::Bottles.file_outdated?(formula, self)
false
end end
def stale_cask?(scrub) using CleanupRefinement
return false unless name = basename.to_s[/\A(.*?)--/, 1]
cask = begin
Cask::CaskLoader.load(name)
rescue Cask::CaskError
return false
end
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
return true if scrub && !cask.versions.include?(cask.version)
if cask.version.latest?
return mtime < CLEANUP_DEFAULT_DAYS.days.ago &&
ctime < CLEANUP_DEFAULT_DAYS.days.ago
end
false
end
end
end
using CleanupRefinement
module Homebrew
class Cleanup
extend Predicable extend Predicable
PERIODIC_CLEAN_FILE = (HOMEBREW_CACHE/".cleaned").freeze PERIODIC_CLEAN_FILE = (HOMEBREW_CACHE/".cleaned").freeze

View File

@ -5,9 +5,9 @@ require "cleanup"
require "cask/cache" require "cask/cache"
require "fileutils" require "fileutils"
using CleanupRefinement using Homebrew::Cleanup::CleanupRefinement
describe CleanupRefinement do describe Homebrew::Cleanup::CleanupRefinement do
describe "::prune?" do describe "::prune?" do
alias_matcher :be_pruned, :be_prune alias_matcher :be_pruned, :be_prune