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