Pass verbose? to Keg#link, Keg#unlink and Keg#optlink.

This commit is contained in:
Markus Reiter 2020-08-02 04:46:32 +02:00
parent e9d8f09da1
commit 6c964d4a78
14 changed files with 92 additions and 92 deletions

View File

@ -201,7 +201,7 @@ class Build
else else
raise raise
end end
Keg.new(path).optlink Keg.new(path).optlink(verbose: args.verbose?)
rescue rescue
raise "#{f.opt_prefix} not present or broken\nPlease reinstall #{f.full_name}. Sorry :(" raise "#{f.opt_prefix} not present or broken\nPlease reinstall #{f.full_name}. Sorry :("
end end

View File

@ -258,7 +258,7 @@ module Homebrew
Install.perform_preinstall_checks(cc: args.cc) Install.perform_preinstall_checks(cc: args.cc)
formulae.each do |f| formulae.each do |f|
Migrator.migrate_if_needed(f, force: args.force?) Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?)
install_formula(f, args: args) install_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)
end end

View File

@ -31,10 +31,11 @@ module Homebrew
def link def link
args = link_args.parse args = link_args.parse
mode = OpenStruct.new options = {
overwrite: args.overwrite?,
mode.overwrite = true if args.overwrite? dry_run: args.dry_run?,
mode.dry_run = true if args.dry_run? verbose: args.verbose?,
}
args.kegs.each do |keg| args.kegs.each do |keg|
keg_only = Formulary.keg_only?(keg.rack) keg_only = Formulary.keg_only?(keg.rack)
@ -53,13 +54,13 @@ module Homebrew
next next
end end
if mode.dry_run if args.dry_run?
if mode.overwrite if args.overwrite?
puts "Would remove:" puts "Would remove:"
else else
puts "Would link:" puts "Would link:"
end end
keg.link(mode) keg.link(**options)
puts_keg_only_path_message(keg) if keg_only puts_keg_only_path_message(keg) if keg_only
next next
end end
@ -89,7 +90,7 @@ module Homebrew
puts if args.verbose? puts if args.verbose?
begin begin
n = keg.link(mode) n = keg.link(**options)
rescue Keg::LinkError rescue Keg::LinkError
puts puts
raise raise

View File

@ -33,7 +33,7 @@ module Homebrew
raise "#{rack} is a symlink" if rack.symlink? raise "#{rack} is a symlink" if rack.symlink?
end end
migrator = Migrator.new(f, force: args.force?) migrator = Migrator.new(f, force: args.force?, verbose: args.verbose?)
migrator.migrate migrator.migrate
end end
end end

View File

@ -67,7 +67,7 @@ module Homebrew
onoe "#{f.full_name} is pinned. You must unpin it to reinstall." onoe "#{f.full_name} is pinned. You must unpin it to reinstall."
next next
end end
Migrator.migrate_if_needed(f, force: args.force?) Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?)
reinstall_formula(f, args: args) reinstall_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)
end end

View File

@ -49,7 +49,7 @@ module Homebrew
# Link new version, if not keg-only # Link new version, if not keg-only
if Formulary.keg_only?(rack) if Formulary.keg_only?(rack)
keg.optlink keg.optlink(verbose: args.verbose?)
puts "Opt link created for #{keg}" puts "Opt link created for #{keg}"
else else
puts "#{keg.link} links created for #{keg}" puts "#{keg.link} links created for #{keg}"

View File

@ -26,20 +26,19 @@ module Homebrew
def unlink def unlink
args = unlink_args.parse args = unlink_args.parse
mode = OpenStruct.new options = { dry_run: args.dry_run?, verbose: args.verbose? }
mode.dry_run = true if args.dry_run?
args.kegs.each do |keg| args.kegs.each do |keg|
if mode.dry_run if args.dry_run?
puts "Would remove:" puts "Would remove:"
keg.unlink(mode) keg.unlink(**options)
next next
end end
keg.lock do keg.lock do
print "Unlinking #{keg}... " print "Unlinking #{keg}... "
puts if args.verbose? puts if args.verbose?
puts "#{keg.unlink(mode)} symlinks removed" puts "#{keg.unlink(**options)} symlinks removed"
end end
end end
end end

