Skip to content
Snippets Groups Projects
Commit 873d9766 authored by Jack Nagel's avatar Jack Nagel
Browse files

Allow explicit conversion of requirements to deps

Fixes Homebrew/homebrew#19857.
parent 3937d2bb
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment