# Copyright 2009 Max Howell # # This file is part of Homebrew. # # Homebrew is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Homebrew is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Homebrew. If not, see . require 'utils' class BuildError 0 rescue return false end def initialize name=nil @name=name @version=self.class.version unless @version @url=self.class.url unless @url @homepage=self.class.homepage unless @homepage @md5=self.class.md5 unless @md5 @sha1=self.class.sha1 unless @sha1 raise "@url.nil?" if @url.nil? end def prefix raise "@name.nil!" if @name.nil? raise "@version.nil?" if @version.nil? HOMEBREW_CELLAR+@name+@version end def bin; prefix+'bin' end def doc; prefix+'share'+'doc'+name end def lib; prefix+'lib' end def man; prefix+'share'+'man' end def man1; man+'man1' end def include; prefix+'include' end def caveats nil end # Pretty titles the command and buffers stdout/stderr # Throws if there's an error def system cmd ohai cmd if ARGV.include? '--verbose' Kernel.system cmd else out='' IO.popen "#{cmd} 2>&1" do |f| until f.eof? out+=f.gets end end puts out unless $? == 0 end raise BuildError.new(cmd) unless $? == 0 end # we don't have a std_autotools variant because autotools is a lot less # consistent and the standard parameters are more memorable # really Homebrew should determine what works inside brew() then # we could add --disable-dependency-tracking when it will work def std_cmake_parameters # The None part makes cmake use the environment's CFLAGS etc. settings "-DCMAKE_INSTALL_PREFIX='#{prefix}' -DCMAKE_BUILD_TYPE=None" end def verify_download_integrity fn require 'digest' type='MD5' type='SHA1' if @sha1 supplied=eval "@#{type.downcase}" hash=eval("Digest::#{type}").hexdigest(fn.read) if supplied raise "#{type} mismatch: #{hash}" unless supplied.upcase == hash.upcase else opoo "Cannot verify package integrity" puts "The formula did not provide a download checksum" puts "For your reference the #{type} is: #{hash}" end end # yields self with current working directory set to the uncompressed tarball def brew ohai "Downloading #{@url}" HOMEBREW_CACHE.mkpath Dir.chdir HOMEBREW_CACHE do tmp=nil tgz=Pathname.new(fetch()).realpath begin verify_download_integrity tgz # 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=`mktemp -dt #{File.basename @url}`.strip Dir.chdir tmp do Dir.chdir uncompress(tgz) do yield self end end rescue Interrupt, RuntimeError 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 ensure FileUtils.rm_rf tmp if tmp end end end protected # returns the directory where the archive was uncompressed # in this Abstract case we assume there is no archive def uncompress path path.dirname end private def fetch %r[http://(www.)?github.com/.*/(zip|tar)ball/].match @url if $2 # curl doesn't do the redirect magic that we would like, so we get a # stupidly named file, this is why wget would be beter, but oh well tgz="#{@name}-#{@version}.#{$2=='tar' ? 'tgz' : $2}" oarg="-o #{tgz}" else oarg='-O' #use the filename that curl gets tgz=File.expand_path File.basename(@url) end unless File.exists? tgz `curl -#LA "#{HOMEBREW_USER_AGENT}" #{oarg} "#{@url}"` raise "Download failed" unless $? == 0 else puts "File already downloaded and cached" end return tgz end end # somewhat useful, it'll raise if you call prefix, but it'll unpack a tar/zip # for you, check the md5, and allow you to yield from brew class UnidentifiedFormula