View File

@ -120,7 +120,7 @@ module Homebrew
else else
hub.dump(updated_formula_report: !args.preinstall?) hub.dump(updated_formula_report: !args.preinstall?)
hub.reporters.each(&:migrate_tap_migration) hub.reporters.each(&:migrate_tap_migration)
hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?) } hub.reporters.each { |r| r.migrate_formula_rename(force: args.force?, verbose: args.verbose?) }
CacheStoreDatabase.use(:descriptions) do |db| CacheStoreDatabase.use(:descriptions) do |db|
DescriptionCacheStore.new(db) DescriptionCacheStore.new(db)
.update_from_report!(hub) .update_from_report!(hub)
@ -371,7 +371,7 @@ class Reporter
end end
end end
def migrate_formula_rename(force:) def migrate_formula_rename(force:, verbose:)
Formula.installed.each do |formula| Formula.installed.each do |formula|
next unless Migrator.needs_migration?(formula) next unless Migrator.needs_migration?(formula)
@ -395,7 +395,7 @@ class Reporter
next next
end end
Migrator.migrate_if_needed(f, force: force) Migrator.migrate_if_needed(f, force: force, verbose: verbose)
end end
end end

View File

@ -662,7 +662,7 @@ class FormulaInstaller
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
ignore_interrupts do ignore_interrupts do
tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory? tmp_keg.rename(installed_keg) if tmp_keg && !installed_keg.directory?
linked_keg.link if keg_was_linked linked_keg.link(verbose: verbose?) if keg_was_linked
end end
raise unless e.is_a? FormulaInstallationAlreadyAttemptedError raise unless e.is_a? FormulaInstallationAlreadyAttemptedError
@ -842,7 +842,7 @@ class FormulaInstaller
def link(keg) def link(keg)
unless link_keg unless link_keg
begin begin
keg.optlink keg.optlink(verbose: verbose?)
Formula.clear_cache Formula.clear_cache
rescue Keg::LinkError => e rescue Keg::LinkError => e
onoe "Failed to create #{formula.opt_prefix}" onoe "Failed to create #{formula.opt_prefix}"
@ -873,7 +873,7 @@ class FormulaInstaller
backup_dir = HOMEBREW_CACHE/"Backup" backup_dir = HOMEBREW_CACHE/"Backup"
begin begin
keg.link keg.link(verbose: verbose?)
rescue Keg::ConflictError => e rescue Keg::ConflictError => e
conflict_file = e.dst conflict_file = e.dst
if formula.link_overwrite?(conflict_file) && !link_overwrite_backup.key?(conflict_file) if formula.link_overwrite?(conflict_file) && !link_overwrite_backup.key?(conflict_file)
@ -888,8 +888,7 @@ class FormulaInstaller
puts e puts e
puts puts
puts "Possible conflicting files are:" puts "Possible conflicting files are:"
mode = OpenStruct.new(dry_run: true, overwrite: true) keg.link(dry_run: true, overwrite: true, verbose: verbose?)
keg.link(mode)
@show_summary_heading = true @show_summary_heading = true
Homebrew.failed = true Homebrew.failed = true
rescue Keg::LinkError => e rescue Keg::LinkError => e

View File

