Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup: Continue on error removing keg #2374

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 28 additions & 19 deletions Library/Homebrew/cleanup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module Homebrew
module Cleanup
@disk_cleanup_size = 0

def self.cleanup
module_function

def cleanup
cleanup_cellar
cleanup_cache
cleanup_logs
Expand All @@ -15,34 +17,41 @@ def self.cleanup
rm_ds_store
end

def self.update_disk_cleanup_size(path_size)
def update_disk_cleanup_size(path_size)
@disk_cleanup_size += path_size
end

def self.disk_cleanup_size
def disk_cleanup_size
@disk_cleanup_size
end

def self.cleanup_formula(formula)
formula.eligible_kegs_for_cleanup.each do |keg|
cleanup_path(keg) { keg.uninstall }
end
def unremovable_kegs
@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 self.cleanup_logs
def cleanup_keg(keg)
cleanup_path(keg) { keg.uninstall }
rescue Errno::EACCES => e
opoo e.message
unremovable_kegs << keg
end

def cleanup_logs
return unless HOMEBREW_LOGS.directory?
HOMEBREW_LOGS.subdirs.each do |dir|
cleanup_path(dir) { dir.rmtree } if prune?(dir, days_default: 14)
end
end

def self.cleanup_cellar
Formula.installed.each do |formula|
cleanup_formula formula
end
end

def self.cleanup_cache(cache = HOMEBREW_CACHE)
def cleanup_cache(cache = HOMEBREW_CACHE)
return unless cache.directory?
cache.children.each do |path|
if path.to_s.end_with? ".incomplete"
Expand Down Expand Up @@ -97,7 +106,7 @@ def self.cleanup_cache(cache = HOMEBREW_CACHE)
end
end

def self.cleanup_path(path)
def cleanup_path(path)
if ARGV.dry_run?
puts "Would remove: #{path} (#{path.abv})"
else
Expand All @@ -108,7 +117,7 @@ def self.cleanup_path(path)
update_disk_cleanup_size(path.disk_usage)
end

def self.cleanup_lockfiles
def cleanup_lockfiles
return unless HOMEBREW_LOCK_DIR.directory?
candidates = HOMEBREW_LOCK_DIR.children
lockfiles = candidates.select(&:file?)
Expand All @@ -118,7 +127,7 @@ def self.cleanup_lockfiles
end
end

def self.rm_ds_store
def rm_ds_store
paths = Queue.new
%w[Cellar Frameworks Library bin etc include lib opt sbin share var]
.map { |p| HOMEBREW_PREFIX/p }.each { |p| paths << p if p.exist? }
Expand All @@ -136,7 +145,7 @@ def self.rm_ds_store
workers.map(&:join)
end

def self.prune?(path, options = {})
def prune?(path, options = {})
@time ||= Time.now

path_modified_time = path.mtime
Expand Down
14 changes: 12 additions & 2 deletions Library/Homebrew/cmd/cleanup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,26 @@ def cleanup
if ARGV.named.empty?
Cleanup.cleanup
else
ARGV.resolved_formulae.each { |f| Cleanup.cleanup_formula f }
Cleanup.cleanup_cellar(ARGV.resolved_formulae)
end

return if Cleanup.disk_cleanup_size.zero?
report_disk_usage unless Cleanup.disk_cleanup_size.zero?
report_unremovable_kegs unless Cleanup.unremovable_kegs.empty?
end

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."
end
end

def report_unremovable_kegs
ofail <<-EOS.undent
Could not cleanup old kegs! Fix your permissions on:
#{Cleanup.unremovable_kegs.join "\n "}
EOS
end
end
33 changes: 33 additions & 0 deletions Library/Homebrew/test/cleanup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@

expect(ds_store).to exist
end

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(:each) do
described_class.instance_variable_set(:@unremovable_kegs, [])
shutup do
[f1, f2].each do |f|
f.brew do
f.install
end

Tab.create(f, DevelopmentTools.default_compiler, :libcxx).write
end
end

allow_any_instance_of(Keg)
.to receive(:uninstall)
.and_raise(Errno::EACCES)
end

it "doesn't remove any kegs" do
shutup { described_class.cleanup_formula f2 }
expect(f1.installed_kegs.size).to eq(2)
end

it "lists the unremovable kegs" do
shutup { described_class.cleanup_formula f2 }
expect(described_class.unremovable_kegs).to contain_exactly(f1.installed_kegs[0])
end
end
end

specify "::cleanup_formula" do
Expand Down