# 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 . # class ExecutionError 0 rescue return false end def prefix validate_variable :name validate_variable :version HOMEBREW_CELLAR+@name+@version end def path self.class.path name end attr_reader :url, :version, :homepage, :name def bin; prefix+'bin' end def sbin; prefix+'sbin' end def doc; prefix+'share'+'doc'+name end def lib; prefix+'lib' end def libexec; prefix+'libexec' end def man; prefix+'share'+'man' end def man1; man+'man1' end def info; prefix+'share'+'info' end def include; prefix+'include' end # reimplement if we don't autodetect the download strategy you require def download_strategy case url when %r[^svn://] then SubversionDownloadStrategy when %r[^git://] then GitDownloadStrategy when %r[^http://(.+?\.)?googlecode\.com/svn] then SubversionDownloadStrategy else HttpDownloadStrategy end end # tell the user about any caveats regarding this package def caveats; nil end # patches are automatically applied after extracting the tarball # return an array of strings, or if you need a patch level other than -p0 # return a Hash eg. # { # :p0 => ['http://foo.com/patch1', 'http://foo.com/patch2'], # :p1 => 'http://bar.com/patch2', # :p2 => ['http://moo.com/patch5', 'http://moo.com/patch6'] # } def patches; [] end # reimplement and specify dependencies def deps; end # sometimes the clean process breaks things, return true to skip anything def skip_clean? path; false end # yields self with current working directory set to the uncompressed tarball def brew validate_variable :name validate_variable :version stage do begin patch yield self rescue Interrupt, RuntimeError, SystemCallError => e raise unless ARGV.debug? onoe e.inspect puts e.backtrace ohai "Rescuing build..." puts "When you exit this shell Homebrew will attempt to finalise the installation." puts "If nothing is installed or the shell exits with a non-zero error code," puts "Homebrew will abort. The installation prefix is:" puts prefix interactive_shell end end 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 self.class name #remove invalid characters and camelcase name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase } end def self.factory name require self.path(name) return eval(self.class(name)).new(name) rescue LoadError raise FormulaUnavailableError.new(name) end def self.path name HOMEBREW_PREFIX+'Library'+'Formula'+"#{name.downcase}.rb" end protected # Pretty titles the command and buffers stdout/stderr # Throws if there's an error def system cmd, *args full="#{cmd} #{args*' '}".strip ohai full if ARGV.verbose? safe_system cmd, *args else out='' # TODO write a ruby extension that does a good popen :P IO.popen "#{full} 2>&1" do |f| until f.eof? out+=f.gets end end unless $? == 0 puts out raise end end rescue raise BuildError.new(cmd, args) end private # creates a temporary directory then yields, when the block returns it # recursively deletes the temporary directory def mktemp # I used /tmp rather than mktemp -td because that generates a directory # name with exotic characters like + in it, and these break badly written # scripts that don't escape strings before trying to regexp them :( tmp=Pathname.new `mktemp -d /tmp/homebrew-#{name}-#{version}-XXXX`.strip raise "Couldn't create build sandbox" if not tmp.directory? or $? != 0 begin wd=Dir.pwd Dir.chdir tmp yield ensure Dir.chdir wd tmp.rmtree end 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 and not supplied.empty? 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 def stage ds=download_strategy.new url, name, version HOMEBREW_CACHE.mkpath dl=ds.fetch verify_download_integrity dl if dl.kind_of? Pathname mktemp do ds.stage yield end end def patch return if patches.empty? ohai "Patching" if patches.kind_of? Hash patch_args=[] curl_args=[] n=0 patches.each do |arg, urls| urls.each do |url| dst='%03d-homebrew.patch' % n+=1 curl_args<