Skip to content

Commit

Permalink
Merge pull request #5472 from MikeMcQuaid/periodic-cleanup
Browse files Browse the repository at this point in the history
Cleanup periodically if HOMEBREW_INSTALL_CLEANUP is set.
  • Loading branch information
MikeMcQuaid committed Jan 3, 2019
2 parents 62448eb + 5b7404a commit 9d1f940
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 53 deletions.
48 changes: 41 additions & 7 deletions Library/Homebrew/cleanup.rb
Expand Up @@ -3,9 +3,10 @@
require "cask/cask_loader"
require "set"

module CleanupRefinement
LATEST_CASK_OUTDATED = 7.days.ago
CLEANUP_DEFAULT_DAYS = 30
CLEANUP_MAX_AGE_DAYS = 120

module CleanupRefinement
refine Enumerator do
def parallel
queue = Queue.new
Expand Down Expand Up @@ -123,7 +124,7 @@ def stale_cask?(scrub)

return true if scrub && !cask.versions.include?(cask.version)

return mtime < LATEST_CASK_OUTDATED if cask.version.latest?
return mtime < CLEANUP_DEFAULT_DAYS.days.ago if cask.version.latest?

false
end
Expand All @@ -136,6 +137,8 @@ module Homebrew
class Cleanup
extend Predicable

PERIODIC_CLEAN_FILE = HOMEBREW_CACHE/".cleaned"

