| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | # Copyright 2009 Max Howell <max@methylblue.com> | 
					
						
							|  |  |  | # Licensed as per the GPL version 3 | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  | require 'pathname' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | $agent = "Homebrew 0.1 (Ruby; Mac OS X 10.5 Leopard)" | 
					
						
							|  |  |  | $cellar = Pathname.new(__FILE__).dirname.parent.realpath | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-22 00:14:57 +01:00
										 |  |  | # optimise all the way to eleven, references: | 
					
						
							|  |  |  | # http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel | 
					
						
							|  |  |  | # http://forums.mozillazine.org/viewtopic.php?f=12&t=577299 | 
					
						
							|  |  |  | # http://gcc.gnu.org/onlinedocs/gcc-4.0.1/gcc/i386-and-x86_002d64-Options.html | 
					
						
							| 
									
										
										
										
											2009-05-21 01:28:11 +01:00
										 |  |  | ENV['MACOSX_DEPLOYMENT_TARGET']='10.5' | 
					
						
							| 
									
										
										
										
											2009-05-22 00:14:57 +01:00
										 |  |  | ENV['CFLAGS']=ENV['CXXFLAGS']='-O3 -w -pipe -fomit-frame-pointer -march=prescott' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # lets use gcc 4.2, it is newer and "better", at least I believe so, mail me | 
					
						
							|  |  |  | # if I'm wrong | 
					
						
							|  |  |  | ENV['CC']='gcc-4.2' | 
					
						
							|  |  |  | ENV['CXX']='g++-4.2' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #TODO don't add the prefixes if we're in /usr or /usr/local | 
					
						
							| 
									
										
										
										
											2009-05-21 04:35:36 +01:00
										 |  |  | ENV['CPPFLAGS']="-I#{$cellar.parent}/include" | 
					
						
							|  |  |  | ENV['LDFLAGS']="-L#{$cellar.parent}/lib" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 01:28:11 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 17:50:57 +01:00
										 |  |  | def ohai title | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  |   puts "\033[0;34m==>\033[0;0;1m #{title} \033[0;0m" | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | class Formula | 
					
						
							| 
									
										
										
										
											2009-05-21 03:26:44 +01:00
										 |  |  |   require 'find' | 
					
						
							|  |  |  |   require 'fileutils' | 
					
						
							| 
									
										
										
										
											2009-05-21 12:40:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |   # if you reimplement, assign @name, @version, @url and @md5 | 
					
						
							|  |  |  |   def initialize(url, md5) | 
					
						
							|  |  |  |     @name = File.basename $0, '.rb' #original script that the interpreter started | 
					
						
							|  |  |  |     @url = url | 
					
						
							|  |  |  |     @md5 = md5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # pls improve this version extraction crap | 
					
						
							|  |  |  |     filename=File.basename url | 
					
						
							|  |  |  |     i=filename.index /[-_]\d/ | 
					
						
							|  |  |  |     unless i.nil? | 
					
						
							|  |  |  |       /^((\d+[.-])*\d+)/.match filename[i+1,1000] #1000 because rubysucks | 
					
						
							|  |  |  |       @version = $1 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       # no divisor or a '.' divisor, eg. dmd.1.11.zip | 
					
						
							|  |  |  |       /^[a-zA-Z._-]*((\d+\.)*\d+)/.match filename | 
					
						
							|  |  |  |       @version = $1 | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   #yields a Pathname object for the installation prefix | 
					
						
							|  |  |  |   def brew | 
					
						
							|  |  |  |     raise "@name.nil?" if @name.nil? | 
					
						
							|  |  |  |     raise "@version.nil?" if @version.nil? | 
					
						
							| 
									
										
										
										
											2009-05-21 12:40:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 04:35:36 +01:00
										 |  |  |     # disabled until the regexp makes sense :P | 
					
						
							|  |  |  |     #raise "@name does not validate to our regexp" unless /^\w+$/ =~ @name | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 03:26:44 +01:00
										 |  |  |     beginning = Time.now | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |     prefix=$cellar+@name+@version | 
					
						
							|  |  |  |     raise "#{prefix} already exists!" if prefix.exist? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 17:50:57 +01:00
										 |  |  |     ohai "Preparing build" | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |     appsupport = File.expand_path "~/Library/Application Support/Homebrew" | 
					
						
							|  |  |  |     FileUtils.mkpath appsupport unless File.exist? appsupport | 
					
						
							|  |  |  |     Dir.chdir appsupport do | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  |       tgz=Pathname.new fetch() | 
					
						
							| 
									
										
										
										
											2009-05-21 17:54:14 +01:00
										 |  |  |       md5=`md5 -q "#{tgz}"`.strip | 
					
						
							|  |  |  |       raise "MD5 mismatch: #{md5}" unless md5 == @md5.downcase | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # we make an additional subdirectory so know exactly what we are | 
					
						
							|  |  |  |       # recursively deleting later | 
					
						
							|  |  |  |       # we use mktemp rather than appsupport/blah because some build scripts | 
					
						
							|  |  |  |       # can't handle being built in a directory with spaces in it :P | 
					
						
							|  |  |  |       tmp=nil | 
					
						
							|  |  |  |       begin | 
					
						
							|  |  |  |         tmp=`mktemp -dt #{@name}-#{@version}`.strip | 
					
						
							|  |  |  |         Dir.chdir tmp do | 
					
						
							|  |  |  |           Dir.chdir uncompress(tgz) do | 
					
						
							| 
									
										
										
										
											2009-05-21 02:46:54 +01:00
										 |  |  |             caveats = yield prefix | 
					
						
							|  |  |  |             if caveats | 
					
						
							| 
									
										
										
										
											2009-05-21 17:50:57 +01:00
										 |  |  |               ohai "Caveats" | 
					
						
							| 
									
										
										
										
											2009-05-21 02:46:54 +01:00
										 |  |  |               puts caveats | 
					
						
							| 
									
										
										
										
											2009-05-21 17:50:57 +01:00
										 |  |  |               ohai "Summary" | 
					
						
							| 
									
										
										
										
											2009-05-21 02:46:54 +01:00
										 |  |  |             end | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |             #TODO copy changelog or CHANGES file to pkg root, | 
					
						
							|  |  |  |             #TODO maybe README, etc. to versioned root | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2009-05-21 17:54:31 +01:00
										 |  |  |       rescue | 
					
						
							|  |  |  |         if ARGV.include? '--debug' | 
					
						
							|  |  |  |           # debug mode allows the packager to intercept a failed build and | 
					
						
							|  |  |  |           # investigate the problems | 
					
						
							|  |  |  |           puts "Rescued build at: #{tmp}" | 
					
						
							|  |  |  |           exit! 1
 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           raise | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |       ensure | 
					
						
							|  |  |  |         FileUtils.rm_rf tmp | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # stay in appsupport in case any odd files gets created etc. | 
					
						
							|  |  |  |       `#{$cellar}/homebrew/brew ln #{prefix}` if prefix.exist? | 
					
						
							| 
									
										
										
										
											2009-05-21 12:40:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 03:26:44 +01:00
										 |  |  |       puts "#{prefix}: "+`find #{prefix} -type f | wc -l`.strip+' files, '+`du -hd0 #{prefix} | cut -d"\t" -f1`.strip+", built in #{Time.now - beginning} seconds" | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def version | 
					
						
							|  |  |  |     @version | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   def name | 
					
						
							|  |  |  |     @name | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected | 
					
						
							|  |  |  |   def fetch | 
					
						
							|  |  |  |     tgz=File.expand_path File.basename(@url) | 
					
						
							| 
									
										
										
										
											2009-05-21 04:36:53 +01:00
										 |  |  |     unless File.exists? tgz | 
					
						
							| 
									
										
										
										
											2009-05-21 12:40:40 +01:00
										 |  |  |       `curl -LOA "#{$agent}" "#{@url}"` | 
					
						
							| 
									
										
										
										
											2009-05-21 04:36:53 +01:00
										 |  |  |       raise "Download failed" unless $? == 0
 | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |     return tgz | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def uncompress(path) | 
					
						
							|  |  |  |     if path.extname == '.zip' | 
					
						
							|  |  |  |       `unzip -qq "#{path}"` | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       `tar xf "#{path}"` | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     raise "Compression tool failed" if $? != 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     entries=Dir['*'] | 
					
						
							|  |  |  |     raise "Empty tar!" if entries.nil? or entries.length == 0
 | 
					
						
							|  |  |  |     raise "Too many folders in uncompressed result. You need to reimplement the Recipe.uncompress function." if entries.length > 1
 | 
					
						
							|  |  |  |     return entries.first | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private | 
					
						
							|  |  |  |   def method_added(method) | 
					
						
							|  |  |  |     raise 'You cannot override Formula.brew' if method == 'brew' | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inreplace(path, before, after) | 
					
						
							| 
									
										
										
										
											2009-05-22 00:15:28 +01:00
										 |  |  |   before=before.to_s | 
					
						
							|  |  |  |   after=after.to_s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   before.gsub! '"', '\"' | 
					
						
							|  |  |  |   after.gsub! '"', '\"' | 
					
						
							|  |  |  |   before.gsub! '|', '\|"' | 
					
						
							|  |  |  |   after.gsub! '|', '\|"' | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |   # we're not using Ruby because the perl script is more concise | 
					
						
							| 
									
										
										
										
											2009-05-22 00:15:28 +01:00
										 |  |  |   #TODO the above escapes are worse, use a proper ruby script :P | 
					
						
							|  |  |  |   #TODO optimise it by taking before and after as arrays | 
					
						
							|  |  |  |   #Bah, just make the script writers do it themselves with a standard collect block | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  |   `perl -pi -e "s|#{before}|#{after}|g" "#{path}"` | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  | def system cmd | 
					
						
							| 
									
										
										
										
											2009-05-21 17:50:57 +01:00
										 |  |  |   ohai cmd | 
					
						
							| 
									
										
										
										
											2009-05-21 02:24:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   out='' | 
					
						
							|  |  |  |   IO.popen("#{cmd} 2>1") do |f| | 
					
						
							|  |  |  |     until f.eof? | 
					
						
							|  |  |  |       s=f.gets | 
					
						
							|  |  |  |       out+=s | 
					
						
							|  |  |  |       puts s if ARGV.include? '--verbose' | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   unless $? == 0
 | 
					
						
							|  |  |  |     puts out unless ARGV.include? '--verbose' #already did that above | 
					
						
							|  |  |  |     raise "Failure during: #{cmd}" | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 03:26:44 +01:00
										 |  |  | # force a prettier exception handler unless --verbose or HOMEBREW_DEBUG | 
					
						
							|  |  |  | Kernel.at_exit { | 
					
						
							| 
									
										
										
										
											2009-05-21 17:55:23 +01:00
										 |  |  |   if $! and not (ARGV.include? '--verbose' or ENV['HOMEBREW_DEBUG']) | 
					
						
							|  |  |  |     exit! 130 if $1.class == Interrupt #control-c | 
					
						
							|  |  |  |     if $!.kind_of? StandardError | 
					
						
							|  |  |  |         puts "\033[1;31mError\033[0;0m: #{$!}" | 
					
						
							|  |  |  |         exit! 1
 | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2009-05-21 03:26:44 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-21 00:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | ########################################################################script | 
					
						
							|  |  |  | if $0 == __FILE__ | 
					
						
							|  |  |  |   d=$cellar.parent+'bin' | 
					
						
							|  |  |  |   d.mkpath unless d.exist? | 
					
						
							|  |  |  |   (d+'brew').make_symlink $cellar+'homebrew'+'brew' | 
					
						
							|  |  |  | end |