@ -323,7 +323,7 @@ class Keg
EOS EOS
end end
def unlink(mode = OpenStruct.new) def unlink(**options)
ObserverPathnameExtension.reset_counts! ObserverPathnameExtension.reset_counts!
dirs = [] dirs = []
@ -341,7 +341,7 @@ class Keg
next unless dst.symlink? next unless dst.symlink?
next if src != dst.resolved_path next if src != dst.resolved_path
if mode.dry_run if options[:dry_run]
puts dst puts dst
Find.prune if src.directory? Find.prune if src.directory?
next next
@ -354,7 +354,7 @@ class Keg
end end
end end
unless mode.dry_run unless options[:dry_run]
remove_linked_keg_record if linked? remove_linked_keg_record if linked?
dirs.reverse_each(&:rmdir_if_possible) dirs.reverse_each(&:rmdir_if_possible)
end end
@ -436,21 +436,21 @@ class Keg
end end
end end
def link(mode = OpenStruct.new) def link(**options)
raise AlreadyLinkedError, self if linked_keg_record.directory? raise AlreadyLinkedError, self if linked_keg_record.directory?
ObserverPathnameExtension.reset_counts! ObserverPathnameExtension.reset_counts!
optlink(mode) unless mode.dry_run optlink(**options) unless options[:dry_run]
# yeah indeed, you have to force anything you need in the main tree into # yeah indeed, you have to force anything you need in the main tree into
# these dirs REMEMBER that *NOT* everything needs to be in the main tree # these dirs REMEMBER that *NOT* everything needs to be in the main tree
link_dir("etc", mode) { :mkpath } link_dir("etc", **options) { :mkpath }
link_dir("bin", mode) { :skip_dir } link_dir("bin", **options) { :skip_dir }
link_dir("sbin", mode) { :skip_dir } link_dir("sbin", **options) { :skip_dir }
link_dir("include", mode) { :link } link_dir("include", **options) { :link }
link_dir("share", mode) do |relative_path| link_dir("share", **options) do |relative_path|
case relative_path.to_s case relative_path.to_s
when "locale/locale.alias" then :skip_file when "locale/locale.alias" then :skip_file
when INFOFILE_RX then :info when INFOFILE_RX then :info
@ -468,7 +468,7 @@ class Keg
end end
end end
link_dir("lib", mode) do |relative_path| link_dir("lib", **options) do |relative_path|
case relative_path.to_s case relative_path.to_s
when "charset.alias" then :skip_file when "charset.alias" then :skip_file
# pkg-config database gets explicitly created # pkg-config database gets explicitly created
@ -494,7 +494,7 @@ class Keg
end end
end end
link_dir("Frameworks", mode) do |relative_path| link_dir("Frameworks", **options) do |relative_path|
# Frameworks contain symlinks pointing into a subdir, so we have to use # Frameworks contain symlinks pointing into a subdir, so we have to use
# the :link strategy. However, for Foo.framework and # the :link strategy. However, for Foo.framework and
# Foo.framework/Versions we have to use :mkpath so that multiple formulae # Foo.framework/Versions we have to use :mkpath so that multiple formulae
@ -506,9 +506,9 @@ class Keg
end end
end end
make_relative_symlink(linked_keg_record, path, mode) unless mode.dry_run make_relative_symlink(linked_keg_record, path, **options) unless options[:dry_run]
rescue LinkError rescue LinkError
unlink unlink(verbose: options[:verbose])
raise raise
else else
ObserverPathnameExtension.n ObserverPathnameExtension.n
@ -536,19 +536,19 @@ class Keg
tab.aliases || [] tab.aliases || []
end end
def optlink(mode = OpenStruct.new) def optlink(**options)
opt_record.delete if opt_record.symlink? || opt_record.exist? opt_record.delete if opt_record.symlink? || opt_record.exist?
make_relative_symlink(opt_record, path, mode) make_relative_symlink(opt_record, path, **options)
aliases.each do |a| aliases.each do |a|
alias_opt_record = opt_record.parent/a alias_opt_record = opt_record.parent/a
alias_opt_record.delete if alias_opt_record.symlink? || alias_opt_record.exist? alias_opt_record.delete if alias_opt_record.symlink? || alias_opt_record.exist?
make_relative_symlink(alias_opt_record, path, mode) make_relative_symlink(alias_opt_record, path, **options)
end end
return unless oldname_opt_record return unless oldname_opt_record
oldname_opt_record.delete oldname_opt_record.delete
make_relative_symlink(oldname_opt_record, path, mode) make_relative_symlink(oldname_opt_record, path, **options)
end end
def delete_pyc_files! def delete_pyc_files!
@ -558,7 +558,7 @@ class Keg
private private
def resolve_any_conflicts(dst, mode) def resolve_any_conflicts(dst, **options)
return unless dst.symlink? return unless dst.symlink?
src = dst.resolved_path src = dst.resolved_path
@ -571,7 +571,7 @@ class Keg
stat = src.lstat stat = src.lstat
rescue Errno::ENOENT rescue Errno::ENOENT
# dst is a broken symlink, so remove it. # dst is a broken symlink, so remove it.
dst.unlink unless mode.dry_run dst.unlink unless options[:dry_run]
return return
end end
@ -580,25 +580,23 @@ class Keg
begin begin
keg = Keg.for(src) keg = Keg.for(src)
rescue NotAKegError rescue NotAKegError
if Homebrew.args.verbose? puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar" if options[:verbose]
puts "Won't resolve conflicts for symlink #{dst} as it doesn't resolve into the Cellar"
end
return return
end end
dst.unlink unless mode.dry_run dst.unlink unless options[:dry_run]
keg.link_dir(src, mode) { :mkpath } keg.link_dir(src, **options) { :mkpath }
true true
end end
def make_relative_symlink(dst, src, mode) def make_relative_symlink(dst, src, **options)
if dst.symlink? && src == dst.resolved_path if dst.symlink? && src == dst.resolved_path
puts "Skipping; link already exists: #{dst}" if Homebrew.args.verbose? puts "Skipping; link already exists: #{dst}" if options[:verbose]
return return
end end
# cf. git-clean -n: list files to delete, don't really link or delete # cf. git-clean -n: list files to delete, don't really link or delete
if mode.dry_run && mode.overwrite if options[:dry_run] && options[:overwrite]
if dst.symlink? if dst.symlink?
puts "#{dst} -> #{dst.resolved_path}" puts "#{dst} -> #{dst.resolved_path}"
elsif dst.exist? elsif dst.exist?
@ -608,12 +606,12 @@ class Keg
end end
# list all link targets # list all link targets
if mode.dry_run if options[:dry_run]
puts dst puts dst
return return
end end
dst.delete if mode.overwrite && (dst.exist? || dst.symlink?) dst.delete if options[:overwrite] && (dst.exist? || dst.symlink?)
dst.make_relative_symlink(src) dst.make_relative_symlink(src)
rescue Errno::EEXIST => e rescue Errno::EEXIST => e
raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist? raise ConflictError.new(self, src.relative_path_from(path), dst, e) if dst.exist?
@ -631,7 +629,7 @@ class Keg
protected protected
# symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir # symlinks the contents of path+relative_dir recursively into #{HOMEBREW_PREFIX}/relative_dir
def link_dir(relative_dir, mode) def link_dir(relative_dir, **options)
root = path/relative_dir root = path/relative_dir
return unless root.exist? return unless root.exist?
@ -655,10 +653,10 @@ class Keg
when :info when :info
next if File.basename(src) == "dir" # skip historical local 'dir' files next if File.basename(src) == "dir" # skip historical local 'dir' files
make_relative_symlink dst, src, mode make_relative_symlink dst, src, **options
dst.install_info dst.install_info
else else
make_relative_symlink dst, src, mode make_relative_symlink dst, src, **options
end end
elsif src.directory? elsif src.directory?
# if the dst dir already exists, then great! walk the rest of the tree tho # if the dst dir already exists, then great! walk the rest of the tree tho
@ -672,10 +670,10 @@ class Keg
when :skip_dir when :skip_dir
Find.prune Find.prune
when :mkpath when :mkpath
dst.mkpath unless resolve_any_conflicts(dst, mode) dst.mkpath unless resolve_any_conflicts(dst, **options)
else else
unless resolve_any_conflicts(dst, mode) unless resolve_any_conflicts(dst, **options)
make_relative_symlink dst, src, mode make_relative_symlink dst, src, **options
Find.prune Find.prune
end end
end end

