FormulaInstaller: allow formulae to pass options to deps
Formulae can now pass build options to dependencies. The following syntax is supported: depends_on 'foo' => 'with-bar' depends_on 'foo' => ['with-bar', 'with-baz'] If a dependency is already installed but lacks the required build options, an exception is raised. Eventually we may be able to just stash the existing keg and reinstall it with the combined set of used_options and passed options, but enabling that is left for another day.
This commit is contained in:
parent
951872c4be
commit
046d802d09
@ -3,7 +3,7 @@ require 'options'
|
||||
# This class holds the build-time options defined for a Formula,
|
||||
# and provides named access to those options during install.
|
||||
class BuildOptions
|
||||
attr_writer :args
|
||||
attr_accessor :args
|
||||
include Enumerable
|
||||
|
||||
def initialize args
|
||||
|
||||
@ -138,7 +138,7 @@ module Dependable
|
||||
end
|
||||
|
||||
def options
|
||||
tags.reject { |tag| RESERVED_TAGS.include? tag }.map { |tag| '--'+tag.to_s }
|
||||
Options.new((tags - RESERVED_TAGS).map { |o| Option.new(o) })
|
||||
end
|
||||
end
|
||||
|
||||
@ -171,13 +171,24 @@ class Dependency
|
||||
end
|
||||
|
||||
def to_formula
|
||||
Formula.factory(name)
|
||||
f = Formula.factory(name)
|
||||
# Add this dependency's options to the formula's build args
|
||||
f.build.args = f.build.args.concat(options)
|
||||
f
|
||||
end
|
||||
|
||||
def installed?
|
||||
to_formula.installed?
|
||||
end
|
||||
|
||||
def requested?
|
||||
ARGV.formulae.include?(to_formula) rescue false
|
||||
end
|
||||
|
||||
def universal!
|
||||
tags << 'universal' if to_formula.build.has_option? 'universal'
|
||||
end
|
||||
|
||||
# Expand the dependencies of f recursively, optionally yielding
|
||||
# [f, dep] to allow callers to apply arbitrary filters to the list.
|
||||
# The default filter, which is used when a block is not supplied,
|
||||
|
||||
@ -8,6 +8,7 @@ require 'caveats'
|
||||
class FormulaInstaller
|
||||
attr :f
|
||||
attr :tab, true
|
||||
attr :options, true
|
||||
attr :show_summary_heading, true
|
||||
attr :ignore_deps, true
|
||||
attr :show_header, true
|
||||
@ -116,20 +117,6 @@ class FormulaInstaller
|
||||
end
|
||||
end
|
||||
|
||||
def dep_needed? dep
|
||||
dep_f = dep.to_formula
|
||||
if dep_f.installed?
|
||||
# If the dep is already installed, skip it.
|
||||
false
|
||||
elsif install_bottle and dep.build?
|
||||
# We skip build-time deps when installing bottles.
|
||||
false
|
||||
else
|
||||
# Otherwise, we need to install it.
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def effective_deps
|
||||
@deps ||= begin
|
||||
deps = Set.new
|
||||
@ -138,15 +125,34 @@ class FormulaInstaller
|
||||
# any influential flags (--HEAD, --devel, etc.) the user has passed
|
||||
# when we check the installed status.
|
||||
requested_deps = f.recursive_dependencies.select do |dep|
|
||||
dep_f = dep.to_formula
|
||||
dep_f.requested? and not dep_f.installed?
|
||||
dep.requested? && !dep.installed?
|
||||
end
|
||||
|
||||
# Otherwise, we filter these influential flags so that they do not
|
||||
# affect installation prefixes and other properties when we decide
|
||||
# whether or not the dep is needed.
|
||||
necessary_deps = ARGV.filter_for_dependencies do
|
||||
f.recursive_dependencies.select { |d| dep_needed? d }
|
||||
f.recursive_dependencies do |dependent, dep|
|
||||
if dep.optional? || dep.recommended?
|
||||
Dependency.prune unless dependent.build.with?(dep.name)
|
||||
elsif dep.build?
|
||||
Dependency.prune if pour_bottle?
|
||||
end
|
||||
|
||||
dep.universal! if f.build.universal?
|
||||
|
||||
dep_f = dep.to_formula
|
||||
dep_tab = Tab.for_formula(dep)
|
||||
missing = dep.options - dep_tab.used_options
|
||||
|
||||
if dep.installed?
|
||||
if missing.empty?
|
||||
Dependency.prune
|
||||
else
|
||||
raise "#{f} dependency #{dep} not installed with:\n #{missing*', '}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
deps.merge(requested_deps)
|
||||
@ -171,12 +177,14 @@ class FormulaInstaller
|
||||
|
||||
def install_dependency dep
|
||||
dep_tab = Tab.for_formula(dep)
|
||||
dep_options = dep.options
|
||||
dep = dep.to_formula
|
||||
|
||||
outdated_keg = Keg.new(dep.linked_keg.realpath) rescue nil
|
||||
|
||||
fi = FormulaInstaller.new(dep)
|
||||
fi.tab = dep_tab
|
||||
fi.options = dep_options
|
||||
fi.ignore_deps = true
|
||||
fi.show_header = false
|
||||
oh1 "Installing #{f} dependency: #{Tty.green}#{dep}#{Tty.reset}"
|
||||
@ -258,7 +266,10 @@ class FormulaInstaller
|
||||
# FIXME: enforce the download of the non-bottled package
|
||||
# in the spawned Ruby process.
|
||||
args << '--build-from-source'
|
||||
args.uniq! # Just in case some dupes were added
|
||||
# Add any options that were passed into this FormulaInstaller instance.
|
||||
# Usually this represents options being passed by a dependent formula.
|
||||
args.concat options
|
||||
args.uniq!
|
||||
|
||||
fork do
|
||||
begin
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
require 'testing_env'
|
||||
require 'dependencies'
|
||||
require 'options'
|
||||
|
||||
class DependableTests < Test::Unit::TestCase
|
||||
def setup
|
||||
@ -8,7 +9,7 @@ class DependableTests < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_options
|
||||
assert_equal %w{--foo --bar}.sort, @dep.options.sort
|
||||
assert_equal %w{--foo --bar}.sort, @dep.options.as_flags.sort
|
||||
end
|
||||
|
||||
def test_interrogation
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
require 'testing_env'
|
||||
require 'dependencies'
|
||||
require 'options'
|
||||
require 'extend/set'
|
||||
|
||||
module DependencyCollectorTestExtension
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user