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. --- bin/brew | 349 ++++++++++++++++----------------------------------------------- 1 file changed, 89 insertions(+), 260 deletions(-) (limited to 'bin') diff --git a/bin/brew b/bin/brew index 6af4460ac..d4162986a 100755 --- a/bin/brew +++ b/bin/brew @@ -1,306 +1,135 @@ #!/usr/bin/ruby -$:.unshift __FILE__+'/../../Library/Homebrew' -require 'env' -require 'find' - -PRISTINE_ARGV=ARGV.dup +$:.unshift ENV['RUBYLIB']=File.expand_path(__FILE__+'/../../Library/Homebrew') + +require 'pathname+yeast' +require 'ARGV+yeast' +require 'utils' +require 'brew.h' + +# TODO if whoami == root then use /Library/Caches/Homebrew instead +HOMEBREW_CACHE=Pathname.new("~/Library/Caches/Homebrew").expand_path +HOMEBREW_PREFIX=Pathname.new(__FILE__).dirname.parent.cleanpath +HOMEBREW_CELLAR=HOMEBREW_PREFIX+'Cellar' +HOMEBREW_VERSION='0.4' +HOMEBREW_WWW='http://bit.ly/Homebrew' HOMEBREW_USER_AGENT="Homebrew #{HOMEBREW_VERSION} (Ruby #{VERSION}; Mac OS X 10.5 Leopard)" -# often causes Ruby to throw exception ffs -Dir.chdir '/' unless File.directory? ENV['PWD'] - -######################################################################## funcs -# remove symlinks that no longer point to files -def prune - n=0 - dirs=Array.new - HOMEBREW_PREFIX.find do |path| - if path.directory? - name=path.relative_path_from(HOMEBREW_PREFIX).to_s - if name == '.git' or name == 'Cellar' or name == 'Library' - Find.prune - else - dirs< brew #{PRISTINE_ARGV.join ' '} wget" if args.empty? - return args -end - -def extract_kegs - require 'keg' - kegs=extract_named_args.collect {|name| Keg.new name} - return kegs -end - -def abv keg=nil - path=keg ? keg.path : HOMEBREW_CELLAR - if path.directory? - `find #{path} -type f | wc -l`.strip+' files, '+`du -hd0 #{path} | cut -d"\t" -f1`.strip - else - '' - end -end - -def install formula - require 'keg' - - beginning = Time.now - - formula.brew do - if ARGV.include? '--interactive' - ohai "Entering interactive mode" - puts "Type `exit' to return and finalize the installation" - puts "Install to this prefix: #{formula.prefix}" - pid=fork - if pid.nil? - exec 'bash' - else - Process.wait pid - end - elsif ARGV.include? '--help' - ohai './configure --help' - puts `./configure --help` - exit - else - formula.prefix.mkpath - formula.install - %w[README ChangeLog COPYING LICENSE COPYRIGHT AUTHORS].each do |file| - formula.prefix.install file if File.file? file - end - end - end - - raise "Nothing was installed to #{formula.prefix}" unless formula.installed? - - ohai 'Finishing up' - keg=Keg.new formula - keg.clean - keg.ln - if formula.caveats - ohai "Caveats" - puts formula.caveats - ohai "Summary" - end - puts "#{keg.path}: "+abv(keg)+", built in #{pretty_duration Time.now-beginning}" -rescue Exception - formula.prefix.rmtree if formula.prefix.directory? - raise -end - -def mk url, mode='make' - require 'formula' - path=Pathname.new(url) - - /(.*?)[-_.]?#{path.version}/.match path.basename - raise "Couldn't parse name from #{url}" if $1.nil? or $1.empty? - - path=Formula.path $1 - raise "#{path} already exists!" if File.exist? path - - f=File.new path, 'w' - f.puts "require 'brewkit'" - f.puts - f.puts "class #{Formula.class $1} #{f.prefix}" if f.installed? unless ARGV.include? '--force' - install f + require 'keg' + ARGV.formulae.each do |f| + raise "#{f.name} is already installed" if f.installed? unless ARGV.force? + start_time=Time.now + begin + install f + if f.caveats + ohai "Caveats" + puts f.caveats + puts + end + ohai 'Finishing up' + clean f + raise "Nothing was installed to #{f.prefix}" unless f.installed? + Keg.new(f.prefix).link + rescue + f.prefix.rmtree if f.prefix.directory? + raise + end + puts "#{f.prefix}: "+f.prefix.abv+", built in #{pretty_duration Time.now-start_time}" end when 'ln', 'link' - n=0 - (kegs=extract_kegs).each do |keg| - n+=nn=keg.ln - puts "Created #{nn} links for #{keg.name}" if kegs.length > 1 - end - puts "Created #{n} links" + ARGV.kegs.each {|keg| puts "#{keg.link} links created for #{keg}"} + + when 'unlink' + ARGV.kegs.each {|keg| puts "#{keg.unlink} links removed for #{keg}"} - when 'rm', 'uninstall' - extract_kegs.each do |keg| - puts "Removing #{keg.name}..." - keg.rm + when 'rm', 'uninstall', 'remove' + ARGV.kegs.each do |keg| + puts "Uninstalling #{keg}..." + keg.uninstall end - print "Pruning #{prefix}/..." - puts " #{prune} symbolic links pruned" + prune + + when 'up', 'update' + puts "Reserved command" when 'prune' - puts "Pruned #{prune} symbolic links" + prune when 'mk', 'make' - mode = "make" - if ARGV.length > 0 - if ARGV[0] == '--cmake' - ARGV.shift - mode = "cmake" - end - end - - paths=ARGV.collect {|arg| mk arg, mode} - if paths.empty? - raise "Invalid URL" - elsif Kernel.system "which mate > /dev/null" and $? == 0 - paths=paths.collect {|path| path.to_s.gsub " ", "\\ "} - exec "mate #{paths.join ' '}" + if ARGV.include? '--macports' + exec "open", "http://www.macports.org/ports.php?by=name&substr=#{ARGV.next}" else - puts paths.join("\n") + exec "mate", *ARGV.named.collect {|name| make name} end when 'info', 'abv' - if ARGV.empty? - puts `ls #{HOMEBREW_CELLAR} | wc -l`.strip+" kegs, "+abv + if ARGV.named.empty? + puts `ls #{HOMEBREW_CELLAR} | wc -l`.strip+" kegs, "+HOMEBREW_CELLAR.abv elsif ARGV[0][0..6] == 'http://' puts Pathname.new(ARGV.shift).version else - require 'formula' - #TODO show outdated status and that - frm=Formula.create(extract_named_args[0]) - puts "#{frm.name} #{frm.version}" - puts frm.homepage - if frm.installed? - require 'keg' - keg=Keg.new frm - puts "#{abv keg} (installed to #{keg.path})" - end - if frm.caveats - ohai 'Caveats' - puts frm.caveats - end + ARGV.named.each {|name| info name} end else - puts usage + puts ARGV.usage end -rescue StandardError, Interrupt => e - if ARGV.include? '--verbose' or ENV['HOMEBREW_DEBUG'] - raise - elsif e.kind_of? Interrupt - puts # seeimgly a newline is typical - exit 130 - elsif e.kind_of? StandardError and not e.kind_of? NameError - puts "\033[1;31mError\033[0;0m: #{e}" - exit 1 +rescue SystemExit + ohai "Kernel.exit" if ARGV.verbose? +rescue Interrupt => e + puts # seemingly a newline is typical + exit 130 +rescue SystemCallError, RuntimeError => e + if ARGV.verbose? or ARGV.debug? + onoe e.inspect + puts e.backtrace else - raise + onoe e end + exit 1 +rescue Exception => e + onoe "Homebrew has failed you :(" + puts "Please report this bug at: #{HOMEBREW_WWW}" + puts "Please include this backtrace:" + ohai e.inspect + puts e.backtrace end -- cgit v1.2.3