View File

@ -5,6 +5,8 @@ require "keg"
require "tab" require "tab"
class Migrator class Migrator
extend Predicable
class MigrationNeededError < RuntimeError class MigrationNeededError < RuntimeError
def initialize(formula) def initialize(formula)
super <<~EOS super <<~EOS
@ -86,6 +88,8 @@ class Migrator
# path to newname keg that will be linked if old_linked_keg isn't nil # path to newname keg that will be linked if old_linked_keg isn't nil
attr_reader :new_linked_keg_record attr_reader :new_linked_keg_record
attr_predicate :verbose?
def self.needs_migration?(formula) def self.needs_migration?(formula)
oldname = formula.oldname oldname = formula.oldname
return false unless oldname return false unless oldname
@ -97,18 +101,20 @@ class Migrator
true true
end end
def self.migrate_if_needed(formula, force:) def self.migrate_if_needed(formula, force:, verbose:)
return unless Migrator.needs_migration?(formula) return unless Migrator.needs_migration?(formula)
begin begin
migrator = Migrator.new(formula, force: force) migrator = Migrator.new(formula, force: force, verbose: verbose)
migrator.migrate migrator.migrate
rescue => e rescue => e
onoe e onoe e
end end
end end
def initialize(formula, force: false) def initialize(formula, force: false, verbose: false)
@verbose = verbose
@oldname = formula.oldname @oldname = formula.oldname
@newname = formula.name @newname = formula.name
raise MigratorNoOldnameError, formula unless oldname raise MigratorNoOldnameError, formula unless oldname
@ -267,7 +273,7 @@ class Migrator
oh1 "Unlinking #{Formatter.identifier(oldname)}" oh1 "Unlinking #{Formatter.identifier(oldname)}"
old_cellar.subdirs.each do |d| old_cellar.subdirs.each do |d|
keg = Keg.new(d) keg = Keg.new(d)
keg.unlink keg.unlink(verbose: verbose?)
end end
end end
@ -275,7 +281,7 @@ class Migrator
oh1 "Temporarily unlinking #{Formatter.identifier(newname)}" oh1 "Temporarily unlinking #{Formatter.identifier(newname)}"
new_cellar.subdirs.each do |d| new_cellar.subdirs.each do |d|
keg = Keg.new(d) keg = Keg.new(d)
keg.unlink keg.unlink(verbose: verbose?)
end end
end end
@ -288,7 +294,7 @@ class Migrator
# If formula is keg-only we also optlink it. # If formula is keg-only we also optlink it.
if formula.keg_only? || !old_linked_keg_record if formula.keg_only? || !old_linked_keg_record
begin begin
new_keg.optlink new_keg.optlink(verbose: verbose?)
rescue Keg::LinkError => e rescue Keg::LinkError => e
onoe "Failed to create #{formula.opt_prefix}" onoe "Failed to create #{formula.opt_prefix}"
raise raise
@ -299,15 +305,13 @@ class Migrator
new_keg.remove_linked_keg_record if new_keg.linked? new_keg.remove_linked_keg_record if new_keg.linked?
begin begin
mode = OpenStruct.new(overwrite: true) new_keg.link(overwrite: true, verbose: verbose?)
new_keg.link(mode)
rescue Keg::ConflictError => e rescue Keg::ConflictError => e
onoe "Error while executing `brew link` step on #{newname}" onoe "Error while executing `brew link` step on #{newname}"
puts e puts e
puts puts
puts "Possible conflicting files are:" puts "Possible conflicting files are:"
mode = OpenStruct.new(dry_run: true, overwrite: true) new_keg.link(dry_run: true, overwrite: true, verbose: verbose?)
new_keg.link(mode)
raise raise
rescue Keg::LinkError => e rescue Keg::LinkError => e
onoe "Error while linking" onoe "Error while linking"
@ -319,7 +323,7 @@ class Migrator
onoe "An unexpected error occurred during linking" onoe "An unexpected error occurred during linking"
puts e puts e
puts e.backtrace if Homebrew.args.debug? puts e.backtrace if Homebrew.args.debug?
ignore_interrupts { new_keg.unlink } ignore_interrupts { new_keg.unlink(verbose: verbose?) }
raise raise
end end
end end
@ -384,7 +388,7 @@ class Migrator
if new_cellar.exist? if new_cellar.exist?
new_cellar.subdirs.each do |d| new_cellar.subdirs.each do |d|
newname_keg = Keg.new(d) newname_keg = Keg.new(d)
newname_keg.unlink newname_keg.unlink(verbose: verbose?)
newname_keg.uninstall if new_cellar_existed newname_keg.uninstall if new_cellar_existed
end end
end end
@ -396,16 +400,16 @@ class Migrator
# create a keg using its old path # create a keg using its old path
if old_linked_keg_record if old_linked_keg_record
begin begin
old_linked_keg.link old_linked_keg.link(verbose: verbose?)
rescue Keg::LinkError rescue Keg::LinkError
old_linked_keg.unlink old_linked_keg.unlink(verbose: verbose?)
raise raise
rescue Keg::AlreadyLinkedError rescue Keg::AlreadyLinkedError
old_linked_keg.unlink old_linked_keg.unlink(verbose: verbose?)
retry retry
end end
else else
old_linked_keg.optlink old_linked_keg.optlink(verbose: verbose?)
end end
end end