attr_predicate :dry_run?, :scrub?
attr_reader :args, :days, :cache
attr_reader :disk_cleanup_size
Expand All @@ -145,11 +148,38 @@ def initialize(*args, dry_run: false, scrub: false, days: nil, cache: HOMEBREW_C
@args = args
@dry_run = dry_run
@scrub = scrub
@days = days
@days = days || CLEANUP_MAX_AGE_DAYS
@cache = cache
@cleaned_up_paths = Set.new
end

def self.install_formula_clean!(f)
return if ENV["HOMEBREW_NO_INSTALL_CLEANUP"]
return unless ENV["HOMEBREW_INSTALL_CLEANUP"]

cleanup = Cleanup.new
if cleanup.periodic_clean_due?
cleanup.periodic_clean!
elsif f.installed?
cleanup.cleanup_formula(f)
end
end

def periodic_clean_due?
return false if ENV["HOMEBREW_NO_INSTALL_CLEANUP"]
return unless ENV["HOMEBREW_INSTALL_CLEANUP"]
return true unless PERIODIC_CLEAN_FILE.exist?

PERIODIC_CLEAN_FILE.mtime < CLEANUP_DEFAULT_DAYS.days.ago
end

def periodic_clean!
return false unless periodic_clean_due?

ohai "`brew cleanup` has not been run in #{CLEANUP_DEFAULT_DAYS} days, running now..."
clean!
end

def clean!
if args.empty?
Formula.installed.sort_by(&:name).each do |formula|
Expand All @@ -164,6 +194,7 @@ def clean!
cleanup_old_cache_db
rm_ds_store
prune_prefix_symlinks_and_directories
FileUtils.touch PERIODIC_CLEAN_FILE
else
args.each do |arg|
formula = begin
Expand Down Expand Up @@ -208,13 +239,16 @@ def cleanup_keg(keg)
unremovable_kegs << keg
end

DEFAULT_LOG_DAYS = 14

def cleanup_logs
return unless HOMEBREW_LOGS.directory?
logs_days = if days > CLEANUP_DEFAULT_DAYS
CLEANUP_DEFAULT_DAYS
else
days
end

HOMEBREW_LOGS.subdirs.each do |dir|
cleanup_path(dir) { dir.rmtree } if dir.prune?(days || DEFAULT_LOG_DAYS)
cleanup_path(dir) { dir.rmtree } if dir.prune?(logs_days)
end
end

Expand Down
6 changes: 2 additions & 4 deletions Library/Homebrew/cmd/install.rb
Expand Up @@ -73,15 +73,13 @@
#:
#: If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for
#: creating patches to the software.
#:
#: If `HOMEBREW_INSTALL_CLEANUP` is set then remove previously installed versions
#: of upgraded <formulae> as well as the HOMEBREW_CACHE for that formula.

require "missing_formula"
require "formula_installer"
require "development_tools"
require "install"
require "search"
require "cleanup"

module Homebrew
module_function
Expand Down Expand Up @@ -257,7 +255,7 @@ def install
formulae.each do |f|
Migrator.migrate_if_needed(f)
install_formula(f)
Cleanup.new.cleanup_formula(f) if ENV["HOMEBREW_INSTALL_CLEANUP"]
Cleanup.install_formula_clean!(f)
end
Homebrew.messages.display_messages
rescue FormulaUnreadableError, FormulaClassUnavailableError,
Expand Down
3 changes: 2 additions & 1 deletion Library/Homebrew/cmd/reinstall.rb
Expand Up @@ -12,6 +12,7 @@
require "messages"
require "reinstall"
require "cli_parser"
require "cleanup"

module Homebrew
module_function
Expand Down Expand Up @@ -49,7 +50,7 @@ def reinstall
end
Migrator.migrate_if_needed(f)
reinstall_formula(f)
Cleanup.new.cleanup_formula(f) if ENV["HOMEBREW_INSTALL_CLEANUP"]
Cleanup.install_formula_clean!(f)
end
Homebrew.messages.display_messages
end
Expand Down
21 changes: 12 additions & 9 deletions Library/Homebrew/cmd/upgrade.rb
@@ -1,11 +1,8 @@
#: * `upgrade` [<install-options>] [`--cleanup`] [`--fetch-HEAD`] [`--ignore-pinned`] [`--display-times`] [<formulae>]:
#: * `upgrade` [<install-options>] [`--fetch-HEAD`] [`--ignore-pinned`] [`--display-times`] [<formulae>]:
#: Upgrade outdated, unpinned brews (with existing install options).
#:
#: Options for the `install` command are also valid here.
#:
#: If `--cleanup` is specified or `HOMEBREW_INSTALL_CLEANUP` is set then remove
#: previously installed version(s) of upgraded <formulae>.
#:
#: If `--fetch-HEAD` is passed, fetch the upstream repository to detect if
#: the HEAD installation of the formula is outdated. Otherwise, the
#: repository's HEAD will be checked for updates when a new stable or devel
Expand All @@ -23,14 +20,23 @@
require "install"
require "reinstall"
require "formula_installer"
require "cleanup"
require "development_tools"
require "messages"
require "cleanup"

module Homebrew
module_function

def upgrade
# TODO: deprecate for next minor release.
if ARGV.include?("--cleanup")
ENV["HOMEBREW_INSTALL_CLEANUP"] = "1"
# odeprecated("'brew upgrade --cleanup'", "'HOMEBREW_INSTALL_CLEANUP'")
elsif ENV["HOMEBREW_UPGRADE_CLEANUP"]
ENV["HOMEBREW_INSTALL_CLEANUP"] = "1"
# odeprecated("'HOMEBREW_UPGRADE_CLEANUP'", "'HOMEBREW_INSTALL_CLEANUP'")
end

FormulaInstaller.prevent_build_flags unless DevelopmentTools.installed?

Install.perform_preinstall_checks
Expand Down Expand Up @@ -107,10 +113,7 @@ def upgrade_formulae(formulae_to_install)
Migrator.migrate_if_needed(f)
begin
upgrade_formula(f)
next if !ARGV.include?("--cleanup") && !ENV["HOMEBREW_UPGRADE_CLEANUP"] && !ENV["HOMEBREW_INSTALL_CLEANUP"]
next unless f.installed?

Cleanup.new.cleanup_formula(f)
Cleanup.install_formula_clean!(f)
rescue UnsatisfiedRequirements => e
Homebrew.failed = true
onoe "#{f}: #{e}"
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/tests.rb
Expand Up @@ -86,7 +86,7 @@ def tests
ENV["GIT_#{role}_DATE"] = "Sun Jan 22 19:59:13 2017 +0000"
end

Homebrew.install_gem_setup_path! "bundler"
Homebrew.install_gem_setup_path! "bundler", "<2"
system "bundle", "install" unless quiet_system("bundle", "check")

parallel = true
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/dev-cmd/vendor-gems.rb
Expand Up @@ -17,7 +17,7 @@ def vendor_gems
switch :debug
end.parse

Homebrew.install_gem_setup_path! "bundler"
Homebrew.install_gem_setup_path! "bundler", "<2"

ohai "cd #{HOMEBREW_LIBRARY_PATH}/vendor"
(HOMEBREW_LIBRARY_PATH/"vendor").cd do
Expand Down
18 changes: 15 additions & 3 deletions Library/Homebrew/manpages/brew.1.md.erb
Expand Up @@ -198,6 +198,16 @@ Note that environment variables must have a value set to be detected. For exampl

*Default:* the beer emoji.

* `HOMEBREW_INSTALL_CLEANUP`:
If set, `brew install`, `brew upgrade` and `brew reinstall` will remove
previously installed version(s) of the installed/upgraded formulae.

If `brew cleanup` has not been run in 30 days then it will be run at this
time.

This will become the default in a later version of Homebrew. To opt-out see
`HOMEBREW_NO_INSTALL_CLEANUP`.

* `HOMEBREW_LOGS`:
If set, Homebrew will use the specified directory to store log files.

Expand Down Expand Up @@ -235,6 +245,11 @@ Note that environment variables must have a value set to be detected. For exampl
If set, Homebrew will not use the GitHub API, e.g. for searches or
fetching relevant issues on a failed install.

* `HOMEBREW_NO_INSTALL_CLEANUP`:
If set, `brew install`, `brew upgrade` and `brew reinstall` will never
automatically remove the previously installed version(s) of the
installed/upgraded formulae.

* `HOMEBREW_PRY`:
If set, Homebrew will use Pry for the `brew irb` command.

Expand All @@ -256,9 +271,6 @@ Note that environment variables must have a value set to be detected. For exampl
If set, instructs Homebrew to always use the latest stable tag (even if
developer commands have been run).

* `HOMEBREW_UPGRADE_CLEANUP`:
If set, `brew upgrade` always assumes `--cleanup` has been passed.

* `HOMEBREW_VERBOSE`:
If set, Homebrew always assumes `--verbose` when running commands.

Expand Down
12 changes: 6 additions & 6 deletions Library/Homebrew/test/cleanup_spec.rb
Expand Up @@ -178,10 +178,10 @@
expect(download).to exist
end

it "removes the download for the latest version after a week" do
it "removes the download for the latest version after 30 days" do
download = Cask::Cache.path/"#{cask.token}--#{cask.version}"

FileUtils.touch download, mtime: 7.days.ago - 1.hour
FileUtils.touch download, mtime: 30.days.ago - 1.hour

subject.cleanup_cask(cask)

Expand All @@ -202,14 +202,14 @@
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(15.days.ago)
it "cleans up logs if older than 30 days" do
allow_any_instance_of(Pathname).to receive(:mtime).and_return(31.days.ago)
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(2.days.ago)
it "does not clean up logs less than 30 days old" do
allow_any_instance_of(Pathname).to receive(:mtime).and_return(15.days.ago)
subject.cleanup_logs
expect(path).to exist
end
Expand Down
26 changes: 16 additions & 10 deletions docs/Manpage.md
Expand Up @@ -312,9 +312,6 @@ these flags should only appear after a command.
If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for
creating patches to the software.

If `HOMEBREW_INSTALL_CLEANUP` is set then remove previously installed versions
of upgraded *`formulae`* as well as the HOMEBREW_CACHE for that formula.

* `leaves`:
Show installed formulae that are not dependencies of another installed formula.

Expand Down Expand Up @@ -599,14 +596,11 @@ these flags should only appear after a command.
`repositories`) using `git`(1) to their latest `origin/master`. Note this
will destroy all your uncommitted or committed changes.

