Allow explicit conversion of requirements to deps
Fixes Homebrew/homebrew#19857.
This commit is contained in:
parent
3937d2bb84
commit
873d9766ae
@ -59,8 +59,10 @@ class Build
|
||||
|
||||
def initialize(f)
|
||||
@f = f
|
||||
# Expand requirements before dependencies, as requirements
|
||||
# may add dependencies if a default formula is activated.
|
||||
@reqs = expand_reqs
|
||||
@deps = expand_deps
|
||||
@reqs = f.recursive_requirements
|
||||
end
|
||||
|
||||
def post_superenv_hacks
|
||||
@ -77,6 +79,19 @@ class Build
|
||||
not ARGV.include? '--env=super'
|
||||
end
|
||||
|
||||
def expand_reqs
|
||||
f.recursive_requirements do |dependent, req|
|
||||
if (req.optional? || req.recommended?) && dependent.build.without?(req.name)
|
||||
Requirement.prune
|
||||
elsif req.build? && dependent != f
|
||||
Requirement.prune
|
||||
elsif req.satisfied? && req.default_formula? && (dep = req.to_dependency).installed?
|
||||
dependent.deps << dep
|
||||
Requirement.prune
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def expand_deps
|
||||
f.recursive_dependencies do |dependent, dep|
|
||||
if dep.optional? || dep.recommended?
|
||||
@ -84,18 +99,18 @@ class Build
|
||||
elsif dep.build?
|
||||
Dependency.prune unless dependent == f
|
||||
end
|
||||
end.map(&:to_formula)
|
||||
end
|
||||
end
|
||||
|
||||
def install
|
||||
keg_only_deps = deps.select(&:keg_only?)
|
||||
keg_only_deps = deps.map(&:to_formula).select(&:keg_only?)
|
||||
|
||||
pre_superenv_hacks
|
||||
require 'superenv'
|
||||
|
||||
deps.each do |dep|
|
||||
opt = HOMEBREW_PREFIX/:opt/dep
|
||||
fixopt(dep) unless opt.directory? or ARGV.ignore_deps?
|
||||
fixopt(dep.to_formula) unless opt.directory? or ARGV.ignore_deps?
|
||||
end
|
||||
|
||||
if superenv?
|
||||
@ -105,9 +120,11 @@ class Build
|
||||
ENV.setup_build_environment
|
||||
post_superenv_hacks
|
||||
reqs.each(&:modify_build_environment)
|
||||
deps.each(&:modify_build_environment)
|
||||
else
|
||||
ENV.setup_build_environment
|
||||
reqs.each(&:modify_build_environment)
|
||||
deps.each(&:modify_build_environment)
|
||||
|
||||
keg_only_deps.each do |dep|
|
||||
opt = dep.opt_prefix
|
||||
|
||||
@ -5,6 +5,7 @@ class Dependency
|
||||
include Dependable
|
||||
|
||||
attr_reader :name, :tags
|
||||
attr_accessor :env_proc
|
||||
|
||||
def initialize(name, tags=[])
|
||||
@name = name
|
||||
@ -54,6 +55,10 @@ class Dependency
|
||||
tags << 'universal' if to_formula.build.has_option? 'universal'
|
||||
end
|
||||
|
||||
def modify_build_environment
|
||||
env_proc.call unless env_proc.nil?
|
||||
end
|
||||
|
||||
class << self
|
||||
# Expand the dependencies of dependent recursively, optionally yielding
|
||||
# [dependent, dep] pairs to allow callers to apply arbitrary filters to
|
||||
|
||||
@ -120,13 +120,16 @@ class FormulaInstaller
|
||||
def check_requirements
|
||||
unsatisfied = ARGV.filter_for_dependencies do
|
||||
f.recursive_requirements do |dependent, req|
|
||||
if req.optional? || req.recommended?
|
||||
Requirement.prune unless dependent.build.with?(req.name)
|
||||
elsif req.build?
|
||||
Requirement.prune if install_bottle?(dependent)
|
||||
if (req.optional? || req.recommended?) && dependent.build.without?(req.name)
|
||||
Requirement.prune
|
||||
elsif req.build? && install_bottle?(dependent)
|
||||
Requirement.prune
|
||||
elsif req.satisfied?
|
||||
Requirement.prune
|
||||
elsif req.default_formula?
|
||||
dependent.deps << req.to_dependency
|
||||
Requirement.prune
|
||||
end
|
||||
|
||||
Requirement.prune if req.satisfied?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
require 'dependable'
|
||||
require 'dependency'
|
||||
require 'build_environment'
|
||||
|
||||
# A base class for non-formula requirements needed by formulae.
|
||||
@ -36,6 +37,10 @@ class Requirement
|
||||
self.class.fatal || false
|
||||
end
|
||||
|
||||
def default_formula?
|
||||
self.class.default_formula || false
|
||||
end
|
||||
|
||||
# Overriding #modify_build_environment is deprecated.
|
||||
# Pass a block to the the env DSL method instead.
|
||||
def modify_build_environment
|
||||
@ -54,6 +59,14 @@ class Requirement
|
||||
[name, *tags].hash
|
||||
end
|
||||
|
||||
def to_dependency
|
||||
f = self.class.default_formula
|
||||
raise "No default formula defined for #{inspect}" if f.nil?
|
||||
dep = Dependency.new(f, tags)
|
||||
dep.env_proc = method(:modify_build_environment)
|
||||
dep
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def infer_name
|
||||
@ -136,11 +149,6 @@ class Requirement
|
||||
requirements.each do |req|
|
||||
if prune?(dependent, req, &block)
|
||||
next
|
||||
# TODO: Do this in a cleaner way, perhaps with another type of
|
||||
# dependency type.
|
||||
elsif req.class.default_formula
|
||||
dependent.class.depends_on(req.class.default_formula)
|
||||
next
|
||||
else
|
||||
reqs << req
|
||||
end
|
||||
|
||||
@ -96,4 +96,28 @@ class RequirementTests < Test::Unit::TestCase
|
||||
ensure
|
||||
klass.send(:remove_const, const) if klass.const_defined?(const)
|
||||
end
|
||||
|
||||
def test_dsl_default_formula
|
||||
req = Class.new(Requirement) { default_formula 'foo' }.new
|
||||
assert req.default_formula?
|
||||
end
|
||||
|
||||
def test_to_dependency
|
||||
req = Class.new(Requirement) { default_formula 'foo' }.new
|
||||
assert_equal Dependency.new('foo'), req.to_dependency
|
||||
end
|
||||
|
||||
def test_to_dependency_calls_requirement_modify_build_environment
|
||||
error = Class.new(StandardError)
|
||||
|
||||
req = Class.new(Requirement) do
|
||||
default_formula 'foo'
|
||||
satisfy { true }
|
||||
env { raise error }
|
||||
end.new
|
||||
|
||||
assert_raises(error) do
|
||||
req.to_dependency.modify_build_environment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user