View File

@ -49,7 +49,7 @@ module Homebrew
rescue FormulaInstallationAlreadyAttemptedError rescue FormulaInstallationAlreadyAttemptedError
nil nil
rescue Exception # rubocop:disable Lint/RescueException rescue Exception # rubocop:disable Lint/RescueException
ignore_interrupts { restore_backup(keg, keg_was_linked) } ignore_interrupts { restore_backup(keg, keg_was_linked, verbose: args.verbose?) }
raise raise
else else
begin begin
@ -82,7 +82,7 @@ module Homebrew
Pathname.new(keg).rmtree if keg.exist? Pathname.new(keg).rmtree if keg.exist?
path.rename keg path.rename keg
keg.link if keg_was_linked keg.link(verbose: verbose) if keg_was_linked
end end
def backup_path(path) def backup_path(path)

View File

@ -21,7 +21,6 @@ describe Keg do
let(:dst) { HOMEBREW_PREFIX/"bin"/"helloworld" } let(:dst) { HOMEBREW_PREFIX/"bin"/"helloworld" }
let(:nonexistent) { Pathname.new("/some/nonexistent/path") } let(:nonexistent) { Pathname.new("/some/nonexistent/path") }
let(:mode) { OpenStruct.new }
let!(:keg) { setup_test_keg("foo", "1.0") } let!(:keg) { setup_test_keg("foo", "1.0") }
let(:kegs) { [] } let(:kegs) { [] }
@ -84,11 +83,11 @@ describe Keg do
end end
context "with dry run set to true" do context "with dry run set to true" do
it "only prints what would be done" do let(:options) { { dry_run: true } }
mode.dry_run = true
it "only prints what would be done" do
expect { expect {
expect(keg.link(mode)).to eq(0) expect(keg.link(**options)).to eq(0)
}.to output(<<~EOF).to_stdout }.to output(<<~EOF).to_stdout
#{HOMEBREW_PREFIX}/bin/goodbye_cruel_world #{HOMEBREW_PREFIX}/bin/goodbye_cruel_world
#{HOMEBREW_PREFIX}/bin/helloworld #{HOMEBREW_PREFIX}/bin/helloworld
@ -119,27 +118,27 @@ describe Keg do
end end
context "with overwrite set to true" do context "with overwrite set to true" do
let(:options) { { overwrite: true } }
it "overwrite existing files" do it "overwrite existing files" do
touch dst touch dst
mode.overwrite = true expect(keg.link(**options)).to eq(3)
expect(keg.link(mode)).to eq(3)
expect(keg).to be_linked expect(keg).to be_linked
end end
it "overwrites broken symlinks" do it "overwrites broken symlinks" do
dst.make_symlink "nowhere" dst.make_symlink "nowhere"
mode.overwrite = true expect(keg.link(**options)).to eq(3)
expect(keg.link(mode)).to eq(3)
expect(keg).to be_linked expect(keg).to be_linked
end end
it "still supports dryrun" do it "still supports dryrun" do
touch dst touch dst
mode.overwrite = true
mode.dry_run = true options[:dry_run] = true
expect { expect {
expect(keg.link(mode)).to eq(0) expect(keg.link(**options)).to eq(0)
}.to output(<<~EOF).to_stdout }.to output(<<~EOF).to_stdout
#{dst} #{dst}
EOF EOF

View File

@ -26,7 +26,7 @@ module Homebrew
end end
formulae_to_install.each do |f| formulae_to_install.each do |f|
Migrator.migrate_if_needed(f, force: args.force?) Migrator.migrate_if_needed(f, force: args.force?, verbose: args.verbose?)
begin begin
upgrade_formula(f, args: args) upgrade_formula(f, args: args)
Cleanup.install_formula_clean!(f) Cleanup.install_formula_clean!(f)