Make reinstall transaction safe.
* Aborting during reinstall will now restore the originally installed
keg.
- Change install code to pass on CannotInstallFormulaError exception
to caller so it can be reused in reinstall.
* Add "--force-new-install" flag to force installing a new formula.
Closes Homebrew/homebrew#22190.
Signed-off-by: Samuel John <github@SamuelJohn.de>
This commit is contained in:
parent
e278135156
commit
8aae1dac7b
@ -19,7 +19,13 @@ module Homebrew extend self
|
|||||||
end unless ARGV.force?
|
end unless ARGV.force?
|
||||||
|
|
||||||
perform_preinstall_checks
|
perform_preinstall_checks
|
||||||
ARGV.formulae.each { |f| install_formula(f) }
|
ARGV.formulae.each do |f|
|
||||||
|
begin
|
||||||
|
install_formula(f)
|
||||||
|
rescue CannotInstallFormulaError => e
|
||||||
|
ofail e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_ppc
|
def check_ppc
|
||||||
@ -80,7 +86,6 @@ module Homebrew extend self
|
|||||||
# another formula. In that case, don't generate an error, just move on.
|
# another formula. In that case, don't generate an error, just move on.
|
||||||
rescue FormulaAlreadyInstalledError => e
|
rescue FormulaAlreadyInstalledError => e
|
||||||
opoo e.message
|
opoo e.message
|
||||||
rescue CannotInstallFormulaError => e
|
# Ignore CannotInstallFormulaError and let caller handle it.
|
||||||
ofail e.message
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
require 'cmd/uninstall'
|
|
||||||
require 'cmd/install'
|
require 'cmd/install'
|
||||||
|
|
||||||
module Homebrew extend self
|
module Homebrew extend self
|
||||||
@ -6,9 +5,6 @@ module Homebrew extend self
|
|||||||
# At first save the named formulae and remove them from ARGV
|
# At first save the named formulae and remove them from ARGV
|
||||||
named = ARGV.named
|
named = ARGV.named
|
||||||
ARGV.delete_if { |arg| named.include? arg }
|
ARGV.delete_if { |arg| named.include? arg }
|
||||||
# We add --force because then uninstall always succeeds and so reinstall
|
|
||||||
# works for formulae not yet installed.
|
|
||||||
ARGV << "--force"
|
|
||||||
clean_ARGV = ARGV.clone
|
clean_ARGV = ARGV.clone
|
||||||
|
|
||||||
# Add the used_options for each named formula separately so
|
# Add the used_options for each named formula separately so
|
||||||
@ -21,13 +17,65 @@ module Homebrew extend self
|
|||||||
if tab.built_as_bottle and not tab.poured_from_bottle
|
if tab.built_as_bottle and not tab.poured_from_bottle
|
||||||
ARGV << '--build-bottle'
|
ARGV << '--build-bottle'
|
||||||
end
|
end
|
||||||
# Todo: Be as smart as upgrade to restore the old state if reinstall fails.
|
|
||||||
self.uninstall
|
canonical_name = Formula.canonical_name(name)
|
||||||
# Don't display --force in options; user didn't request it so a bit scary.
|
formula = Formula.factory(canonical_name)
|
||||||
options_only = ARGV.options_only
|
|
||||||
options_only.delete "--force"
|
if not formula.installed?
|
||||||
oh1 "Reinstalling #{name} #{options_only*' '}"
|
if force_new_install?
|
||||||
self.install
|
oh1 "Force installing new formula: #{name}"
|
||||||
|
self.install_formula formula
|
||||||
|
next
|
||||||
|
else
|
||||||
|
raise <<-EOS.undent
|
||||||
|
#{formula} is not installed. Please install it first or use
|
||||||
|
"--force-new-install" flag.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
linked_keg_ref = HOMEBREW_REPOSITORY/'opt'/canonical_name
|
||||||
|
keg = Keg.new(linked_keg_ref.realpath)
|
||||||
|
|
||||||
|
begin
|
||||||
|
oh1 "Reinstalling #{name} #{ARGV.options_only*' '}"
|
||||||
|
quarantine keg
|
||||||
|
self.install_formula formula
|
||||||
|
rescue Exception => e
|
||||||
|
ofail e.message unless e.message.empty?
|
||||||
|
restore_quarantine keg, formula
|
||||||
|
raise 'Reinstallation abort.'
|
||||||
|
else
|
||||||
|
remove_quarantine keg
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def force_new_install?
|
||||||
|
ARGV.include? '--force-new-install'
|
||||||
|
end
|
||||||
|
|
||||||
|
def quarantine keg
|
||||||
|
keg.unlink
|
||||||
|
|
||||||
|
path = Pathname.new(keg.to_s)
|
||||||
|
path.rename quarantine_path(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def restore_quarantine keg, formula
|
||||||
|
path = Pathname.new(quarantine_path(keg))
|
||||||
|
if path.directory?
|
||||||
|
path.rename keg.to_s
|
||||||
|
keg.link unless formula.keg_only?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_quarantine keg
|
||||||
|
path = Pathname.new(quarantine_path(keg))
|
||||||
|
path.rmtree
|
||||||
|
end
|
||||||
|
|
||||||
|
def quarantine_path path
|
||||||
|
path.to_s + '.reinstall'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user