Use option parser for brew cleanup.

This commit is contained in:
Markus Reiter 2018-08-08 11:20:53 +02:00
parent 6ae224611c
commit 03b93da296
5 changed files with 90 additions and 76 deletions

View File

@ -1,5 +1,6 @@
require "utils/bottles"
require "formula"
require "hbc/cask_loader"
module CleanupRefinement
refine Pathname do
@ -67,22 +68,50 @@ end
using CleanupRefinement
module Homebrew
module Cleanup
@disk_cleanup_size = 0
class Cleanup
extend Predicable
class << self
attr_reader :disk_cleanup_size
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
end
module_function
def clean!
if args.empty?
Formula.installed.each do |formula|
cleanup_formula(formula)
end
cleanup_cache
cleanup_logs
return if dry_run?
cleanup_lockfiles
rm_ds_store
else
args.each do |arg|
formula = begin
Formula[arg]
rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
nil
end
def cleanup
cleanup_cellar
cleanup_cache
cleanup_logs
return if ARGV.dry_run?
cleanup_lockfiles
rm_ds_store
cask = begin
Hbc::CaskLoader.load(arg)
rescue Hbc::CaskUnavailableError
nil
end
cleanup_formula(formula) if formula
cleanup_cask(cask) if cask
end
end
end
def update_disk_cleanup_size(path_size)
@ -93,14 +122,12 @@ module Homebrew
@unremovable_kegs ||= []
end
def cleanup_cellar(formulae = Formula.installed)
formulae.each(&method(:cleanup_formula))
end
def cleanup_formula(formula)
formula.eligible_kegs_for_cleanup.each(&method(:cleanup_keg))
end
def cleanup_cask(cask); end
def cleanup_keg(keg)
cleanup_path(keg) { keg.uninstall }
rescue Errno::EACCES => e
@ -113,17 +140,17 @@ module Homebrew
def cleanup_logs
return unless HOMEBREW_LOGS.directory?
HOMEBREW_LOGS.subdirs.each do |dir|
cleanup_path(dir) { dir.rmtree } if dir.prune?(ARGV.value("prune")&.to_i || DEFAULT_LOG_DAYS)
cleanup_path(dir) { dir.rmtree } if dir.prune?(days || DEFAULT_LOG_DAYS)
end
end
def cleanup_cache(cache = HOMEBREW_CACHE)
def cleanup_cache
return unless cache.directory?
cache.children.each do |path|
next cleanup_path(path) { path.unlink } if path.incomplete?
next cleanup_path(path) { FileUtils.rm_rf path } if path.nested_cache?
if path.prune?(ARGV.value("prune")&.to_i)
if path.prune?(days)
if path.file?
cleanup_path(path) { path.unlink }
elsif path.directory? && path.to_s.include?("--")
@ -139,7 +166,7 @@ module Homebrew
def cleanup_path(path)
disk_usage = path.disk_usage
if ARGV.dry_run?
if dry_run?
puts "Would remove: #{path} (#{path.abv})"
else
puts "Removing: #{path}... (#{path.abv})"

View File

@ -12,34 +12,36 @@
#: deleted. If you want to delete those too: `rm -rf $(brew --cache)`
require "cleanup"
require "cli_parser"
module Homebrew
module_function
def cleanup
if ARGV.named.empty?
Cleanup.cleanup
else
Cleanup.cleanup_cellar(ARGV.resolved_formulae)
CLI::Parser.parse do
switch "-n", "--dry-run"
switch "-s"
flag "--prune="
end
report_disk_usage unless Cleanup.disk_cleanup_size.zero?
report_unremovable_kegs unless Cleanup.unremovable_kegs.empty?
end
cleanup = Cleanup.new(*args.remaining, dry_run: args.dry_run?, scrub: args.s?, days: args.prune&.to_i)
def report_disk_usage
disk_space = disk_usage_readable(Cleanup.disk_cleanup_size)
if ARGV.dry_run?
ohai "This operation would free approximately #{disk_space} of disk space."
else
ohai "This operation has freed approximately #{disk_space} of disk space."
cleanup.clean!
unless cleanup.disk_cleanup_size.zero?
disk_space = disk_usage_readable(cleanup.disk_cleanup_size)
if args.dry_run?
ohai "This operation would free approximately #{disk_space} of disk space."
else
ohai "This operation has freed approximately #{disk_space} of disk space."
end
end
end
def report_unremovable_kegs
return if cleanup.unremovable_kegs.empty?
ofail <<~EOS
Could not cleanup old kegs! Fix your permissions on:
#{Cleanup.unremovable_kegs.join "\n "}
#{cleanup.unremovable_kegs.join "\n "}
EOS
end
end

