2013-01-26 20:05:39 -06:00
|
|
|
require 'dependable'
|
2013-06-03 15:08:47 -05:00
|
|
|
require 'dependency'
|
2014-07-03 14:50:57 -05:00
|
|
|
require 'dependencies'
|
2013-01-26 20:05:39 -06:00
|
|
|
require 'build_environment'
|
|
|
|
|
2014-09-20 16:07:55 +01:00
|
|
|
# :startdoc:
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
# A base class for non-formula requirements needed by formulae.
|
|
|
|
# A "fatal" requirement is one that will fail the build if it is not present.
|
|
|
|
# By default, Requirements are non-fatal.
|
|
|
|
class Requirement
|
|
|
|
include Dependable
|
|
|
|
|
2014-10-09 21:54:36 -05:00
|
|
|
attr_reader :tags, :name
|
|
|
|
alias_method :option_name, :name
|
2013-01-26 20:05:39 -06:00
|
|
|
|
2013-05-06 16:08:50 -05:00
|
|
|
def initialize(tags=[])
|
|
|
|
@tags = tags
|
2013-01-26 20:05:39 -06:00
|
|
|
@tags << :build if self.class.build
|
2013-02-12 16:24:30 -06:00
|
|
|
@name ||= infer_name
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
# The message to show when the requirement is not met.
|
|
|
|
def message; "" end
|
|
|
|
|
2013-02-07 18:58:26 -06:00
|
|
|
# Overriding #satisfied? is deprecated.
|
2013-06-02 17:14:42 -05:00
|
|
|
# Pass a block or boolean to the satisfy DSL method instead.
|
2013-01-26 20:05:39 -06:00
|
|
|
def satisfied?
|
2014-07-07 21:32:35 -05:00
|
|
|
result = self.class.satisfy.yielder { |p| instance_eval(&p) }
|
|
|
|
@satisfied_result = result
|
2013-01-26 20:05:39 -06:00
|
|
|
!!result
|
|
|
|
end
|
|
|
|
|
2014-03-28 14:52:23 +00:00
|
|
|
# Can overridden to optionally prevent a formula with this requirement from
|
|
|
|
# pouring a bottle.
|
|
|
|
def pour_bottle?; true end
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
# Overriding #fatal? is deprecated.
|
|
|
|
# Pass a boolean to the fatal DSL method instead.
|
|
|
|
def fatal?
|
|
|
|
self.class.fatal || false
|
|
|
|
end
|
|
|
|
|
2013-06-03 15:08:47 -05:00
|
|
|
def default_formula?
|
|
|
|
self.class.default_formula || false
|
|
|
|
end
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
# Overriding #modify_build_environment is deprecated.
|
|
|
|
# Pass a block to the the env DSL method instead.
|
2013-06-24 10:39:00 -05:00
|
|
|
# Note: #satisfied? should be called before invoking this method
|
|
|
|
# as the env modifications may depend on its side effects.
|
2013-01-26 20:05:39 -06:00
|
|
|
def modify_build_environment
|
2014-07-07 21:32:35 -05:00
|
|
|
instance_eval(&env_proc) if env_proc
|
|
|
|
|
|
|
|
# XXX If the satisfy block returns a Pathname, then make sure that it
|
|
|
|
# remains available on the PATH. This makes requirements like
|
|
|
|
# satisfy { which("executable") }
|
|
|
|
# work, even under superenv where "executable" wouldn't normally be on the
|
|
|
|
# PATH.
|
|
|
|
# This is undocumented magic and it should be removed, but we need to add
|
|
|
|
# a way to declare path-based requirements that work with superenv first.
|
|
|
|
if Pathname === @satisfied_result
|
|
|
|
parent = @satisfied_result.parent
|
|
|
|
unless ENV["PATH"].split(File::PATH_SEPARATOR).include?(parent.to_s)
|
|
|
|
ENV.append_path("PATH", parent)
|
|
|
|
end
|
|
|
|
end
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def env
|
2014-07-07 21:32:35 -05:00
|
|
|
self.class.env
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
2014-07-07 21:32:35 -05:00
|
|
|
def env_proc
|
|
|
|
self.class.env_proc
|
|
|
|
end
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
def eql?(other)
|
2013-06-27 01:18:32 -05:00
|
|
|
instance_of?(other.class) && name == other.name && tags == other.tags
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def hash
|
2013-01-29 22:52:10 -06:00
|
|
|
[name, *tags].hash
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
2013-06-07 22:24:36 -05:00
|
|
|
def inspect
|
2014-07-01 15:07:06 -05:00
|
|
|
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>"
|
2013-06-07 22:24:36 -05:00
|
|
|
end
|
|
|
|
|
2013-06-03 15:08:47 -05:00
|
|
|
def to_dependency
|
|
|
|
f = self.class.default_formula
|
|
|
|
raise "No default formula defined for #{inspect}" if f.nil?
|
2014-02-27 14:22:43 -06:00
|
|
|
Dependency.new(f, tags, method(:modify_build_environment), name)
|
2013-06-03 15:08:47 -05:00
|
|
|
end
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
private
|
|
|
|
|
2013-02-12 16:24:30 -06:00
|
|
|
def infer_name
|
2014-06-12 16:12:21 -05:00
|
|
|
klass = self.class.name || self.class.to_s
|
2013-02-12 16:24:30 -06:00
|
|
|
klass.sub!(/(Dependency|Requirement)$/, '')
|
2013-02-12 16:28:50 -06:00
|
|
|
klass.sub!(/^(\w+::)*/, '')
|
2013-02-12 16:24:30 -06:00
|
|
|
klass.downcase
|
|
|
|
end
|
|
|
|
|
2013-08-19 12:33:00 -05:00
|
|
|
def which(cmd)
|
|
|
|
super(cmd, ORIGINAL_PATHS.join(File::PATH_SEPARATOR))
|
|
|
|
end
|
|
|
|
|
2014-09-20 16:07:55 +01:00
|
|
|
# :stopdoc:
|
|
|
|
|
2013-01-26 20:05:39 -06:00
|
|
|
class << self
|
2014-07-07 20:16:51 -05:00
|
|
|
include BuildEnvironmentDSL
|
|
|
|
|
2014-07-07 21:32:35 -05:00
|
|
|
attr_reader :env_proc
|
2014-05-30 18:11:25 -05:00
|
|
|
attr_rw :fatal, :default_formula
|
|
|
|
# build is deprecated, use `depends_on <requirement> => :build` instead
|
|
|
|
attr_rw :build
|
2013-01-26 20:05:39 -06:00
|
|
|
|
|
|
|
def satisfy(options={}, &block)
|
|
|
|
@satisfied ||= Requirement::Satisfier.new(options, &block)
|
|
|
|
end
|
2014-07-07 21:32:35 -05:00
|
|
|
|
|
|
|
def env(*settings, &block)
|
|
|
|
if block_given?
|
|
|
|
@env_proc = block
|
|
|
|
else
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
class Satisfier
|
2014-08-14 19:58:17 -05:00
|
|
|
def initialize(options, &block)
|
2013-01-26 20:05:39 -06:00
|
|
|
case options
|
|
|
|
when Hash
|
|
|
|
@options = { :build_env => true }
|
|
|
|
@options.merge!(options)
|
|
|
|
else
|
|
|
|
@satisfied = options
|
|
|
|
end
|
|
|
|
@proc = block
|
|
|
|
end
|
|
|
|
|
|
|
|
def yielder
|
|
|
|
if instance_variable_defined?(:@satisfied)
|
|
|
|
@satisfied
|
|
|
|
elsif @options[:build_env]
|
2014-07-02 21:24:01 -05:00
|
|
|
require "extend/ENV"
|
2013-08-19 12:33:00 -05:00
|
|
|
ENV.with_build_environment { yield @proc }
|
2013-01-26 20:05:39 -06:00
|
|
|
else
|
|
|
|
yield @proc
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-01-30 17:55:04 -06:00
|
|
|
|
2013-06-03 15:08:46 -05:00
|
|
|
class << self
|
|
|
|
# Expand the requirements of dependent recursively, optionally yielding
|
|
|
|
# [dependent, req] pairs to allow callers to apply arbitrary filters to
|
|
|
|
# the list.
|
|
|
|
# The default filter, which is applied when a block is not given, omits
|
|
|
|
# optionals and recommendeds based on what the dependent has asked for.
|
|
|
|
def expand(dependent, &block)
|
2014-07-03 14:50:57 -05:00
|
|
|
reqs = Requirements.new
|
2013-06-03 15:08:46 -05:00
|
|
|
|
|
|
|
formulae = dependent.recursive_dependencies.map(&:to_formula)
|
|
|
|
formulae.unshift(dependent)
|
|
|
|
|
2013-06-25 10:12:14 -05:00
|
|
|
formulae.each do |f|
|
|
|
|
f.requirements.each do |req|
|
|
|
|
if prune?(f, req, &block)
|
2013-06-03 15:08:46 -05:00
|
|
|
next
|
|
|
|
else
|
|
|
|
reqs << req
|
2013-01-30 17:55:04 -06:00
|
|
|
end
|
|
|
|
end
|
2013-06-03 15:08:46 -05:00
|
|
|
end
|
2013-01-30 17:55:04 -06:00
|
|
|
|
2013-06-03 15:08:46 -05:00
|
|
|
reqs
|
2013-01-30 17:55:04 -06:00
|
|
|
end
|
|
|
|
|
2013-06-03 15:08:46 -05:00
|
|
|
def prune?(dependent, req, &block)
|
|
|
|
catch(:prune) do
|
|
|
|
if block_given?
|
|
|
|
yield dependent, req
|
|
|
|
elsif req.optional? || req.recommended?
|
2013-12-09 14:36:10 -06:00
|
|
|
prune unless dependent.build.with?(req)
|
2013-06-03 15:08:46 -05:00
|
|
|
end
|
|
|
|
end
|
2013-01-30 17:55:04 -06:00
|
|
|
end
|
|
|
|
|
2013-06-03 15:08:46 -05:00
|
|
|
# Used to prune requirements when calling expand with a block.
|
|
|
|
def prune
|
|
|
|
throw(:prune, true)
|
|
|
|
end
|
2013-01-30 17:55:04 -06:00
|
|
|
end
|
2013-01-26 20:05:39 -06:00
|
|
|
end
|