Moved autoremove logic into cleanup.rb and formula.rb

Cleanup.rb:
- Added #autoremove method
- #autoremove is called in clean when HOMEBREW_AUTOREMOVE is set

Formula.rb:
- Added #unused_formulae_with_no_dependents and helpers

Removed old autoremove.rb module.
This commit is contained in:
apainintheneck 2022-07-14 13:16:26 -07:00
parent fa43418bfb
commit fe83500617
10 changed files with 66 additions and 81 deletions

View File

@ -1,64 +0,0 @@
# typed: false
# frozen_string_literal: true
require "cask/caskroom"
require "formula"
require "uninstall"
module Homebrew
# Helpers for removing unused formulae.
#
# @api private
module Autoremove
module_function
def remove_unused_formulae(dry_run: false)
removable_formulae = unused_formulae_with_no_dependents
return if removable_formulae.blank?
formulae_names = removable_formulae.map(&:full_name).sort
verb = dry_run ? "Would autoremove" : "Autoremoving"
oh1 "#{verb} #{formulae_names.count} unneeded #{"formula".pluralize(formulae_names.count)}:"
puts formulae_names.join("\n")
return if dry_run
kegs_by_rack = removable_formulae.map(&:any_installed_keg).group_by(&:rack)
Uninstall.uninstall_kegs(kegs_by_rack)
end
# An array of installed {Formula} without {Formula} or {Cask}
# dependents that weren't installed on request.
# @private
def unused_formulae_with_no_dependents
unused_formulae = unused_formulae_with_no_formula_dependents(Formula.installed)
unused_formulae - installed_formulae_with_cask_dependents
end
# Recursive function that returns an array of installed {Formula} without
# {Formula} dependents that weren't installed on request.
# @private
def unused_formulae_with_no_formula_dependents(formulae)
unused_formulae = Formula.installed_formulae_with_no_dependents(formulae).reject do |f|
Tab.for_keg(f.any_installed_keg).installed_on_request
end
if unused_formulae.present?
unused_formulae += unused_formulae_with_no_formula_dependents(formulae - unused_formulae)
end
unused_formulae
end
# An array of all installed {Formula} with {Cask} dependents.
# @private
def installed_formulae_with_cask_dependents
Cask::Caskroom.casks
.flat_map { |cask| cask.depends_on[:formula] }
.compact
.map { |f| Formula[f] }
.flat_map { |f| [f, *f.runtime_formula_dependencies].compact }
end
end
end

View File

@ -219,6 +219,9 @@ module Homebrew
.each do |formula| .each do |formula|
cleanup_formula(formula, quiet: quiet, ds_store: false, cache_db: false) cleanup_formula(formula, quiet: quiet, ds_store: false, cache_db: false)
end end
Cleanup.autoremove(dry_run: dry_run?) if Homebrew::EnvConfig.autoremove?
cleanup_cache cleanup_cache
cleanup_logs cleanup_logs
cleanup_lockfiles cleanup_lockfiles
@ -261,6 +264,8 @@ module Homebrew
end end
cleanup_cask(cask) if cask cleanup_cask(cask) if cask
end end
Cleanup.autoremove(dry_run: dry_run?) if Homebrew::EnvConfig.autoremove?
end end
end end
@ -519,5 +524,23 @@ module Homebrew
print "and #{d} directories " if d.positive? print "and #{d} directories " if d.positive?
puts "from #{HOMEBREW_PREFIX}" puts "from #{HOMEBREW_PREFIX}"
end end
def self.autoremove(dry_run: false)
removable_formulae = Formula.unused_formulae_with_no_dependents
return if removable_formulae.blank?
formulae_names = removable_formulae.map(&:full_name).sort
verb = dry_run ? "Would autoremove" : "Autoremoving"
oh1 "#{verb} #{formulae_names.count} unneeded #{"formula".pluralize(formulae_names.count)}:"
puts formulae_names.join("\n")
return if dry_run
require "uninstall"
kegs_by_rack = removable_formulae.map(&:any_installed_keg).group_by(&:rack)
Uninstall.uninstall_kegs(kegs_by_rack)
end
end end
end end

View File

@ -1,7 +1,7 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "autoremove" require "cleanup"
require "cli/parser" require "cli/parser"
module Homebrew module Homebrew
@ -22,6 +22,6 @@ module Homebrew
def autoremove def autoremove
args = autoremove_args.parse args = autoremove_args.parse
Autoremove.remove_unused_formulae(dry_run: args.dry_run?) Cleanup.autoremove(dry_run: args.dry_run?)
end end
end end

View File

@ -1,7 +1,6 @@
# typed: false # typed: false
# frozen_string_literal: true # frozen_string_literal: true
require "autoremove"
require "cask/config" require "cask/config"
require "cask/cmd" require "cask/cmd"
require "cask/cmd/install" require "cask/cmd/install"
@ -255,8 +254,6 @@ module Homebrew
) )
Homebrew.messages.display_messages(display_times: args.display_times?) Homebrew.messages.display_messages(display_times: args.display_times?)
Autoremove.remove_unused_formulae if Homebrew::EnvConfig.autoremove?
rescue FormulaUnreadableError, FormulaClassUnavailableError, rescue FormulaUnreadableError, FormulaClassUnavailableError,
TapFormulaUnreadableError, TapFormulaClassUnavailableError => e TapFormulaUnreadableError, TapFormulaClassUnavailableError => e
# Need to rescue before `FormulaUnavailableError` (superclass of this) # Need to rescue before `FormulaUnavailableError` (superclass of this)