View File

@ -147,10 +147,6 @@ module Homebrew
return unless legacy_cache.writable_real?
FileUtils.touch migration_attempted_file
# Cleanup to avoid copying files unnecessarily
ohai "Cleaning up #{legacy_cache}..."
Cleanup.cleanup_cache legacy_cache
# This directory could have been compromised if it's world-writable/
# a symlink/owned by another user so don't copy files in those cases.
world_writable = legacy_cache.stat.mode & 0777 == 0777

View File

@ -98,7 +98,7 @@ module Homebrew
upgrade_formula(f)
next if !ARGV.include?("--cleanup") && !ENV["HOMEBREW_UPGRADE_CLEANUP"]
next unless f.installed?
Homebrew::Cleanup.cleanup_formula f
Cleanup.new.cleanup_formula(f)
rescue UnsatisfiedRequirements => e
Homebrew.failed = true
onoe "#{f}: #{e}"

View File

@ -43,16 +43,14 @@ describe Homebrew::Cleanup do
describe "::cleanup" do
it "removes .DS_Store and lock files" do
described_class.cleanup
subject.clean!
expect(ds_store).not_to exist
expect(lock_file).not_to exist
end
it "doesn't remove anything if `--dry-run` is specified" do
ARGV << "--dry-run"
described_class.cleanup
it "doesn't remove anything if `dry_run` is true" do
described_class.new(dry_run: true).clean!
expect(ds_store).to exist
expect(lock_file).to exist
@ -61,7 +59,7 @@ describe Homebrew::Cleanup do
it "doesn't remove the lock file if it is locked" do
lock_file.open(File::RDWR | File::CREAT).flock(File::LOCK_EX | File::LOCK_NB)
described_class.cleanup
subject.clean!
expect(lock_file).to exist
end
@ -69,10 +67,8 @@ describe Homebrew::Cleanup do
context "when it can't remove a keg" do
let(:f1) { Class.new(Testball) { version "0.1" }.new }
let(:f2) { Class.new(Testball) { version "0.2" }.new }
let(:unremovable_kegs) { [] }
before do
described_class.instance_variable_set(:@unremovable_kegs, [])
[f1, f2].each do |f|
f.brew do
f.install
@ -87,13 +83,13 @@ describe Homebrew::Cleanup do
end
it "doesn't remove any kegs" do
described_class.cleanup_formula f2
subject.cleanup_formula f2
expect(f1.installed_kegs.size).to eq(2)
end
it "lists the unremovable kegs" do
described_class.cleanup_formula f2
expect(described_class.unremovable_kegs).to contain_exactly(f1.installed_kegs[0])
subject.cleanup_formula f2
expect(subject.unremovable_kegs).to contain_exactly(f1.installed_kegs[0])
end
end
end
@ -131,7 +127,7 @@ describe Homebrew::Cleanup do
expect(f3).to be_installed
expect(f4).to be_installed
described_class.cleanup_formula f3
subject.cleanup_formula f3
expect(f1).not_to be_installed
expect(f2).not_to be_installed
@ -146,21 +142,20 @@ describe Homebrew::Cleanup do
path.mkpath
end
it "cleans all logs if prune all" do
ARGV << "--prune=all"
described_class.cleanup_logs
it "cleans all logs if prune is 0" do
described_class.new(days: 0).cleanup_logs
expect(path).not_to exist
end
it "cleans up logs if older than 14 days" do
allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - 15 * 60 * 60 * 24)
described_class.cleanup_logs
subject.cleanup_logs
expect(path).not_to exist
end
it "does not clean up logs less than 14 days old" do
allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - 2 * 60 * 60 * 24)
described_class.cleanup_logs
subject.cleanup_logs
expect(path).to exist
end
end
@ -170,7 +165,7 @@ describe Homebrew::Cleanup do
incomplete = (HOMEBREW_CACHE/"something.incomplete")
incomplete.mkpath
described_class.cleanup_cache
subject.cleanup_cache
expect(incomplete).not_to exist
end
@ -179,7 +174,7 @@ describe Homebrew::Cleanup do
glide_home = (HOMEBREW_CACHE/"glide_home")
glide_home.mkpath
described_class.cleanup_cache
subject.cleanup_cache
expect(glide_home).not_to exist
end
@ -188,7 +183,7 @@ describe Homebrew::Cleanup do
java_cache = (HOMEBREW_CACHE/"java_cache")
java_cache.mkpath
described_class.cleanup_cache
subject.cleanup_cache
expect(java_cache).not_to exist
end
@ -197,7 +192,7 @@ describe Homebrew::Cleanup do
npm_cache = (HOMEBREW_CACHE/"npm_cache")
npm_cache.mkpath
described_class.cleanup_cache
subject.cleanup_cache
expect(npm_cache).not_to exist
end
@ -211,9 +206,7 @@ describe Homebrew::Cleanup do
gist.mkpath
FileUtils.touch svn
allow(ARGV).to receive(:value).with("prune").and_return("all")
described_class.cleanup_cache
described_class.new(days: 0).cleanup_cache
expect(git).not_to exist
expect(gist).to exist
@ -223,9 +216,8 @@ describe Homebrew::Cleanup do
it "does not clean up directories that are not VCS checkouts" do
git = (HOMEBREW_CACHE/"git")
git.mkpath
allow(ARGV).to receive(:value).with("prune").and_return("all")
described_class.cleanup_cache
described_class.new(days: 0).cleanup_cache
expect(git).to exist
end
@ -233,17 +225,15 @@ describe Homebrew::Cleanup do
it "cleans up VCS checkout directories with modified time < prune time" do
foo = (HOMEBREW_CACHE/"--foo")
foo.mkpath
allow(ARGV).to receive(:value).with("prune").and_return("1")
allow_any_instance_of(Pathname).to receive(:mtime).and_return(Time.now - 2 * 60 * 60 * 24)
described_class.cleanup_cache
described_class.new(days: 1).cleanup_cache
expect(foo).not_to exist
end
it "does not clean up VCS checkout directories with modified time >= prune time" do
foo = (HOMEBREW_CACHE/"--foo")
foo.mkpath
allow(ARGV).to receive(:value).with("prune").and_return("1")
described_class.cleanup_cache
described_class.new(days: 1).cleanup_cache
expect(foo).to exist
end
@ -260,20 +250,19 @@ describe Homebrew::Cleanup do
it "cleans up file if outdated" do
allow(Utils::Bottles).to receive(:file_outdated?).with(any_args).and_return(true)
described_class.cleanup_cache
subject.cleanup_cache
expect(bottle).not_to exist
expect(testball).not_to exist
end
it "cleans up file if ARGV has -s and formula not installed" do
ARGV << "-s"
described_class.cleanup_cache
it "cleans up file if `scrub` is true and formula not installed" do
described_class.new(scrub: true).cleanup_cache
expect(bottle).not_to exist
expect(testball).not_to exist
end
it "cleans up file if stale" do
described_class.cleanup_cache
subject.cleanup_cache
expect(bottle).not_to exist
expect(testball).not_to exist
end