| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | require 'dependable' | 
					
						
							|  |  |  | require 'build_environment' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  |   extend BuildEnvironmentDSL | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-27 15:41:45 -06:00
										 |  |  |   attr_reader :tags, :name | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def initialize(*tags) | 
					
						
							|  |  |  |     @tags = tags.flatten.compact | 
					
						
							|  |  |  |     @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-01-26 20:05:39 -06:00
										 |  |  |   # Pass a block or boolean to the satisfied DSL method instead. | 
					
						
							|  |  |  |   def satisfied? | 
					
						
							|  |  |  |     result = self.class.satisfy.yielder do |proc| | 
					
						
							|  |  |  |       instance_eval(&proc) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     infer_env_modification(result) | 
					
						
							|  |  |  |     !!result | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Overriding #fatal? is deprecated. | 
					
						
							|  |  |  |   # Pass a boolean to the fatal DSL method instead. | 
					
						
							|  |  |  |   def fatal? | 
					
						
							|  |  |  |     self.class.fatal || false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Overriding #modify_build_environment is deprecated. | 
					
						
							|  |  |  |   # Pass a block to the the env DSL method instead. | 
					
						
							|  |  |  |   def modify_build_environment | 
					
						
							|  |  |  |     satisfied? and env.modify_build_environment(self) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def env | 
					
						
							|  |  |  |     @env ||= self.class.env | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def eql?(other) | 
					
						
							| 
									
										
										
										
											2013-01-29 22:52:10 -06:00
										 |  |  |     instance_of?(other.class) && hash == other.hash | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-12 16:24:30 -06:00
										 |  |  |   def infer_name | 
					
						
							|  |  |  |     klass = self.class.to_s | 
					
						
							|  |  |  |     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-01-26 20:05:39 -06:00
										 |  |  |   def infer_env_modification(o) | 
					
						
							|  |  |  |     case o | 
					
						
							|  |  |  |     when Pathname | 
					
						
							|  |  |  |       self.class.env do | 
					
						
							|  |  |  |         unless ENV["PATH"].split(":").include?(o.parent.to_s) | 
					
						
							| 
									
										
										
										
											2013-04-01 12:05:57 -05:00
										 |  |  |           ENV.append("PATH", o.parent, ":") | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class << self | 
					
						
							|  |  |  |     def fatal(val=nil) | 
					
						
							|  |  |  |       val.nil? ? @fatal : @fatal = val | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def build(val=nil) | 
					
						
							|  |  |  |       val.nil? ? @build : @build = val | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def satisfy(options={}, &block) | 
					
						
							|  |  |  |       @satisfied ||= Requirement::Satisfier.new(options, &block) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class Satisfier | 
					
						
							|  |  |  |     def initialize(options={}, &block) | 
					
						
							|  |  |  |       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] | 
					
						
							|  |  |  |         require 'superenv' | 
					
						
							|  |  |  |         ENV.with_build_environment do | 
					
						
							|  |  |  |           ENV.userpaths! | 
					
						
							|  |  |  |           yield @proc | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         yield @proc | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-01-30 17:55:04 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # 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 self.expand(dependent, &block) | 
					
						
							|  |  |  |     reqs = ComparableSet.new | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     formulae = dependent.recursive_dependencies.map(&:to_formula) | 
					
						
							|  |  |  |     formulae.unshift(dependent) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     formulae.map(&:requirements).each do |requirements| | 
					
						
							|  |  |  |       requirements.each do |req| | 
					
						
							|  |  |  |         prune = catch(:prune) do | 
					
						
							|  |  |  |           if block_given? | 
					
						
							|  |  |  |             yield dependent, req | 
					
						
							|  |  |  |           elsif req.optional? || req.recommended? | 
					
						
							|  |  |  |             Requirement.prune unless dependent.build.with?(req.name) | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         next if prune | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         reqs << req | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We special case handling of X11Dependency and its subclasses to | 
					
						
							|  |  |  |     # ensure the correct dependencies are present in the final list. | 
					
						
							|  |  |  |     # If an X11Dependency is present after filtering, we eliminate | 
					
						
							|  |  |  |     # all X11Dependency::Proxy objects from the list. If there aren't | 
					
						
							|  |  |  |     # any X11Dependency objects, then we eliminate all but one of the | 
					
						
							|  |  |  |     # proxy objects. | 
					
						
							|  |  |  |     proxy = unless reqs.any? { |r| r.instance_of?(X11Dependency) } | 
					
						
							|  |  |  |       reqs.find { |r| r.kind_of?(X11Dependency::Proxy) } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reqs.reject! do |r| | 
					
						
							|  |  |  |       r.kind_of?(X11Dependency::Proxy) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reqs << proxy unless proxy.nil? | 
					
						
							|  |  |  |     reqs | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Used to prune requirements when calling expand with a block. | 
					
						
							|  |  |  |   def self.prune | 
					
						
							|  |  |  |     throw(:prune, true) | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | end |