Separate formula conflicts from requirements
Closes Homebrew/homebrew#20357.
This commit is contained in:
parent
33cae6ac42
commit
8b9a3a560f
@ -174,11 +174,11 @@ class FormulaAuditor
|
|||||||
end
|
end
|
||||||
|
|
||||||
def audit_conflicts
|
def audit_conflicts
|
||||||
f.conflicts.each do |req|
|
f.conflicts.each do |c|
|
||||||
begin
|
begin
|
||||||
Formula.factory req.formula
|
Formula.factory(c.name)
|
||||||
rescue FormulaUnavailableError
|
rescue FormulaUnavailableError
|
||||||
problem "Can't find conflicting formula \"#{req.formula}\"."
|
problem "Can't find conflicting formula #{c.name.inspect}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -102,7 +102,7 @@ module Homebrew extend self
|
|||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|
||||||
conflicts = f.conflicts.map(&:formula).sort!
|
conflicts = f.conflicts.map(&:name).sort!
|
||||||
puts "Conflicts with: #{conflicts*', '}" unless conflicts.empty?
|
puts "Conflicts with: #{conflicts*', '}" unless conflicts.empty?
|
||||||
|
|
||||||
if f.rack.directory?
|
if f.rack.directory?
|
||||||
|
|||||||
@ -115,6 +115,38 @@ class UnsatisfiedRequirements < Homebrew::InstallationError
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class FormulaConflictError < Homebrew::InstallationError
|
||||||
|
attr_reader :f, :conflicts
|
||||||
|
|
||||||
|
def initialize(f, conflicts)
|
||||||
|
@f = f
|
||||||
|
@conflicts = conflicts
|
||||||
|
super f, message
|
||||||
|
end
|
||||||
|
|
||||||
|
def conflict_message(conflict)
|
||||||
|
message = []
|
||||||
|
message << " #{conflict.name}"
|
||||||
|
message << ": because #{conflict.reason}" if conflict.reason
|
||||||
|
message.join
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
message = []
|
||||||
|
message << "Cannot install #{f.name} because conflicting formulae are installed.\n"
|
||||||
|
message.concat conflicts.map { |c| conflict_message(c) } << ""
|
||||||
|
message << <<-EOS.undent
|
||||||
|
Please `brew unlink #{conflicts.map(&:name)*' '}` before continuing.
|
||||||
|
|
||||||
|
Unlinking removes a formula's symlinks from #{HOMEBREW_PREFIX}. You can
|
||||||
|
link the formula again after the install finishes. You can --force this
|
||||||
|
install, but the build may fail or cause obscure side-effects in the
|
||||||
|
resulting software.
|
||||||
|
EOS
|
||||||
|
message.join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class BuildError < Homebrew::InstallationError
|
class BuildError < Homebrew::InstallationError
|
||||||
attr_reader :exit_status, :command, :env
|
attr_reader :exit_status, :command, :env
|
||||||
|
|
||||||
|
|||||||
@ -491,7 +491,7 @@ class Formula
|
|||||||
end
|
end
|
||||||
|
|
||||||
def conflicts
|
def conflicts
|
||||||
requirements.grep(ConflictRequirement)
|
self.class.conflicts
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a list of Dependency objects in an installable order, which
|
# Returns a list of Dependency objects in an installable order, which
|
||||||
@ -764,8 +764,12 @@ class Formula
|
|||||||
@plist_manual = options[:manual]
|
@plist_manual = options[:manual]
|
||||||
end
|
end
|
||||||
|
|
||||||
def conflicts_with formula, opts={}
|
def conflicts
|
||||||
dependencies.add ConflictRequirement.new(formula, name, opts)
|
@conflicts ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
def conflicts_with name, opts={}
|
||||||
|
conflicts << FormulaConflict.new(name, opts[:because])
|
||||||
end
|
end
|
||||||
|
|
||||||
def skip_clean *paths
|
def skip_clean *paths
|
||||||
|
|||||||
@ -78,6 +78,8 @@ class FormulaInstaller
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
check_conflicts
|
||||||
|
|
||||||
unless ignore_deps
|
unless ignore_deps
|
||||||
perform_readline_hack
|
perform_readline_hack
|
||||||
check_requirements
|
check_requirements
|
||||||
@ -121,6 +123,17 @@ class FormulaInstaller
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_conflicts
|
||||||
|
return if ARGV.force?
|
||||||
|
|
||||||
|
conflicts = f.conflicts.reject do |c|
|
||||||
|
keg = Formula.factory(c.name).prefix
|
||||||
|
not keg.directory? && Keg.new(keg).linked?
|
||||||
|
end
|
||||||
|
|
||||||
|
raise FormulaConflictError.new(f, conflicts) unless conflicts.empty?
|
||||||
|
end
|
||||||
|
|
||||||
def check_requirements
|
def check_requirements
|
||||||
unsatisfied = ARGV.filter_for_dependencies do
|
unsatisfied = ARGV.filter_for_dependencies do
|
||||||
f.recursive_requirements do |dependent, req|
|
f.recursive_requirements do |dependent, req|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ require 'download_strategy'
|
|||||||
require 'checksum'
|
require 'checksum'
|
||||||
require 'version'
|
require 'version'
|
||||||
|
|
||||||
|
FormulaConflict = Struct.new(:name, :reason)
|
||||||
|
|
||||||
class SoftwareSpec
|
class SoftwareSpec
|
||||||
attr_reader :checksum, :mirrors, :specs
|
attr_reader :checksum, :mirrors, :specs
|
||||||
attr_reader :using # for auditing
|
attr_reader :using # for auditing
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
require 'requirement'
|
require 'requirement'
|
||||||
require 'requirements/conflict_requirement'
|
|
||||||
require 'requirements/language_module_dependency'
|
require 'requirements/language_module_dependency'
|
||||||
require 'requirements/x11_dependency'
|
require 'requirements/x11_dependency'
|
||||||
require 'requirements/mpi_dependency'
|
require 'requirements/mpi_dependency'
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
require 'requirement'
|
|
||||||
|
|
||||||
# This requirement added by the `conflicts_with` DSL method.
|
|
||||||
class ConflictRequirement < Requirement
|
|
||||||
attr_reader :formula
|
|
||||||
|
|
||||||
# The user can chose to force installation even in the face of conflicts.
|
|
||||||
fatal !ARGV.force?
|
|
||||||
|
|
||||||
def initialize formula, name, opts={}
|
|
||||||
@formula = formula
|
|
||||||
@name = name
|
|
||||||
@opts = opts
|
|
||||||
super([formula])
|
|
||||||
end
|
|
||||||
|
|
||||||
def message
|
|
||||||
message = "#{@name.downcase} cannot be installed alongside #{@formula}.\n"
|
|
||||||
message << "This is because #{@opts[:because]}\n" if @opts[:because]
|
|
||||||
message << <<-EOS.undent unless ARGV.force?
|
|
||||||
Please `brew unlink #{@formula}` before continuing. Unlinking removes
|
|
||||||
the formula's symlinks from #{HOMEBREW_PREFIX}. You can link the
|
|
||||||
formula again after the install finishes. You can --force this install
|
|
||||||
but the build may fail or cause obscure side-effects in the end-binary.
|
|
||||||
EOS
|
|
||||||
message
|
|
||||||
end
|
|
||||||
|
|
||||||
satisfy :build_env => false do
|
|
||||||
keg = Formula.factory(@formula).prefix
|
|
||||||
not keg.exist? && Keg.new(keg).linked?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Loading…
x
Reference in New Issue
Block a user