# Copyright 2009 Max Howell and other contributors. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # def make url 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 path.exist? template=<<-EOS require 'brewkit' class #{Formula.class_s $1} 1 puts end else puts "Not installed" end if f.caveats puts puts f.caveats puts end puts history rescue FormulaUnavailableError # check for DIY installation d=HOMEBREW_PREFIX+name if d.directory? ohai "DIY Installation" d.children.each {|keg| puts "#{keg} (#{keg.abv})"} else raise "No such formula or keg" end end def clean f Cleaner.new f # Hunt for empty folders and nuke them unless they are # protected by f.skip_clean? # We want post-order traversal, so put the dirs in a stack # and then pop them off later. paths = [] f.prefix.find do |path| paths << path if path.directory? end until paths.empty? do d = paths.pop if d.children.empty? and not f.skip_clean? d puts "rmdir: #{d} (empty)" if ARGV.verbose? d.rmdir end end end def expand_deps ff deps = [] ff.deps.collect do |f| deps += expand_deps(Formula.factory(f)) end deps << ff end def prune $n=0 $d=0 dirs=Array.new paths=%w[bin sbin etc lib include share].collect {|d| HOMEBREW_PREFIX+d} paths.each do |path| path.find do |path| path.extend ObserverPathnameExtension if path.symlink? path.unlink unless path.resolved_path_exists? elsif path.directory? dirs< 0 puts "from #{HOMEBREW_PREFIX}" end end def diy path=Pathname.getwd if ARGV.include? '--set-version' version=ARGV.next else version=path.version raise "Couldn't determine version, try --set-version" if version.nil? or version.empty? end if ARGV.include? '--set-name' name=ARGV.next else path.basename.to_s =~ /(.*?)-?#{version}/ if $1.nil? or $1.empty? name=path.basename else name=$1 end end prefix=HOMEBREW_CELLAR+name+version if File.file? 'CMakeLists.txt' "-DCMAKE_INSTALL_PREFIX=#{prefix}" elsif File.file? 'Makefile.am' "--prefix=#{prefix}" end end def fix_PATH bad_paths = `/usr/bin/which -a port`.split bad_paths += `/usr/bin/which -a fink`.split # don't remove standard paths! bad_paths.delete_if do |pn| %w[/usr/bin /bin /usr/sbin /sbin /usr/local/bin /usr/X11/bin].include? pn or pn.empty? end bad_paths += %w[/opt/local/bin /opt/local/sbin /sw/bin /sw/sbin] paths = ENV['PATH'].split(':').reject do |p| p.squeeze! '/' bad_paths.find { |pn| p =~ /^#{pn}/ } and true end ENV['PATH'] = paths*':' end ########################################################## class PrettyListing class PrettyListing def initialize path Pathname.new(path).children.sort{ |a,b| a.to_s.downcase <=> b.to_s.downcase }.each do |pn| case pn.basename.to_s when 'bin', 'sbin' pn.find { |pnn| puts pnn unless pnn.directory? } when 'lib' print_dir pn do |pnn| # dylibs have multiple symlinks and we don't care about them (pnn.extname == '.dylib' or pnn.extname == '.pc') and not pnn.symlink? end else print_dir pn end end end private def print_dir root return unless root.directory? dirs = [] remaining_root_files = [] other = '' root.children.sort.each do |pn| if pn.directory? dirs << pn elsif block_given? and yield pn puts pn other = 'other ' else remaining_root_files << pn end end dirs.each do |d| files = [] d.find { |pn| files << pn unless pn.directory? } print_remaining_files files, d end print_remaining_files remaining_root_files, root, other end def print_remaining_files files, root, other = '' case files.length when 0 # noop when 1 puts *files else puts "#{root} (#{files.length} #{other}files)" end end end ################################################################ class Cleaner class Cleaner def initialize f @f=f # correct common issues share=f.prefix+'share' (f.prefix+'man').mv share rescue nil [f.bin, f.sbin, f.lib].each {|d| clean_dir d} # you can read all of this stuff online nowadays, save the space # info pages are pants, everyone agrees apart from Richard Stallman # feel free to ask for build options though! http://bit.ly/Homebrew (f.prefix+'share'+'doc').rmtree rescue nil (f.prefix+'share'+'info').rmtree rescue nil (f.prefix+'doc').rmtree rescue nil (f.prefix+'docs').rmtree rescue nil (f.prefix+'info').rmtree rescue nil end private def strip path, args='' return if @f.skip_clean? path puts "strip #{path}" if ARGV.verbose? path.chmod 0644 # so we can strip unless path.stat.nlink > 1 `strip #{args} #{path}` else # strip unlinks the file and recreates it, thus breaking hard links! # is this expected behaviour? patch does it too… still, this fixes it tmp=`mktemp -t #{path.basename}`.strip `strip #{args} -o #{tmp} #{path}` `cat #{tmp} > #{path}` File.unlink tmp end end def clean_file path perms=0444 case `file -h #{path}` when /Mach-O dynamically linked shared library/ strip path, '-SxX' when /Mach-O [^ ]* ?executable/ strip path perms=0555 when /script text executable/ perms=0555 end path.chmod perms end def clean_dir d d.find do |path| if path.directory? Find.prune if @f.skip_clean? path elsif not path.file? next elsif path.extname == '.la' and not @f.skip_clean? path # *.la files are stupid path.unlink else clean_file path end end end end