Stop supporting `brew install --force'
Rationale: it breaks stuff. You should not be able to install over something already installed *and* linked. brew now prompts you to unlink the existing linked keg first. I came to fix this because I discovered that `brew install foo` works without --force provided foo's formula version is different to that which is installed and linked. I'm not sure if this was intentionally broken, but it led to at least two tickets I found where people were getting crazy issues trying to install over the top of already installed previous versions. So I also fixed a whole category of other issues, mostly by moving error handling into FormulaInstaller. Now error's can be caught in Homebrew.install and handled on a formula-by-formula basis. I will next port this behaviour to upgrade.
This commit is contained in:
parent
15a70c36d0
commit
76aa0a62f3
@ -11,10 +11,6 @@ module Homebrew extend self
|
|||||||
raise "No available formula for #{name}\n#{msg}" if msg
|
raise "No available formula for #{name}\n#{msg}" if msg
|
||||||
end unless ARGV.force?
|
end unless ARGV.force?
|
||||||
|
|
||||||
ARGV.formulae.each do |f|
|
|
||||||
opoo "#{f} already installed" if f.linked_keg.directory?
|
|
||||||
end unless ARGV.force?
|
|
||||||
|
|
||||||
if Process.uid.zero? and not File.stat(HOMEBREW_BREW_FILE).uid.zero?
|
if Process.uid.zero? and not File.stat(HOMEBREW_BREW_FILE).uid.zero?
|
||||||
# note we only abort if Homebrew is *not* installed as sudo and the user
|
# note we only abort if Homebrew is *not* installed as sudo and the user
|
||||||
# calls brew as root. The fix is to chown brew to root.
|
# calls brew as root. The fix is to chown brew to root.
|
||||||
@ -84,29 +80,16 @@ module Homebrew extend self
|
|||||||
unless formulae.empty?
|
unless formulae.empty?
|
||||||
perform_preinstall_checks
|
perform_preinstall_checks
|
||||||
formulae.each do |f|
|
formulae.each do |f|
|
||||||
# Check formula status and skip if necessary---a formula passed on the
|
|
||||||
# command line may have been installed to satisfy a dependency.
|
|
||||||
next if f.installed? unless ARGV.force?
|
|
||||||
|
|
||||||
# Building head-only without --HEAD is an error
|
|
||||||
if not ARGV.build_head? and f.standard.nil?
|
|
||||||
raise "This is a head-only formula; install with `brew install --HEAD #{f.name}`"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Building stable-only with --HEAD is an error
|
|
||||||
if ARGV.build_head? and f.unstable.nil?
|
|
||||||
raise "No head is defined for #{f.name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
fi = FormulaInstaller.new(f)
|
fi = FormulaInstaller.new(f)
|
||||||
fi.install
|
fi.install
|
||||||
fi.caveats
|
fi.caveats
|
||||||
fi.finish
|
fi.finish
|
||||||
rescue FormulaAlreadyInstalledError => e
|
rescue CannotInstallFormulaError => e
|
||||||
opoo e.message
|
onoe e.message
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -42,10 +42,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class FormulaAlreadyInstalledError < Homebrew::InstallationError
|
class CannotInstallFormulaError < RuntimeError
|
||||||
def message
|
|
||||||
"Formula already installed: #{formula}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class FormulaInstallationAlreadyAttemptedError < Homebrew::InstallationError
|
class FormulaInstallationAlreadyAttemptedError < Homebrew::InstallationError
|
||||||
|
|||||||
@ -16,10 +16,40 @@ class FormulaInstaller
|
|||||||
@show_header = true
|
@show_header = true
|
||||||
@ignore_deps = ARGV.include? '--ignore-dependencies' || ARGV.interactive?
|
@ignore_deps = ARGV.include? '--ignore-dependencies' || ARGV.interactive?
|
||||||
@install_bottle = !ARGV.build_from_source? && ff.bottle_up_to_date?
|
@install_bottle = !ARGV.build_from_source? && ff.bottle_up_to_date?
|
||||||
|
|
||||||
|
check_install_sanity
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_install_sanity
|
||||||
|
if f.installed?
|
||||||
|
raise CannotInstallFormulaError, "#{f}-#{f.version} already installed"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Building head-only without --HEAD is an error
|
||||||
|
if not ARGV.build_head? and f.standard.nil?
|
||||||
|
raise CannotInstallFormulaError, <<-EOS.undent
|
||||||
|
#{f} is a head-only formula
|
||||||
|
Install with `brew install --HEAD #{f.name}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
# Building stable-only with --HEAD is an error
|
||||||
|
if ARGV.build_head? and f.unstable.nil?
|
||||||
|
raise CannotInstallFormulaError, "No head is defined for #{f.name}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def install
|
def install
|
||||||
raise FormulaAlreadyInstalledError, f if f.installed? and not ARGV.force?
|
# not in initialize so upgrade can unlink the active keg before calling this
|
||||||
|
# function but after instantiating this class so that it can avoid having to
|
||||||
|
# relink the active keg if possible (because it is slow).
|
||||||
|
if f.linked_keg.directory?
|
||||||
|
# some other version is already installed *and* linked
|
||||||
|
raise CannotInstallFormulaError, <<-EOS.undent
|
||||||
|
#{f}-#{f.linked_keg.realpath.basename} already installed
|
||||||
|
To install this version, first `brew unlink #{f}'
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
unless ignore_deps
|
unless ignore_deps
|
||||||
f.check_external_deps
|
f.check_external_deps
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user