| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  | ## This file defines dependencies and requirements. | 
					
						
							|  |  |  | ## | 
					
						
							|  |  |  | ## A dependency is a formula that another formula needs to install. | 
					
						
							|  |  |  | ## A requirement is something other than a formula that another formula | 
					
						
							|  |  |  | ## needs to be present. This includes external language modules, | 
					
						
							|  |  |  | ## command-line tools in the path, or any arbitrary predicate. | 
					
						
							|  |  |  | ## | 
					
						
							|  |  |  | ## The `depends_on` method in the formula DSL is used to declare | 
					
						
							|  |  |  | ## dependencies and requirements. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # This class is used by `depends_on` in the formula DSL to turn dependency | 
					
						
							|  |  |  | # specifications into the proper kinds of dependencies and requirements. | 
					
						
							|  |  |  | class DependencyCollector | 
					
						
							|  |  |  |   # Define the languages that we can handle as external dependencies. | 
					
						
							|  |  |  |   LANGUAGE_MODULES = [ | 
					
						
							|  |  |  |     :chicken, :jruby, :lua, :node, :perl, :python, :rbx, :ruby | 
					
						
							|  |  |  |   ].freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   attr_reader :deps, :external_deps | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize | 
					
						
							|  |  |  |     @deps = Dependencies.new | 
					
						
							|  |  |  |     @external_deps = [] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def add spec | 
					
						
							|  |  |  |     case spec | 
					
						
							|  |  |  |     when String      then @deps << Dependency.new(spec) | 
					
						
							|  |  |  |     when Formula     then @deps << Dependency.new(spec.name) | 
					
						
							|  |  |  |     when Dependency  then @deps << spec | 
					
						
							|  |  |  |     when Requirement then @external_deps << spec | 
					
						
							|  |  |  |     when Hash | 
					
						
							|  |  |  |       key, value = spec.shift | 
					
						
							|  |  |  |       case value | 
					
						
							|  |  |  |       when Array | 
					
						
							|  |  |  |         @deps << Dependency.new(key, value) | 
					
						
							|  |  |  |       when *LANGUAGE_MODULES | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |         @external_deps << LanguageModuleDependency.new(value, key) | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |       else | 
					
						
							|  |  |  |         # :optional, :recommended, :build, :universal and "32bit" are predefined | 
					
						
							|  |  |  |         @deps << Dependency.new(key, [value]) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       raise "Unsupported type #{spec.class} for #{spec}" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A list of formula dependencies. | 
					
						
							|  |  |  | class Dependencies < Array | 
					
						
							|  |  |  |   def include? dependency_name | 
					
						
							|  |  |  |     self.any?{|d| d.name == dependency_name} | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A dependency on another Homebrew formula. | 
					
						
							|  |  |  | class Dependency | 
					
						
							|  |  |  |   attr_reader :name, :tags | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize name, tags=nil | 
					
						
							|  |  |  |     @name = name | 
					
						
							|  |  |  |     tags = [] if tags == nil | 
					
						
							|  |  |  |     @tags = tags.each {|s| s.to_s} | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def to_s | 
					
						
							|  |  |  |     @name | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def ==(other_dep) | 
					
						
							| 
									
										
										
										
											2012-03-20 22:31:14 -07:00
										 |  |  |     @name == other_dep.to_s | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-11 18:24:24 -05:00
										 |  |  |   def <=>(other_dep) | 
					
						
							|  |  |  |     @name <=> other_dep.to_s | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |   def options | 
					
						
							|  |  |  |     @tags.select{|p|p.start_with? '--'} | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  |   def satisfied?; false; end | 
					
						
							|  |  |  |   def fatal?; false; end | 
					
						
							|  |  |  |   def message; ""; end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # A dependency on a language-specific module. | 
					
						
							|  |  |  | class LanguageModuleDependency < Requirement | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |   def initialize language, module_name, import_name=nil | 
					
						
							|  |  |  |     @language = language | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |     @module_name = module_name | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |     @import_name = import_name || module_name | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def fatal?; true; end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def satisfied? | 
					
						
							| 
									
										
										
										
											2012-04-30 14:17:56 +10:00
										 |  |  |     quiet_system(*the_test) | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def message; <<-EOS.undent
 | 
					
						
							|  |  |  |     Unsatisfied dependency: #{@module_name} | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |     Homebrew does not provide #{@language.to_s.capitalize} dependencies; install with: | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |       #{command_line} #{@module_name} | 
					
						
							|  |  |  |     EOS | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def the_test | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |     case @language | 
					
						
							|  |  |  |       when :chicken then %W{/usr/bin/env csi -e (use #{@import_name})} | 
					
						
							|  |  |  |       when :jruby then %W{/usr/bin/env jruby -rubygems -e require\ '#{@import_name}'} | 
					
						
							|  |  |  |       when :lua then %W{/usr/bin/env luarocks show #{@import_name}} | 
					
						
							|  |  |  |       when :node then %W{/usr/bin/env node -e require('#{@import_name}');} | 
					
						
							|  |  |  |       when :perl then %W{/usr/bin/env perl -e use\ #{@import_name}} | 
					
						
							|  |  |  |       when :python then %W{/usr/bin/env python -c import\ #{@import_name}} | 
					
						
							|  |  |  |       when :ruby then %W{/usr/bin/env ruby -rubygems -e require\ '#{@import_name}'} | 
					
						
							|  |  |  |       when :rbx then %W{/usr/bin/env rbx -rubygems -e require\ '#{@import_name}'} | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def command_line | 
					
						
							| 
									
										
										
										
											2012-03-20 19:43:41 -07:00
										 |  |  |     case @language | 
					
						
							| 
									
										
										
										
											2012-02-28 19:56:29 -08:00
										 |  |  |       when :chicken then "chicken-install" | 
					
						
							|  |  |  |       when :jruby   then "jruby -S gem install" | 
					
						
							|  |  |  |       when :lua     then "luarocks install" | 
					
						
							|  |  |  |       when :node    then "npm install" | 
					
						
							|  |  |  |       when :perl    then "cpan -i" | 
					
						
							|  |  |  |       when :python  then "easy_install" | 
					
						
							|  |  |  |       when :rbx     then "rbx gem install" | 
					
						
							|  |  |  |       when :ruby    then "gem install" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |