Infer path to be added for requirements that search PATH

When a requirement is specified like:

  satisfy { which "foo" }

There is no reason that we should inject all of ENV.userpaths! into the
build environment. Instead, infer the directory to be added to PATH from
the Pathname that is returned.

This is another step towards condensing the "which program" requirements
down into a one-liner DSL element.
This commit is contained in:
Jack Nagel 2013-01-22 14:33:33 -06:00
parent b9e5f1229b
commit 3725f771de
3 changed files with 41 additions and 16 deletions

View File

@ -184,13 +184,12 @@ class Requirement
# Overriding #satisfied? is deprepcated. # Overriding #satisfied? is deprepcated.
# Pass a block or boolean to the satisfied DSL method instead. # Pass a block or boolean to the satisfied DSL method instead.
def satisfied? def satisfied?
self.class.satisfy.yielder do |proc| result = self.class.satisfy.yielder do |proc|
instance_eval(&proc) instance_eval(&proc)
end end
rescue NoMethodError
self.class.satisfy || false infer_env_modification(result)
rescue ArgumentError !!result
false
end end
# Overriding #fatal? is deprecated. # Overriding #fatal? is deprecated.
@ -217,29 +216,45 @@ class Requirement
message.hash message.hash
end end
private
def infer_env_modification(o)
case o
when Pathname
self.class.env do
unless ENV["PATH"].split(":").include?(o.parent.to_s)
append("PATH", o.parent, ":")
end
end
end
end
class << self class << self
def fatal(val=nil) def fatal(val=nil)
val.nil? ? @fatal : @fatal = val val.nil? ? @fatal : @fatal = val
end end
def satisfy(options={}, &block) def satisfy(options={}, &block)
if block_given?
@satisfied ||= Requirement::Satisfier.new(options, &block) @satisfied ||= Requirement::Satisfier.new(options, &block)
else
@satisfied ||= options
end
end end
end end
class Satisfier class Satisfier
def initialize(options={}, &block) def initialize(options={}, &block)
case options
when Hash
@options = { :build_env => true } @options = { :build_env => true }
@options.merge!(options) @options.merge!(options)
else
@satisfied = options
end
@proc = block @proc = block
end end
def yielder def yielder
if @options[:build_env] if instance_variable_defined?(:@satisfied)
@satisfied
elsif @options[:build_env]
require 'superenv' require 'superenv'
ENV.with_build_environment do ENV.with_build_environment do
ENV.userpaths! ENV.userpaths!

View File

@ -216,7 +216,6 @@ end
class MysqlInstalled < Requirement class MysqlInstalled < Requirement
fatal true fatal true
env :userpaths
satisfy { which 'mysql_config' } satisfy { which 'mysql_config' }
@ -238,7 +237,6 @@ end
class PostgresqlInstalled < Requirement class PostgresqlInstalled < Requirement
fatal true fatal true
env :userpaths
satisfy { which 'pg_config' } satisfy { which 'pg_config' }
@ -257,7 +255,6 @@ end
class TeXInstalled < Requirement class TeXInstalled < Requirement
fatal true fatal true
env :userpaths
satisfy { which('tex') || which('latex') } satisfy { which('tex') || which('latex') }

View File

@ -74,4 +74,17 @@ class RequirementTests < Test::Unit::TestCase
assert req.satisfied? assert req.satisfied?
end end
def test_infers_path_from_satisfy_result
which_path = Pathname.new("/foo/bar/baz")
req = Class.new(Requirement) do
satisfy { which_path }
end.new
ENV.expects(:with_build_environment).yields.returns(which_path)
ENV.expects(:userpaths!)
ENV.expects(:append).with("PATH", which_path.parent, ":")
req.modify_build_environment
end
end end