* `upgrade` [*`install-options`*] [`--cleanup`] [`--fetch-HEAD`] [`--ignore-pinned`] [`--display-times`] [*`formulae`*]:
* `upgrade` [*`install-options`*] [`--fetch-HEAD`] [`--ignore-pinned`] [`--display-times`] [*`formulae`*]:
Upgrade outdated, unpinned brews (with existing install options).

Options for the `install` command are also valid here.

If `--cleanup` is specified or `HOMEBREW_INSTALL_CLEANUP` is set then remove
previously installed version(s) of upgraded *`formulae`*.

If `--fetch-HEAD` is passed, fetch the upstream repository to detect if
the HEAD installation of the formula is outdated. Otherwise, the
repository's HEAD will be checked for updates when a new stable or devel
Expand Down Expand Up @@ -1198,6 +1192,16 @@ Note that environment variables must have a value set to be detected. For exampl

*Default:* the beer emoji.

* `HOMEBREW_INSTALL_CLEANUP`:
If set, `brew install`, `brew upgrade` and `brew reinstall` will remove
previously installed version(s) of the installed/upgraded formulae.

If `brew cleanup` has not been run in 30 days then it will be run at this
time.

This will become the default in a later version of Homebrew. To opt-out see
`HOMEBREW_NO_INSTALL_CLEANUP`.

* `HOMEBREW_LOGS`:
If set, Homebrew will use the specified directory to store log files.

Expand Down Expand Up @@ -1235,6 +1239,11 @@ Note that environment variables must have a value set to be detected. For exampl
If set, Homebrew will not use the GitHub API, e.g. for searches or
fetching relevant issues on a failed install.

* `HOMEBREW_NO_INSTALL_CLEANUP`:
If set, `brew install`, `brew upgrade` and `brew reinstall` will never
automatically remove the previously installed version(s) of the
installed/upgraded formulae.

* `HOMEBREW_PRY`:
If set, Homebrew will use Pry for the `brew irb` command.

Expand All @@ -1256,9 +1265,6 @@ Note that environment variables must have a value set to be detected. For exampl
If set, instructs Homebrew to always use the latest stable tag (even if
developer commands have been run).

* `HOMEBREW_UPGRADE_CLEANUP`:
If set, `brew upgrade` always assumes `--cleanup` has been passed.

* `HOMEBREW_VERBOSE`:
If set, Homebrew always assumes `--verbose` when running commands.

Expand Down

0 comments on commit 9d1f940

Please sign in to comment.