From 760c083c0c0c9934e4118b4669c8c8dfd0a3587d Mon Sep 17 00:00:00 2001
From: Max Howell
Date: Mon, 10 Aug 2009 16:48:30 +0100
Subject: Refactor
Large refactor to Formula, mostly improving reliability and error handling but
also layout and readability.
General improvements so testing can be more complete.
Patches are automatically downloaded and applied for Formula that return a
list of urls from Formula::patches.
Split out the brew command logic to facilitate testing.
Facility from Adam Vandenberg to allow selective cleaning of files, added
because Python doesn't work when stripped.
---
Library/Homebrew/formula.rb | 315 +++++++++++++++++++++++---------------------
1 file changed, 166 insertions(+), 149 deletions(-)
(limited to 'Library/Homebrew/formula.rb')
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
index 4f02e2077..f01798eba 100644
--- a/Library/Homebrew/formula.rb
+++ b/Library/Homebrew/formula.rb
@@ -15,30 +15,31 @@
# You should have received a copy of the GNU General Public License
# along with Homebrew. If not, see .
-require 'utils'
-class BuildError 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
- ohai cmd
- if ARGV.include? '--verbose'
- Kernel.system cmd
+ def system cmd, *args
+ full="#{cmd} #{args*' '}".strip
+ ohai full
+ if ARGV.verbose?
+ safe_system cmd, *args
else
out=''
- IO.popen "#{cmd} 2>&1" do |f|
+ # 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
- puts out unless $? == 0
+ unless $? == 0
+ puts out
+ raise
+ end
end
+ rescue
+ raise BuildError.new(cmd, args)
+ end
- raise BuildError.new(cmd) unless $? == 0
+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
- # 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"
+ # 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'
@@ -110,7 +165,7 @@ public
supplied=eval "@#{type.downcase}"
hash=eval("Digest::#{type}").hexdigest(fn.read)
- if supplied
+ if supplied and not supplied.empty?
raise "#{type} mismatch: #{hash}" unless supplied.upcase == hash.upcase
else
opoo "Cannot verify package integrity"
@@ -119,91 +174,69 @@ public
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
+ 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 <