Enable typing in Homebrew::Cleanup
This commit is contained in:
parent
c271a9ae75
commit
eaeceda31e
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/bottles"
|
||||
@ -15,15 +15,18 @@ module Homebrew
|
||||
CLEANUP_DEFAULT_DAYS = Homebrew::EnvConfig.cleanup_periodic_full_days.to_i.freeze
|
||||
private_constant :CLEANUP_DEFAULT_DAYS
|
||||
|
||||
# {Pathname} refinement with helper functions for cleaning up files.
|
||||
module CleanupRefinement
|
||||
refine Pathname do
|
||||
def incomplete?
|
||||
extname.end_with?(".incomplete")
|
||||
module PathnameUtils
|
||||
class << self
|
||||
extend T::Sig
|
||||
|
||||
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||
def incomplete?(pathname)
|
||||
pathname.extname.end_with?(".incomplete")
|
||||
end
|
||||
|
||||
def nested_cache?
|
||||
directory? && %w[
|
||||
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||
def nested_cache?(pathname)
|
||||
pathname.directory? && %w[
|
||||
cargo_cache
|
||||
go_cache
|
||||
go_mod_cache
|
||||
@ -31,56 +34,62 @@ module Homebrew
|
||||
java_cache
|
||||
npm_cache
|
||||
gclient_cache
|
||||
].include?(basename.to_s)
|
||||
].include?(pathname.basename.to_s)
|
||||
end
|
||||
|
||||
def go_cache_directory?
|
||||
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||
def go_cache_directory?(pathname)
|
||||
# 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 go_mod_cache].include?(basename.to_s)
|
||||
pathname.directory? && %w[go_cache go_mod_cache].include?(pathname.basename.to_s)
|
||||
end
|
||||
|
||||
def prune?(days)
|
||||
sig { params(pathname: Pathname, days: T.nilable(Integer)).returns(T::Boolean) }
|
||||
def prune?(pathname, days)
|
||||
return false unless days
|
||||
return true if days.zero?
|
||||
|
||||
return true if symlink? && !exist?
|
||||
return true if pathname.symlink? && !pathname.exist?
|
||||
|
||||
days_ago = (DateTime.now - days).to_time
|
||||
mtime < days_ago && ctime < days_ago
|
||||
pathname.mtime < days_ago && pathname.ctime < days_ago
|
||||
end
|
||||
|
||||
def stale?(scrub: false)
|
||||
return false unless resolved_path.file?
|
||||
sig { params(pathname: Pathname, scrub: T::Boolean).returns(T::Boolean) }
|
||||
def stale?(pathname, scrub: false)
|
||||
return false unless pathname.resolved_path.file?
|
||||
|
||||
if dirname.basename.to_s == "Cask"
|
||||
stale_cask?(scrub)
|
||||
if pathname.dirname.basename.to_s == "Cask"
|
||||
stale_cask?(pathname, scrub)
|
||||
else
|
||||
stale_formula?(scrub)
|
||||
stale_formula?(pathname, scrub)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stale_formula?(scrub)
|
||||
sig { params(pathname: Pathname, scrub: T::Boolean).returns(T::Boolean) }
|
||||
def stale_formula?(pathname, scrub)
|
||||
return false unless HOMEBREW_CELLAR.directory?
|
||||
|
||||
version = if HOMEBREW_BOTTLES_EXTNAME_REGEX.match?(to_s)
|
||||
begin
|
||||
Utils::Bottles.resolve_version(self)
|
||||
Utils::Bottles.resolve_version(pathname)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
end
|
||||
basename_str = pathname.basename.to_s
|
||||
|
||||
version ||= basename.to_s[/\A.*(?:--.*?)*--(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
||||
version ||= basename.to_s[/\A.*--?(.*?)#{Regexp.escape(extname)}\Z/, 1]
|
||||
version ||= basename_str[/\A.*(?:--.*?)*--(.*?)#{Regexp.escape(pathname.extname)}\Z/, 1]
|
||||
version ||= basename_str[/\A.*--?(.*?)#{Regexp.escape(pathname.extname)}\Z/, 1]
|
||||
|
||||
return false unless version
|
||||
|
||||
version = Version.new(version)
|
||||
|
||||
return false unless (formula_name = basename.to_s[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version)})/, 1])
|
||||
unless (formula_name = basename_str[/\A(.*?)(?:--.*?)*--?(?:#{Regexp.escape(version.to_s)})/, 1])
|
||||
return false
|
||||
end
|
||||
|
||||
formula = begin
|
||||
Formulary.from_rack(HOMEBREW_CELLAR/formula_name)
|
||||
@ -90,27 +99,26 @@ module Homebrew
|
||||
|
||||
return false if formula.blank?
|
||||
|
||||
resource_name = basename.to_s[/\A.*?--(.*?)--?(?:#{Regexp.escape(version)})/, 1]
|
||||
resource_name = basename_str[/\A.*?--(.*?)--?(?:#{Regexp.escape(version.to_s)})/, 1]
|
||||
|
||||
if resource_name == "patch"
|
||||
patch_hashes = formula.stable&.patches&.select(&:external?)&.map(&:resource)&.map(&:version)
|
||||
return true unless patch_hashes&.include?(Checksum.new(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)
|
||||
return true if Utils::Bottles.file_outdated?(formula, pathname)
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def stale_cask?(scrub)
|
||||
sig { params(pathname: Pathname, scrub: T::Boolean).returns(T::Boolean) }
|
||||
def stale_cask?(pathname, scrub)
|
||||
basename = pathname.basename
|
||||
return false unless (name = basename.to_s[/\A(.*?)--/, 1])
|
||||
|
||||
cask = begin
|
||||
@ -120,14 +128,12 @@ module Homebrew
|
||||
end
|
||||
|
||||
return false if cask.blank?
|
||||
|
||||
return true unless basename.to_s.match?(/\A#{Regexp.escape(name)}--#{Regexp.escape(cask.version)}\b/)
|
||||
|
||||
return true if scrub && cask.versions.exclude?(cask.version)
|
||||
|
||||
if cask.version.latest?
|
||||
cleanup_threshold = (DateTime.now - CLEANUP_DEFAULT_DAYS).to_time
|
||||
return mtime < cleanup_threshold && ctime < cleanup_threshold
|
||||
return pathname.mtime < cleanup_threshold && pathname.ctime < cleanup_threshold
|
||||
end
|
||||
|
||||
false
|
||||
@ -135,8 +141,6 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
using CleanupRefinement
|
||||
|
||||
extend Predicable
|
||||
|
||||
PERIODIC_CLEAN_FILE = (HOMEBREW_CACHE/".cleaned").freeze
|
||||
@ -190,7 +194,7 @@ module Homebrew
|
||||
def self.skip_clean_formula?(formula)
|
||||
return false if Homebrew::EnvConfig.no_cleanup_formulae.blank?
|
||||
|
||||
@skip_clean_formulae ||= Homebrew::EnvConfig.no_cleanup_formulae.split(",")
|
||||
@skip_clean_formulae ||= T.must(Homebrew::EnvConfig.no_cleanup_formulae).split(",")
|
||||
@skip_clean_formulae.include?(formula.name) || (@skip_clean_formulae & formula.aliases).present?
|
||||
end
|
||||
|
||||
@ -311,7 +315,7 @@ module Homebrew
|
||||
logs_days = [days, CLEANUP_DEFAULT_DAYS].min
|
||||
|
||||
HOMEBREW_LOGS.subdirs.each do |dir|
|
||||
cleanup_path(dir) { dir.rmtree } if dir.prune?(logs_days)
|
||||
cleanup_path(dir) { dir.rmtree } if PathnameUtils.prune?(dir, logs_days)
|
||||
end
|
||||
end
|
||||
|
||||
@ -327,7 +331,7 @@ module Homebrew
|
||||
.map(&:resolved_path)
|
||||
|
||||
(downloads - referenced_downloads).each do |download|
|
||||
if download.incomplete?
|
||||
if PathnameUtils.incomplete?(download)
|
||||
begin
|
||||
LockFile.new(download.basename).with_lock do
|
||||
download.unlink
|
||||
@ -350,11 +354,11 @@ module Homebrew
|
||||
entries.each do |path|
|
||||
next if path == PERIODIC_CLEAN_FILE
|
||||
|
||||
FileUtils.chmod_R 0755, path if path.go_cache_directory? && !dry_run?
|
||||
next cleanup_path(path) { path.unlink } if path.incomplete?
|
||||
next cleanup_path(path) { FileUtils.rm_rf path } if path.nested_cache?
|
||||
FileUtils.chmod_R 0755, path if PathnameUtils.go_cache_directory?(path) && !dry_run?
|
||||
next cleanup_path(path) { path.unlink } if PathnameUtils.incomplete?(path)
|
||||
next cleanup_path(path) { FileUtils.rm_rf path } if PathnameUtils.nested_cache?(path)
|
||||
|
||||
if path.prune?(days)
|
||||
if PathnameUtils.prune?(path, days)
|
||||
if path.file? || path.symlink?
|
||||
cleanup_path(path) { path.unlink }
|
||||
elsif path.directory? && path.to_s.include?("--")
|
||||
@ -364,7 +368,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
# If we've specified --prune don't do the (expensive) .stale? check.
|
||||
cleanup_path(path) { path.unlink } if !prune? && path.stale?(scrub: scrub?)
|
||||
cleanup_path(path) { path.unlink } if !prune? && PathnameUtils.stale?(path, scrub: scrub?)
|
||||
end
|
||||
|
||||
cleanup_unreferenced_downloads
|
||||
@ -485,7 +489,7 @@ module Homebrew
|
||||
if child.basename.to_s == "__pycache__"
|
||||
child.find do |path|
|
||||
next unless path.extname == ".pyc"
|
||||
next unless path.prune?(days)
|
||||
next unless PathnameUtils.prune?(path, days)
|
||||
|
||||
unused_pyc_files << path
|
||||
end
|
||||
|
@ -6,8 +6,6 @@ require "cleanup"
|
||||
require "cask/cache"
|
||||
require "fileutils"
|
||||
|
||||
using Homebrew::Cleanup::CleanupRefinement
|
||||
|
||||
describe Homebrew::Cleanup do
|
||||
subject(:cleanup) { described_class.new }
|
||||
|
||||
@ -27,9 +25,7 @@ describe Homebrew::Cleanup do
|
||||
FileUtils.rm_rf HOMEBREW_LIBRARY/"Homebrew"
|
||||
end
|
||||
|
||||
describe "::CleanupRefinement::prune?" do
|
||||
alias_matcher :be_pruned, :be_prune
|
||||
|
||||
describe "::PathnameUtils.prune?" do
|
||||
subject(:path) { HOMEBREW_CACHE/"foo" }
|
||||
|
||||
before do
|
||||
@ -39,11 +35,11 @@ describe Homebrew::Cleanup do
|
||||
it "returns true when ctime and mtime < days_default" do
|
||||
allow_any_instance_of(Pathname).to receive(:ctime).and_return((DateTime.now - 2).to_time)
|
||||
allow_any_instance_of(Pathname).to receive(:mtime).and_return((DateTime.now - 2).to_time)
|
||||
expect(path.prune?(1)).to be true
|
||||
expect(described_class::PathnameUtils.prune?(path, 1)).to be true
|
||||
end
|
||||
|
||||
it "returns false when ctime and mtime >= days_default" do
|
||||
expect(path.prune?(2)).to be false
|
||||
expect(described_class::PathnameUtils.prune?(path, 2)).to be false
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user