| 
									
										
										
										
											2009-08-31 16:01:36 +01:00
										 |  |  | #  Copyright 2009 Max Howell and other contributors. | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-08-31 16:01:36 +01:00
										 |  |  | #  Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  | #  modification, are permitted provided that the following conditions | 
					
						
							|  |  |  | #  are met: | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-08-31 16:01:36 +01:00
										 |  |  | #  1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  | #     notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  | #  2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  | #     notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  | #     documentation and/or other materials provided with the distribution. | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-08-31 16:01:36 +01:00
										 |  |  | #  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
					
						
							|  |  |  | #  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
					
						
							|  |  |  | #  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
					
						
							|  |  |  | #  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
					
						
							|  |  |  | #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  | #  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
					
						
							|  |  |  | #  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
					
						
							|  |  |  | #  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  | #  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
					
						
							|  |  |  | #  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  | # | 
					
						
							|  |  |  | class AbstractDownloadStrategy | 
					
						
							| 
									
										
										
										
											2009-10-17 14:35:24 +02:00
										 |  |  |   def initialize url, name, version, specs | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     @url=url | 
					
						
							| 
									
										
										
										
											2009-10-19 03:01:03 +01:00
										 |  |  |     case specs when Hash | 
					
						
							| 
									
										
										
										
											2009-10-17 14:35:24 +02:00
										 |  |  |       @spec = specs.keys.first # only use first spec | 
					
						
							|  |  |  |       @ref = specs.values.first | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-08-30 16:11:44 +01:00
										 |  |  |     @unique_token="#{name}-#{version}" unless name.to_s.empty? or name == '__UNKNOWN__' | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-02 18:36:58 +01:00
										 |  |  | class CurlDownloadStrategy <AbstractDownloadStrategy | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |   def fetch | 
					
						
							|  |  |  |     ohai "Downloading #{@url}" | 
					
						
							| 
									
										
										
										
											2009-08-30 16:11:44 +01:00
										 |  |  |     if @unique_token | 
					
						
							|  |  |  |       @dl=HOMEBREW_CACHE+(@unique_token+ext) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       @dl=HOMEBREW_CACHE+File.basename(@url) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     unless @dl.exist? | 
					
						
							| 
									
										
										
										
											2009-09-05 20:47:15 +01:00
										 |  |  |       begin | 
					
						
							|  |  |  |         curl @url, '-o', @dl | 
					
						
							| 
									
										
										
										
											2009-09-17 16:20:20 +01:00
										 |  |  |       rescue Exception | 
					
						
							|  |  |  |         @dl.unlink if @dl.exist? | 
					
						
							| 
									
										
										
										
											2009-09-05 20:47:15 +01:00
										 |  |  |         raise | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2009-10-23 14:47:15 +01:00
										 |  |  |       puts "File already downloaded and cached to #{HOMEBREW_CACHE}" | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |     return @dl # thus performs checksum verification | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def stage | 
					
						
							| 
									
										
										
										
											2009-09-23 16:22:16 -06:00
										 |  |  |     # magic numbers stolen from /usr/share/file/magic/ | 
					
						
							|  |  |  |     File.open(@dl) do |f| | 
					
						
							|  |  |  |       # get the first four bytes | 
					
						
							|  |  |  |       case f.read(4) | 
					
						
							|  |  |  |       when /^PK\003\004/ # .zip archive | 
					
						
							| 
									
										
										
										
											2009-09-23 16:44:10 +01:00
										 |  |  |         safe_system '/usr/bin/unzip', '-qq', @dl | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |         chdir | 
					
						
							| 
									
										
										
										
											2009-09-23 16:22:16 -06:00
										 |  |  |       when /^\037\213/, /^BZh/ # gzip/bz2 compressed | 
					
						
							|  |  |  |         # TODO check if it's really a tar archive | 
					
						
							| 
									
										
										
										
											2009-09-23 16:44:10 +01:00
										 |  |  |         safe_system '/usr/bin/tar', 'xf', @dl | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |         chdir | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         # we are assuming it is not an archive, use original filename | 
					
						
							|  |  |  |         # this behaviour is due to ScriptFileFormula expectations | 
					
						
							| 
									
										
										
										
											2009-09-02 14:31:28 +01:00
										 |  |  |         # So I guess we should cp, but we mv, for this historic reason | 
					
						
							|  |  |  |         # HOWEVER if this breaks some expectation you had we *will* change the | 
					
						
							|  |  |  |         # behaviour, just open an issue at github | 
					
						
							|  |  |  |         FileUtils.mv @dl, File.basename(@url) | 
					
						
							| 
									
										
										
										
											2009-09-23 16:22:16 -06:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | private | 
					
						
							|  |  |  |   def chdir | 
					
						
							|  |  |  |     entries=Dir['*'] | 
					
						
							|  |  |  |     case entries.length | 
					
						
							|  |  |  |       when 0 then raise "Empty archive" | 
					
						
							|  |  |  |       when 1 then Dir.chdir entries.first rescue nil | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def ext | 
					
						
							|  |  |  |     # GitHub uses odd URLs for zip files, so check for those | 
					
						
							|  |  |  |     rx=%r[http://(www\.)?github\.com/.*/(zip|tar)ball/] | 
					
						
							|  |  |  |     if rx.match @url | 
					
						
							|  |  |  |       if $2 == 'zip' | 
					
						
							|  |  |  |         '.zip' | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         '.tgz' | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       Pathname.new(@url).extname | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-02 18:36:58 +01:00
										 |  |  | class HttpDownloadStrategy <CurlDownloadStrategy | 
					
						
							| 
									
										
										
										
											2009-10-19 03:01:41 +01:00
										 |  |  |   def initialize url, name, version, specs | 
					
						
							| 
									
										
										
										
											2009-10-02 18:36:58 +01:00
										 |  |  |     opoo "HttpDownloadStrategy is deprecated" | 
					
						
							|  |  |  |     puts "Please use CurlDownloadStrategy in future" | 
					
						
							|  |  |  |     puts "HttpDownloadStrategy will be removed in version 0.5" | 
					
						
							| 
									
										
										
										
											2009-10-19 03:01:41 +01:00
										 |  |  |     super url, name, version, specs | 
					
						
							| 
									
										
										
										
											2009-10-02 18:36:58 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  | class SubversionDownloadStrategy <AbstractDownloadStrategy | 
					
						
							|  |  |  |   def fetch | 
					
						
							|  |  |  |     ohai "Checking out #{@url}" | 
					
						
							|  |  |  |     @co=HOMEBREW_CACHE+@unique_token | 
					
						
							|  |  |  |     unless @co.exist? | 
					
						
							| 
									
										
										
										
											2009-10-20 20:44:14 -07:00
										 |  |  |       checkout_args = ['/usr/bin/svn', 'checkout', @url] | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       if (@spec == :revision) and @ref | 
					
						
							|  |  |  |         checkout_args << '-r' | 
					
						
							|  |  |  |         checkout_args << @ref | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       checkout_args << @co | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       safe_system *checkout_args | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     else | 
					
						
							|  |  |  |       # TODO svn up? | 
					
						
							|  |  |  |       puts "Repository already checked out" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def stage | 
					
						
							|  |  |  |     # Force the export, since the target directory will already exist | 
					
						
							| 
									
										
										
										
											2009-09-23 16:44:10 +01:00
										 |  |  |     safe_system '/usr/bin/svn', 'export', '--force', @co, Dir.pwd | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class GitDownloadStrategy <AbstractDownloadStrategy | 
					
						
							|  |  |  |   def fetch | 
					
						
							|  |  |  |     ohai "Cloning #{@url}" | 
					
						
							|  |  |  |     @clone=HOMEBREW_CACHE+@unique_token | 
					
						
							|  |  |  |     unless @clone.exist? | 
					
						
							|  |  |  |       safe_system 'git', 'clone', @url, @clone | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       # TODO git pull? | 
					
						
							|  |  |  |       puts "Repository already cloned" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def stage | 
					
						
							| 
									
										
										
										
											2009-10-17 14:35:24 +02:00
										 |  |  |     dst = Dir.getwd | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     Dir.chdir @clone do | 
					
						
							| 
									
										
										
										
											2009-10-17 14:35:24 +02:00
										 |  |  |       if @spec and @ref | 
					
						
							|  |  |  |         ohai "Checking out #{@spec} #{@ref}" | 
					
						
							|  |  |  |         case @spec | 
					
						
							|  |  |  |         when :branch | 
					
						
							|  |  |  |           safe_system 'git', 'checkout', '-b', @ref, "origin/#{@ref}" | 
					
						
							|  |  |  |         when :tag | 
					
						
							|  |  |  |           safe_system 'git', 'checkout', @ref | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |       # http://stackoverflow.com/questions/160608/how-to-do-a-git-export-like-svn-export | 
					
						
							| 
									
										
										
										
											2009-08-23 19:05:05 +01:00
										 |  |  |       safe_system 'git', 'checkout-index', '-af', "--prefix=#{dst}/" | 
					
						
							| 
									
										
										
										
											2009-08-21 20:30:13 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2009-09-27 19:30:39 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class CVSDownloadStrategy <AbstractDownloadStrategy | 
					
						
							|  |  |  |   def fetch | 
					
						
							|  |  |  |     ohai "Checking out #{@url}" | 
					
						
							|  |  |  |     @co=HOMEBREW_CACHE+@unique_token | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # URL of cvs cvs://:pserver:anoncvs@www.gccxml.org:/cvsroot/GCC_XML:gccxml | 
					
						
							|  |  |  |     # will become: | 
					
						
							|  |  |  |     # cvs -d :pserver:anoncvs@www.gccxml.org:/cvsroot/GCC_XML login | 
					
						
							|  |  |  |     # cvs -d :pserver:anoncvs@www.gccxml.org:/cvsroot/GCC_XML co gccxml | 
					
						
							|  |  |  |     mod, url = split_url(@url) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unless @co.exist? | 
					
						
							|  |  |  |       Dir.chdir HOMEBREW_CACHE do | 
					
						
							|  |  |  |         safe_system '/usr/bin/cvs', '-d', url, 'login' | 
					
						
							|  |  |  |         safe_system '/usr/bin/cvs', '-d', url, 'checkout', '-d', @unique_token, mod | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       # TODO cvs up? | 
					
						
							|  |  |  |       puts "Repository already checked out" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def stage | 
					
						
							|  |  |  |     FileUtils.cp_r(Dir[HOMEBREW_CACHE+@unique_token+"*"], Dir.pwd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     require 'find' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Find.find(Dir.pwd) do |path| | 
					
						
							|  |  |  |       if FileTest.directory?(path) && File.basename(path) == "CVS" | 
					
						
							|  |  |  |         Find.prune | 
					
						
							|  |  |  |         FileUtil.rm_r path, :force => true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private | 
					
						
							|  |  |  |   def split_url(in_url) | 
					
						
							|  |  |  |     parts=in_url.sub(%r[^cvs://], '').split(/:/) | 
					
						
							|  |  |  |     mod=parts.pop | 
					
						
							|  |  |  |     url=parts.join(':') | 
					
						
							|  |  |  |     [ mod, url ] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MercurialDownloadStrategy <AbstractDownloadStrategy | 
					
						
							|  |  |  |   def fetch | 
					
						
							|  |  |  |     ohai "Cloning #{@url}" | 
					
						
							|  |  |  |     @clone=HOMEBREW_CACHE+@unique_token | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     url=@url.sub(%r[^hg://], '') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unless @clone.exist? | 
					
						
							|  |  |  |       safe_system 'hg', 'clone', url, @clone | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       # TODO hg pull? | 
					
						
							|  |  |  |       puts "Repository already cloned" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def stage | 
					
						
							|  |  |  |     dst=Dir.getwd | 
					
						
							|  |  |  |     Dir.chdir @clone do | 
					
						
							| 
									
										
										
										
											2009-10-17 14:35:24 +02:00
										 |  |  |       if @spec and @ref | 
					
						
							|  |  |  |         ohai "Checking out #{@spec} #{@ref}" | 
					
						
							|  |  |  |         Dir.chdir @clone do | 
					
						
							|  |  |  |           safe_system 'hg', 'archive', '-y', '-r', @ref, '-t', 'files', dst | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         safe_system 'hg', 'archive', '-y', '-t', 'files', dst | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2009-09-27 19:30:39 -04:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |