| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | require 'dependency' | 
					
						
							|  |  |  | require 'dependencies' | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  | require 'ld64_dependency' | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | require 'requirement' | 
					
						
							|  |  |  | require 'requirements' | 
					
						
							| 
									
										
										
										
											2013-04-16 03:31:29 -05:00
										 |  |  | require 'set' | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## 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. | 
					
						
							| 
									
										
										
										
											2013-04-16 03:31:29 -05:00
										 |  |  |   LANGUAGE_MODULES = Set[ | 
					
						
							| 
									
										
										
										
											2015-03-19 18:22:57 -07:00
										 |  |  |     :chicken, :jruby, :lua, :node, :ocaml, :perl, :python, :python3, :rbx, :ruby | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |   ].freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 14:22:43 -06:00
										 |  |  |   CACHE = {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-02 15:10:07 -05:00
										 |  |  |   def self.clear_cache | 
					
						
							|  |  |  |     CACHE.clear | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |   attr_reader :deps, :requirements | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize | 
					
						
							|  |  |  |     @deps = Dependencies.new | 
					
						
							| 
									
										
										
										
											2014-07-03 14:50:57 -05:00
										 |  |  |     @requirements = Requirements.new | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-27 16:53:42 -06:00
										 |  |  |   def add(spec) | 
					
						
							| 
									
										
										
										
											2014-02-27 14:22:43 -06:00
										 |  |  |     case dep = fetch(spec) | 
					
						
							| 
									
										
										
										
											2013-01-27 16:53:42 -06:00
										 |  |  |     when Dependency | 
					
						
							|  |  |  |       @deps << dep | 
					
						
							|  |  |  |     when Requirement | 
					
						
							|  |  |  |       @requirements << dep | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     dep | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 14:22:43 -06:00
										 |  |  |   def fetch(spec) | 
					
						
							|  |  |  |     CACHE.fetch(cache_key(spec)) { |key| CACHE[key] = build(spec) } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cache_key(spec) | 
					
						
							|  |  |  |     if Resource === spec && spec.download_strategy == CurlDownloadStrategy | 
					
						
							|  |  |  |       File.extname(spec.url) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       spec | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-27 16:53:42 -06:00
										 |  |  |   def build(spec) | 
					
						
							| 
									
										
										
										
											2015-06-19 22:30:13 -04:00
										 |  |  |     spec, tags = Hash === spec ? spec.first : spec | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |     parse_spec(spec, Array(tags)) | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-07 00:49:56 -05:00
										 |  |  |   private | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |   def parse_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     case spec | 
					
						
							|  |  |  |     when String | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       parse_string_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |     when Resource | 
					
						
							|  |  |  |       resource_dep(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-04-17 14:05:47 -05:00
										 |  |  |     when Symbol | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       parse_symbol_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     when Requirement, Dependency | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |       spec | 
					
						
							|  |  |  |     when Class | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       parse_class_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2014-07-01 15:07:06 -05:00
										 |  |  |       raise TypeError, "Unsupported type #{spec.class.name} for #{spec.inspect}" | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |   def parse_string_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2015-04-06 23:20:07 -07:00
										 |  |  |     if HOMEBREW_TAP_FORMULA_REGEX === spec | 
					
						
							|  |  |  |       TapDependency.new(spec, tags) | 
					
						
							|  |  |  |     elsif tags.empty? | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       Dependency.new(spec, tags) | 
					
						
							|  |  |  |     elsif (tag = tags.first) && LANGUAGE_MODULES.include?(tag) | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |       LanguageModuleRequirement.new(tag, spec, tags[1]) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       Dependency.new(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |   def parse_symbol_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     case spec | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |     when :x11        then X11Requirement.new(spec.to_s, tags) | 
					
						
							|  |  |  |     when :xcode      then XcodeRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-05-24 08:37:16 -07:00
										 |  |  |     when :macos      then MinimumMacOSRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |     when :mysql      then MysqlRequirement.new(tags) | 
					
						
							|  |  |  |     when :postgresql then PostgresqlRequirement.new(tags) | 
					
						
							|  |  |  |     when :gpg        then GPGRequirement.new(tags) | 
					
						
							|  |  |  |     when :fortran    then FortranRequirement.new(tags) | 
					
						
							|  |  |  |     when :mpi        then MPIRequirement.new(*tags) | 
					
						
							|  |  |  |     when :tex        then TeXRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |     when :arch       then ArchRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |     when :hg         then MercurialRequirement.new(tags) | 
					
						
							|  |  |  |     when :python     then PythonRequirement.new(tags) | 
					
						
							|  |  |  |     when :python3    then Python3Requirement.new(tags) | 
					
						
							|  |  |  |     when :java       then JavaRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2015-04-11 19:18:40 +01:00
										 |  |  |     when :ruby       then RubyRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |     when :osxfuse    then OsxfuseRequirement.new(tags) | 
					
						
							|  |  |  |     when :tuntap     then TuntapRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2014-12-05 01:34:56 -05:00
										 |  |  |     when :ant        then ant_dep(spec, tags) | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |     when :apr        then AprRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2015-05-08 14:37:15 +08:00
										 |  |  |     when :emacs      then EmacsRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-04-13 21:11:14 -05:00
										 |  |  |     # Tiger's ld is too old to properly link some software | 
					
						
							|  |  |  |     when :ld64       then LD64Dependency.new if MacOS.version < :leopard | 
					
						
							| 
									
										
										
										
											2014-05-19 10:37:45 -05:00
										 |  |  |     when :clt # deprecated | 
					
						
							| 
									
										
										
										
											2014-12-05 01:34:56 -05:00
										 |  |  |     when :autoconf, :automake, :bsdmake, :libtool # deprecated | 
					
						
							|  |  |  |       autotools_dep(spec, tags) | 
					
						
							| 
									
										
										
										
											2014-05-23 13:11:22 -05:00
										 |  |  |     when :cairo, :fontconfig, :freetype, :libpng, :pixman # deprecated | 
					
						
							|  |  |  |       Dependency.new(spec.to_s, tags) | 
					
						
							|  |  |  |     when :libltdl # deprecated | 
					
						
							|  |  |  |       tags << :run | 
					
						
							|  |  |  |       Dependency.new("libtool", tags) | 
					
						
							| 
									
										
										
										
											2014-12-05 01:34:56 -05:00
										 |  |  |     when :python2 | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |       PythonRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2014-03-22 10:31:00 +00:00
										 |  |  |       raise ArgumentError, "Unsupported special dependency #{spec.inspect}" | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-02-10 19:25:22 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |   def parse_class_spec(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     if spec < Requirement | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |       spec.new(tags) | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2013-06-26 15:25:09 -05:00
										 |  |  |       raise TypeError, "#{spec.inspect} is not a Requirement subclass" | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:49 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-06 16:08:50 -05:00
										 |  |  |   def autotools_dep(spec, tags) | 
					
						
							| 
									
										
										
										
											2013-11-04 12:00:06 -06:00
										 |  |  |     tags << :build unless tags.include? :run | 
					
						
							|  |  |  |     Dependency.new(spec.to_s, tags) | 
					
						
							| 
									
										
										
										
											2013-02-10 19:25:22 -06:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-28 14:44:20 -05:00
										 |  |  |   def ant_dep(spec, tags) | 
					
						
							|  |  |  |     if MacOS.version >= :mavericks | 
					
						
							|  |  |  |       Dependency.new(spec.to_s, tags) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |   def resource_dep(spec, tags) | 
					
						
							|  |  |  |     tags << :build | 
					
						
							|  |  |  |     strategy = spec.download_strategy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case | 
					
						
							|  |  |  |     when strategy <= CurlDownloadStrategy | 
					
						
							|  |  |  |       parse_url_spec(spec.url, tags) | 
					
						
							|  |  |  |     when strategy <= GitDownloadStrategy | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |       GitRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |     when strategy <= MercurialDownloadStrategy | 
					
						
							| 
									
										
										
										
											2015-06-15 09:56:04 +01:00
										 |  |  |       MercurialRequirement.new(tags) | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |     when strategy <= FossilDownloadStrategy | 
					
						
							|  |  |  |       Dependency.new("fossil", tags) | 
					
						
							|  |  |  |     when strategy <= BazaarDownloadStrategy | 
					
						
							|  |  |  |       Dependency.new("bazaar", tags) | 
					
						
							| 
									
										
										
										
											2013-11-18 15:58:41 -06:00
										 |  |  |     when strategy <= CVSDownloadStrategy | 
					
						
							| 
									
										
										
										
											2014-04-02 19:58:15 -05:00
										 |  |  |       Dependency.new("cvs", tags) if MacOS.version >= :mavericks || !MacOS::Xcode.provides_cvs? | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |     when strategy < AbstractDownloadStrategy | 
					
						
							|  |  |  |       # allow unknown strategies to pass through | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       raise TypeError, | 
					
						
							|  |  |  |         "#{strategy.inspect} is not an AbstractDownloadStrategy subclass" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def parse_url_spec(url, tags) | 
					
						
							|  |  |  |     case File.extname(url) | 
					
						
							|  |  |  |     when '.xz'  then Dependency.new('xz', tags) | 
					
						
							| 
									
										
										
										
											2013-11-29 10:10:28 -08:00
										 |  |  |     when '.lz'  then Dependency.new('lzip', tags) | 
					
						
							| 
									
										
										
										
											2013-09-28 16:37:05 -05:00
										 |  |  |     when '.rar' then Dependency.new('unrar', tags) | 
					
						
							|  |  |  |     when '.7z'  then Dependency.new('p7zip', tags) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-01-26 20:05:39 -06:00
										 |  |  | end |