# 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 Formula.path name end attr_reader :url, :version, :url, :homepage, :name 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 info; prefix+'share'+'info' end def include; prefix+'include' end # tell the user about any caveats regarding this package def caveats; nil end # patches are automatically applied after extracting the tarball 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 ohai "Downloading #{@url}" tgz=HOMEBREW_CACHE+File.basename(@url) unless tgz.exist? HOMEBREW_CACHE.mkpath curl @url, '-o', tgz else puts "File already downloaded and cached" end verify_download_integrity tgz mktemp do Dir.chdir uncompress(tgz) 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 end end 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 def mktemp tmp=Pathname.new `mktemp -dt #{File.basename @url}`.strip raise if not tmp.directory? or $? != 0 begin wd=Dir.pwd Dir.chdir tmp yield ensure Dir.chdir wd tmp.rmtree end end # Kernel.system but with exceptions def safe_system cmd, *args puts "#{cmd} #{args*' '}" if ARGV.verbose? # stderr is shown, so hopefully that will explain the problem raise ExecutionError.new(cmd, args) unless Kernel.system cmd, *args and $? == 0 end def curl url, *args safe_system 'curl', '-f#LA', HOMEBREW_USER_AGENT, url, *args 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 patch unless patches.empty? ohai "Patching" ff=(1..patches.length).collect {|n| '%03d-homebrew.patch'%n} curl *patches+ff.collect {|f|"-o#{f}"} ff.each {|f| safe_system 'patch', '-p0', '-i', f} end end class <