# 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 raise "Invalid @name" if @name.nil? or @name.empty? raise "Invalid @version" if @version.nil? or @version.empty? 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 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 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 "Type `exit' and Homebrew will attempt to finalize the installation" puts "If nothing is installed to #{prefix}, then Homebrew will abort" interactive_shell raise "Non-zero exit status, installation aborted" if $? != 0 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 tmp=Pathname.new `mktemp -dt #{name}-#{version}`.strip raise 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<