View File

@ -37,7 +37,7 @@ module Homebrew
def leaves def leaves
args = leaves_args.parse args = leaves_args.parse
leaves_list = Formula.installed_formulae_with_no_dependents leaves_list = Formula.installed_formulae_with_no_formula_dependents
leaves_list.select!(&method(:installed_on_request?)) if args.installed_on_request? leaves_list.select!(&method(:installed_on_request?)) if args.installed_on_request?
leaves_list.select!(&method(:installed_as_dependency?)) if args.installed_as_dependency? leaves_list.select!(&method(:installed_as_dependency?)) if args.installed_as_dependency?

View File

@ -1,7 +1,6 @@
# typed: false # typed: false
# frozen_string_literal: true # frozen_string_literal: true
require "autoremove"
require "formula_installer" require "formula_installer"
require "development_tools" require "development_tools"
require "messages" require "messages"
@ -153,7 +152,5 @@ module Homebrew
end end
Homebrew.messages.display_messages(display_times: args.display_times?) Homebrew.messages.display_messages(display_times: args.display_times?)
Autoremove.remove_unused_formulae if Homebrew::EnvConfig.autoremove?
end end
end end

View File

@ -79,6 +79,6 @@ module Homebrew
) )
end end
Autoremove.remove_unused_formulae if Homebrew::EnvConfig.autoremove? Cleanup.autoremove if Homebrew::EnvConfig.autoremove?
end end
end end

View File

@ -1,7 +1,6 @@
# typed: false # typed: false
# frozen_string_literal: true # frozen_string_literal: true
require "autoremove"
require "cli/parser" require "cli/parser"
require "formula_installer" require "formula_installer"
require "install" require "install"
@ -112,8 +111,6 @@ module Homebrew
upgrade_outdated_casks(casks, args: args) unless only_upgrade_formulae upgrade_outdated_casks(casks, args: args) unless only_upgrade_formulae
Homebrew.messages.display_messages(display_times: args.display_times?) Homebrew.messages.display_messages(display_times: args.display_times?)
Autoremove.remove_unused_formulae(dry_run: args.dry_run?) if Homebrew::EnvConfig.autoremove?
end end
sig { params(formulae: T::Array[Formula], args: CLI::Args).returns(T::Boolean) } sig { params(formulae: T::Array[Formula], args: CLI::Args).returns(T::Boolean) }

View File

@ -1706,14 +1706,49 @@ class Formula
end.uniq(&:name) end.uniq(&:name)
end end
# An array of all installed {Formula} with {Cask} dependents.
# @private
def self.installed_formulae_with_cask_dependents
require "cask/caskroom"
Cask::Caskroom.casks
.flat_map { |cask| cask.depends_on[:formula] }
.compact
.map { |f| Formula[f] }
.flat_map { |f| [f, *f.runtime_formula_dependencies].compact }
end
# An array of all installed {Formula} without {Formula} dependents # An array of all installed {Formula} without {Formula} dependents
# @private # @private
def self.installed_formulae_with_no_dependents(formulae = installed) def self.installed_formulae_with_no_formula_dependents(formulae = installed)
return [] if formulae.blank? return [] if formulae.blank?
formulae - formulae.flat_map(&:runtime_formula_dependencies) formulae - formulae.flat_map(&:runtime_formula_dependencies)
end end
# Recursive function that returns an array of installed {Formula} without
# {Formula} dependents that weren't installed on request.
# @private
def self.unused_formulae_with_no_formula_dependents(formulae)
unused_formulae = installed_formulae_with_no_formula_dependents(formulae).reject do |f|
Tab.for_keg(f.any_installed_keg).installed_on_request
end
if unused_formulae.present?
unused_formulae += unused_formulae_with_no_formula_dependents(formulae - unused_formulae)
end
unused_formulae
end
# An array of installed {Formula} without {Formula} or {Cask}
# dependents that weren't installed on request.
# @private
def self.unused_formulae_with_no_dependents
unused_formulae = unused_formulae_with_no_formula_dependents(installed)
unused_formulae - installed_formulae_with_cask_dependents
end
def self.installed_with_alias_path(alias_path) def self.installed_with_alias_path(alias_path)
return [] if alias_path.nil? return [] if alias_path.nil?

View File

@ -446,7 +446,7 @@ describe Formula do
end end
end end
describe "::installed_formulae_with_no_dependents" do describe "::installed_formulae_with_no_formula_dependents" do
let(:formula_is_dep) do let(:formula_is_dep) do
formula "foo" do formula "foo" do
url "foo-1.1" url "foo-1.1"
@ -473,12 +473,12 @@ describe Formula do
specify "without formulae parameter" do specify "without formulae parameter" do
allow(described_class).to receive(:installed).and_return(formulae) allow(described_class).to receive(:installed).and_return(formulae)
expect(described_class.installed_formulae_with_no_dependents) expect(described_class.installed_formulae_with_no_formula_dependents)
.to eq([formula_with_deps]) .to eq([formula_with_deps])
end end
specify "with formulae parameter" do specify "with formulae parameter" do
expect(described_class.installed_formulae_with_no_dependents(formulae)) expect(described_class.installed_formulae_with_no_formula_dependents(formulae))
.to eq([formula_with_deps]) .to eq([formula_with_deps])
end end
end end