| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  | require 'download_strategy' | 
					
						
							|  |  |  | require 'checksum' | 
					
						
							|  |  |  | require 'version' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  | # Resource is the fundamental representation of an external resource. The | 
					
						
							|  |  |  | # primary formula download, along with other declared resources, are instances | 
					
						
							|  |  |  | # of this class. | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  | class Resource | 
					
						
							|  |  |  |   include FileUtils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-12 00:37:24 -05:00
										 |  |  |   attr_reader :mirrors, :specs, :using | 
					
						
							|  |  |  |   attr_writer :version | 
					
						
							|  |  |  |   attr_accessor :download_strategy, :checksum | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   # Formula name must be set after the DSL, as we have no access to the | 
					
						
							|  |  |  |   # formula name before initialization of the formula | 
					
						
							| 
									
										
										
										
											2014-03-13 19:51:23 -05:00
										 |  |  |   attr_accessor :name, :owner | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 22:11:23 -05:00
										 |  |  |   class Download | 
					
						
							|  |  |  |     def initialize(resource) | 
					
						
							|  |  |  |       @resource = resource | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def url | 
					
						
							|  |  |  |       @resource.url | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def specs | 
					
						
							|  |  |  |       @resource.specs | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def version | 
					
						
							|  |  |  |       @resource.version | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def mirrors | 
					
						
							|  |  |  |       @resource.mirrors | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-23 21:39:19 -05:00
										 |  |  |   def initialize name=nil, &block | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |     @name = name | 
					
						
							| 
									
										
										
										
											2013-09-23 21:39:19 -05:00
										 |  |  |     @url = nil | 
					
						
							|  |  |  |     @version = nil | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |     @mirrors = [] | 
					
						
							|  |  |  |     @specs = {} | 
					
						
							|  |  |  |     @checksum = nil | 
					
						
							|  |  |  |     @using = nil | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:39 -05:00
										 |  |  |     instance_eval(&block) if block_given? | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   def downloader | 
					
						
							| 
									
										
										
										
											2015-01-06 00:25:04 -05:00
										 |  |  |     download_strategy.new(download_name, Download.new(self)) | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-02 21:53:53 -07:00
										 |  |  |   # Removes /s from resource names; this allows go package names | 
					
						
							|  |  |  |   # to be used as resource names without confusing software that | 
					
						
							|  |  |  |   # interacts with download_name, e.g. github.com/foo/bar | 
					
						
							|  |  |  |   def escaped_name | 
					
						
							|  |  |  |     name.gsub("/", '-') | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:40 -05:00
										 |  |  |   def download_name | 
					
						
							| 
									
										
										
										
											2014-06-02 21:53:53 -07:00
										 |  |  |     name.nil? ? owner.name : "#{owner.name}--#{escaped_name}" | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:40 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cached_download | 
					
						
							|  |  |  |     downloader.cached_location | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 14:28:49 -05:00
										 |  |  |   def clear_cache | 
					
						
							|  |  |  |     downloader.clear_cache | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 00:43:10 -05:00
										 |  |  |   def stage(target=nil, &block) | 
					
						
							| 
									
										
										
										
											2014-12-13 22:51:21 -05:00
										 |  |  |     unless target || block | 
					
						
							|  |  |  |       raise ArgumentError, "target directory or block is required" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-30 00:43:10 -05:00
										 |  |  |     verify_download_integrity(fetch) | 
					
						
							|  |  |  |     unpack(target, &block) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   # If a target is given, unpack there; else unpack to a temp folder | 
					
						
							|  |  |  |   # If block is given, yield to that block | 
					
						
							|  |  |  |   # A target or a block must be given, but not both | 
					
						
							| 
									
										
										
										
											2013-10-30 00:43:10 -05:00
										 |  |  |   def unpack(target=nil) | 
					
						
							| 
									
										
										
										
											2014-12-14 17:59:35 -05:00
										 |  |  |     mktemp(download_name) do | 
					
						
							|  |  |  |       downloader.stage | 
					
						
							|  |  |  |       if block_given? | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |         yield self | 
					
						
							| 
									
										
										
										
											2014-12-14 17:59:35 -05:00
										 |  |  |       elsif target | 
					
						
							|  |  |  |         target = Pathname.new(target) unless target.is_a? Pathname | 
					
						
							|  |  |  |         target.install Dir['*'] | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:43 -05:00
										 |  |  |   Partial = Struct.new(:resource, :files) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def files(*files) | 
					
						
							|  |  |  |     Partial.new(self, files) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   def fetch | 
					
						
							| 
									
										
										
										
											2014-02-18 15:08:03 -05:00
										 |  |  |     HOMEBREW_CACHE.mkpath | 
					
						
							| 
									
										
										
										
											2014-10-10 20:30:29 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     begin | 
					
						
							|  |  |  |       downloader.fetch | 
					
						
							|  |  |  |     rescue ErrorDuringExecution, CurlDownloadStrategyError => e | 
					
						
							|  |  |  |       raise DownloadError.new(self, e) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 15:08:03 -05:00
										 |  |  |     cached_download | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def verify_download_integrity fn | 
					
						
							| 
									
										
										
										
											2014-12-05 18:08:21 -05:00
										 |  |  |     if fn.file? | 
					
						
							| 
									
										
										
										
											2013-12-08 21:37:22 +00:00
										 |  |  |       ohai "Verifying #{fn.basename} checksum" if ARGV.verbose? | 
					
						
							| 
									
										
										
										
											2013-10-30 00:43:10 -05:00
										 |  |  |       fn.verify_checksum(checksum) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   rescue ChecksumMissingError | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:41 -05:00
										 |  |  |     opoo "Cannot verify integrity of #{fn.basename}" | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |     puts "A checksum was not provided for this resource" | 
					
						
							| 
									
										
										
										
											2015-02-24 23:25:57 +00:00
										 |  |  |     puts "For your reference the SHA256 is: #{fn.sha256}" | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-27 21:02:00 -05:00
										 |  |  |   Checksum::TYPES.each do |type| | 
					
						
							|  |  |  |     define_method(type) { |val| @checksum = Checksum.new(type, val) } | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def url val=nil, specs={} | 
					
						
							|  |  |  |     return @url if val.nil? | 
					
						
							|  |  |  |     @url = val | 
					
						
							|  |  |  |     @specs.merge!(specs) | 
					
						
							| 
									
										
										
										
											2013-10-11 20:21:41 -05:00
										 |  |  |     @using = @specs.delete(:using) | 
					
						
							| 
									
										
										
										
											2014-07-15 13:42:03 -05:00
										 |  |  |     @download_strategy = DownloadStrategyDetector.detect(url, using) | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def version val=nil | 
					
						
							|  |  |  |     @version ||= detect_version(val) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def mirror val | 
					
						
							|  |  |  |     mirrors << val | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def detect_version(val) | 
					
						
							| 
									
										
										
										
											2014-12-31 10:37:29 -05:00
										 |  |  |     return if val.nil? && url.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |     case val | 
					
						
							| 
									
										
										
										
											2014-05-27 21:41:43 -05:00
										 |  |  |     when nil     then Version.detect(url, specs) | 
					
						
							|  |  |  |     when String  then Version.new(val) | 
					
						
							|  |  |  |     when Version then val | 
					
						
							| 
									
										
										
										
											2013-09-17 21:25:38 -05:00
										 |  |  |     else | 
					
						
							|  |  |  |       raise TypeError, "version '#{val.inspect}' should be a string" | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2014-06-02 23:32:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   class Go < Resource | 
					
						
							|  |  |  |     def stage target | 
					
						
							|  |  |  |       super(target/name) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2013-08-06 19:52:58 -07:00
										 |  |  | end |