diff --git a/Cellar/homebrew/brew b/Cellar/homebrew/brew index d857c60687..9782c4edd4 100755 --- a/Cellar/homebrew/brew +++ b/Cellar/homebrew/brew @@ -3,7 +3,10 @@ # Licensed as per the GPL version 3 require 'find' require 'pathname' -$root = Pathname.new(__FILE__).realpath.dirname.parent.parent +$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" +$root=Pathname.new(__FILE__).realpath.dirname.parent.parent +$formula=$root+'Formula' +$cellar=$root+'Cellar' def prune n=0 @@ -25,95 +28,224 @@ def prune end end # entries lists '.' and '..' so 2 is minimum basically - dirs.sort.reverse_each { |d| d.rmdir if d.children.length == 0 } + dirs.sort.reverse_each do |d| + if d.children.length == 0 + d.rmdir + n+=1 + end + end return n end -case ARGV[0] - when 'brew', 'install' then - abort "You must specify a Formula" unless ARGV[1] - ARGV.shift - file="#{$root}/Formula/#{ARGV.shift}" - file+='.rb' unless File.exist? file - system "ruby #{file} #{ARGV.join ' '}" +def shift_formulae + name=Pathname.new ARGV.shift - when 'rm', 'uninstall' then - path=$root+'Cellar'+ARGV[1] - abort "#{ARGV[1]} is not installed" unless path.directory? - path.rmtree - prune - puts "#{path} removed" + return name if name.directory? and name.parent.realpath == $cellar + return File.basename(name, '.rb') if name.file? and name.extname == '.rb' and name.parent.realpath == $formula - when 'ln' then - target=Pathname.new(ARGV[1]) - target=$root+'Cellar'+target unless target.exist? + name=name.to_s + raise "#{name} is an invalid name for a formula" if name.include? '/' - abort "#{target} is not a directory" unless target.directory? + return name if ($formula+(name+'.rb')).file? + return name if ($cellar+name).directory? - target=target.realpath + raise "No formula or keg for #{name} found" +end - if target.parent.parent == $root - # we are one dir too high - kids=target.children - abort "#{target} is empty :(" if kids.length == 0 - abort "There are multiple versions of #{target.basename} installed please specify one" if kids.length > 1 - target=target.children.first - abort "#{target} is not a directory!" unless target.directory? - elsif target.parent.parent.parent != $root - abort '#{target} is not a keg' - end +def __class name + #remove invalid characters and camelcase + name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase } +end - #TODO you should mkdirs as you find them and symlink files otherwise - #TODO consider using hardlinks +def __rb name + $formula+(name+'.rb') +end - n=0 - target.find do |from| - next if from == ARGV[1] #rubysucks +def __obj name + require "#{__rb name}" + o=eval(__class(name)).new + o.name=name + return o +end - to=$root+from.relative_path_from(target) +def rm keg + #TODO if multiple versions don't rm all unless --force + path=$cellar+keg + path.rmtree + puts "#{path} removed (#{prune} files)" +end - if from.directory? - to.mkpath unless to.exist? - elsif from.file? - tod=to.dirname - Dir.chdir(tod) do - `ln -sf "#{from.relative_path_from tod}"` - n+=1 - end - end - end - puts "Created #{n} links" +def ln name + keg=$cellar+name + keg=keg.realpath - when 'abv', 'stats', 'statistics' - cellar=$root+'Cellar' - print `find #{cellar} -type f | wc -l`.strip+' files, '+`du -hd0 #{cellar} | cut -d"\t" -f1`.strip + if keg.parent.parent == $root + # we are one dir too high + kids=keg.children + raise "#{keg} is empty :(" if kids.length == 0 + raise "There are multiple versions of #{keg.basename} installed please specify one" if kids.length > 1 + keg=keg.children.first + raise "#{keg} is not a directory" unless keg.directory? + elsif keg.parent.parent.parent != $root + raise '#{keg} is not a keg' + end - when 'prune', 'pasteurize' then - puts "Pruned #{prune} files" + #TODO consider using hardlinks - when 'prefix' - # Get the clean path to $prefix/Cellar/homebrew/brew/../../../ - # Don't resolve any symlinks of that final result. - # Rationale: if the user calls /usr/local/bin/brew but that will resolve - # to /Brewery/Cellar/homebrew/brew we should give /usr/local and not - # /Brewery because the user probably has chosen /usr/local as the Homebrew - # to expose to the system. - if File.symlink? __FILE__ - # using pathname as it will handle readlink returning abs or rel paths - d=Pathname.new(__FILE__).dirname - puts File.expand_path(d+File.readlink(__FILE__)+'../../../') + # yeah indeed, you have to force anything you want in the main tree into + # these directories :P + $n=0 + lnd(keg, 'etc') {nil} + lnd(keg, 'include') {nil} + + lnd(keg, 'lib') do |path| + :mkpath if ['pkgconfig','php'].include? path.to_s + end + + lnd(keg, 'bin') do |path| + if path.extname.to_s == '.app' + # no need to put .app bundles in the path, just use spotlight, or the + # open command + :skip else - # Dir.pwd resolves the symlink :P #rubysucks - # we use the cwd because __FILE__ can be relative and expand_path - # resolves the symlink for the working directory if fed a relative path - # SIGH - cwd=Pathname.new `pwd`.strip - puts File.expand_path(cwd+__FILE__+'../../../') + :mkpath end + end - when 'cache' - puts File.expand_path('~/Library/Application Support/Homebrew') + lnd(keg, 'share') do |path| + path=path.to_s + if ['man','doc','locale','info'].include? path + :mkpath + else + mans=(1..9).collect {|x| "man/man#{x}"} + :mkpath if mans.include? path + end + end + return $n +end + +def symlink_relative_to from, to + tod=to.dirname + tod.mkpath + Dir.chdir(tod) do + #TODO use ruby function so we get exceptions + `ln -sf "#{from.relative_path_from tod}"` + $n+=1 + end +end + +# symlinks a directory recursively into our FHS tree +def lnd keg, start + start=keg+start + return unless start.directory? + + start.find do |from| + next if from == start + + prune=false + relative_path=from.relative_path_from keg + to=$root+relative_path + + if from.directory? + cmd=yield from.relative_path_from(start) + + if :skip == cmd + Find.prune + elsif :mkpath == cmd + to.mkpath + $n+=1 + else + symlink_relative_to from, to + Find.prune + end + elsif from.file? + symlink_relative_to from, to + end + end +end + +def prefix + # Get the clean path to $prefix/Cellar/homebrew/brew/../../../ + # Don't resolve any symlinks of that final result. + # Rationale: if the user calls /usr/local/bin/brew but that will resolve + # to /Brewery/Cellar/homebrew/brew we should give /usr/local and not + # /Brewery because the user probably has chosen /usr/local as the Homebrew + # to expose to the system. + if File.symlink? __FILE__ + # using pathname as it will handle readlink returning abs or rel paths + d=Pathname.new(__FILE__).dirname + File.expand_path(d+File.readlink(__FILE__)+'../../../') else - puts "usage: #{$0} [prune] [ln path] [install pkg]" + # Dir.pwd resolves the symlink :P #rubysucks + # we use the cwd because __FILE__ can be relative and expand_path + # resolves the symlink for the working directory if fed a relative path + # SIGH + cwd=Pathname.new `pwd`.strip + File.expand_path(cwd+__FILE__+'../../../') + end +end + +def usage + name=File.basename $0 + <<-EOS +Usage: #{name} [abv] [prune] [--prefix] [--cache] +Usage: #{name} [install] [ln] [rm] [info] [list] beverage + EOS +end + +######################################################################### impl +begin + #TODO proper options parsing so --options can go first if necessary + + case ARGV.shift + when 'abv' + `find #{$cellar} -type f | wc -l`.strip+' files, '+`du -hd0 #{$cellar} | cut -d"\t" -f1`.strip + when 'prune' + puts "Pruned #{prune} files" + when '--prefix' + puts prefix + when '--cache' + puts File.expand_path('~/Library/Application Support/Homebrew') + when '-h', '--help', '--usage', '-?' + puts usage + when '-v', '--version' + puts HOMEBREW_VERSION + when 'list' + puts `find #{$cellar+shift_formulae}` + when 'install' + name=shift_formulae + beginning = Time.now + o=__obj(name) + raise "#{o.prefix} already exists!" if o.prefix.exist? + o.brew { o.install } + ln name + puts "#{o.prefix}: "+`find #{o.prefix} -type f | wc -l`.strip+ + ' files, '+ + `du -hd0 #{o.prefix} | cut -d"\t" -f1`.strip+ + ", built in #{Time.now - beginning} seconds" + when 'ln' + puts "Created #{ln shift_formulae} links" + when 'rm' + rm shift_formulae + when 'info' + o=__obj shift_formulae + puts "#{o.name} #{o.version}" + puts o.homepage + else + puts 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 + else + raise + end end \ No newline at end of file diff --git a/Cellar/homebrew/brewkit.rb b/Cellar/homebrew/brewkit.rb index f0daa48c82..b19cfcf66b 100644 --- a/Cellar/homebrew/brewkit.rb +++ b/Cellar/homebrew/brewkit.rb @@ -2,8 +2,7 @@ # Licensed as per the GPL version 3 require 'pathname' -$agent = "Homebrew 0.1 (Ruby; Mac OS X 10.5 Leopard)" -$cellar = Pathname.new(__FILE__).dirname.parent.realpath +HOMEBREW_VERSION='0.1' # optimise all the way to eleven, references: # http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel @@ -18,9 +17,9 @@ ENV['CC']='gcc-4.2' ENV['CXX']='g++-4.2' ENV['MAKEFLAGS']='-j2' -unless $cellar.parent.to_s == '/usr/local' - ENV['CPPFLAGS']="-I#{$cellar.parent}/include" - ENV['LDFLAGS']="-L#{$cellar.parent}/lib" +unless $root.to_s == '/usr/local' + ENV['CPPFLAGS']='-I'+$root+'include' + ENV['LDFLAGS']='-L'+$root+'lib' end @@ -35,21 +34,59 @@ def appsupport return appsupport end + +# make our code neater +class Pathname + def mv dst + FileUtils.mv to_s, dst + end + def cp dst + if file? + FileUtils.cp to_s, dst + else + FileUtils.cp_r to_s, dst + end + end +end + + class Formula require 'find' require 'fileutils' - # if you reimplement, assign @name, @version, @url and @md5 - def initialize(url, md5) - @name = File.basename $0, '.rb' #original script that the interpreter started - @url = url - @md5 = md5 + # fuck knows, ruby is weird + def self.url + @url + end + def url + self.class.url + end + def self.md5 + @md5 + end + def md5 + self.class.md5 + end + def self.homepage + @homepage + end + def homepage + self.class.homepage + end + # end ruby is weird section + + def initialize + # fuck knows, ruby is weird + @url=url if @url.nil? + raise "@url.nil?" if @url.nil? + @md5=md5 if @md5.nil? + # end ruby is weird section # pls improve this version extraction crap - filename=File.basename url + filename=File.basename @url i=filename.index /[-_]\d/ unless i.nil? - /^((\d+[._])*(\d+-)?\d+)/.match filename[i+1,1000] #1000 because rubysucks + /^((\d+[._])*(\d+-)?\d+[abc]?)/.match filename[i+1,1000] #1000 because rubysucks @version=$1 # if there are no dots replace underscores, boost do this, the bastards! @version.gsub!('_', '.') unless @version.include? '.' @@ -59,26 +96,57 @@ class Formula @version = $1 end end + +private + def maybe_mkpath path + path.mkpath unless path.exist? + return path + end +public + def prefix + raise "@name.nil!" if @name.nil? + raise "@version.nil?" if @version.nil? + $cellar+@name+@version + end + def bin + maybe_mkpath prefix+'bin' + end + def doc + maybe_mkpath prefix+'share'+'doc'+name + end + def man + maybe_mkpath prefix+'share'+'man' + end + def lib + maybe_mkpath prefix+'lib' + end + def include + maybe_mkpath prefix+'include' + end + + def name=name + raise "Name assigned twice, I'm not letting you do that!" if @name + @name=name + end + +protected + def caveats + nil + end + +public #yields a Pathname object for the installation prefix def brew - raise "@name.nil?" if @name.nil? - raise "@version.nil?" if @version.nil? - # disabled until the regexp makes sense :P #raise "@name does not validate to our regexp" unless /^\w+$/ =~ @name - beginning = Time.now - - prefix=$cellar+@name+@version - raise "#{prefix} already exists!" if prefix.exist? - ohai "Downloading #{@url}" Dir.chdir appsupport do tgz=Pathname.new(fetch()).realpath md5=`md5 -q "#{tgz}"`.strip - raise "MD5 mismatch: #{md5}" unless md5 == @md5.downcase + raise "MD5 mismatch: #{md5}" unless md5 and md5 == @md5.downcase # we make an additional subdirectory so know exactly what we are # recursively deleting later @@ -86,26 +154,27 @@ class Formula # can't handle being built in a directory with spaces in it :P tmp=nil begin - tmp=`mktemp -dt #{@name}-#{@version}`.strip + tmp=`mktemp -dt #{File.basename @url}`.strip Dir.chdir tmp do Dir.chdir uncompress(tgz) do - caveats = yield prefix + prefix.mkpath + yield self if caveats ohai "Caveats" puts caveats - ohai "Summary" end #TODO copy changelog or CHANGES file to pkg root, #TODO maybe README, etc. to versioned root end end - rescue + 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 + FileUtils.rm_rf prefix raise end ensure @@ -115,27 +184,26 @@ class Formula ohai 'Finishing up' - # stay in appsupport in case any odd files gets created etc. - `#{$cellar}/homebrew/brew ln #{prefix}` if prefix.exist? - prefix.find do |path| if path==prefix #rubysucks next elsif path.file? - fo=`file -h #{path}` - args=nil - args='-SxX' if fo =~ /Mach-O dynamically linked shared library/ - args='' if fo =~ /Mach-O executable/ #defaults strip everything - if args - puts "Stripping: #{path}" if ARGV.include? '--verbose' - `strip #{args} #{path}` + if path.extname == '.la' + path.unlink + else + fo=`file -h #{path}` + args=nil + args='-SxX' if fo =~ /Mach-O dynamically linked shared library/ + args='' if fo =~ /Mach-O executable/ #defaults strip everything + if args + puts "Stripping: #{path}" if ARGV.include? '--verbose' + `strip #{args} #{path}` + end end elsif path.directory? and path!=prefix+'bin' and path!=prefix+'lib' Find.prune end end - - puts "#{prefix}: "+`find #{prefix} -type f | wc -l`.strip+' files, '+`du -hd0 #{prefix} | cut -d"\t" -f1`.strip+", built in #{Time.now - beginning} seconds" end end @@ -159,8 +227,10 @@ protected tgz=File.expand_path File.basename(@url) end + agent="Homebrew #{HOMEBREW_VERSION} (Ruby #{VERSION}; Mac OS X 10.5 Leopard)" + unless File.exists? tgz - `curl -#LA "#{$agent}" #{oarg} "#{@url}"` + `curl -#LA "#{agent}" #{oarg} "#{@url}"` raise "Download failed" unless $? == 0 else puts "File already downloaded and cached" @@ -178,9 +248,15 @@ protected raise "Compression tool failed" if $? != 0 entries=Dir['*'] - raise "Empty tar!" if entries.nil? or entries.length == 0 - raise "Too many folders in uncompressed result. You need to reimplement the Recipe.uncompress function." if entries.length > 1 - return entries.first + if entries.nil? or entries.length == 0 + raise "Empty tarball!" + elsif entries.length == 1 + # if one dir enter it as that will be where the build is + entries.first + else + # if there's more than one dir, then this is the build directory already + Dir.pwd + end end def cache? @@ -193,22 +269,21 @@ private end end -# you have to reimplement initialize to set the version, for example usage -# see the ack script -class UncompressedScriptFormula < Formula - def initialize(url) - @url=url - @name=File.basename url - end +# see ack.rb for an example usage +class UncompressedScriptFormula e - # this is not an error, cook will throw as nothing was installed - raise unless e.errno == Errno::ENOENT + TestFormula.new(url, md5).brew do |f| + prefix=f.prefix + # we test for +/unittest/0.1 because we derive @name from $0 + assert_equal File.expand_path(prefix), ($cellar+'test'+'0.1').to_s + assert_kind_of Pathname, prefix end end end \ No newline at end of file diff --git a/Formula/__template.rb b/Formula/__template.rb deleted file mode 100644 index 2d7ba24070..0000000000 --- a/Formula/__template.rb +++ /dev/null @@ -1,11 +0,0 @@ -$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks -require 'brewkit' - -homepage='' -url='' -md5='' # leave this blank and brewkit will error out, but show you the md5 - -Formula.new(url, md5).brew do |prefix| - system "./configure --disable-debug --prefix='#{prefix}'" - system "make install" # if this fails, split into two steps -end \ No newline at end of file diff --git a/Formula/ack.rb b/Formula/ack.rb index b27d827ac2..4bab09c89e 100644 --- a/Formula/ack.rb +++ b/Formula/ack.rb @@ -1,22 +1,10 @@ -$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks require 'brewkit' -require 'fileutils' -homepage='http://betterthangrep.com/' - -class AckFormula < UncompressedScriptFormula +class Ack > ~/.profile - <<-nruter -grc won't work as is. One option is to add some aliases to your ~/.profile -file. Homebrew can do that for you, just execute this command: - - ruby #{$0} --profile >> ~/.profile - -nruter -end + EOS + end +end \ No newline at end of file diff --git a/Formula/lame.rb b/Formula/lame.rb index 8bbf7b3d8f..2c248285c5 100644 --- a/Formula/lame.rb +++ b/Formula/lame.rb @@ -1,11 +1,12 @@ -$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks require 'brewkit' -homepage='http://lame.sourceforge.net/' -url='http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz' -md5='719dae0ee675d0c16e0e89952930ed35' +class Lame > src/#{makefile}` } + end + + configure=<<-EOS + ./configure -prefix '#{prefix}' + -system-sqlite -system-libpng -system-zlib + -nomake demos -nomake examples -no-qt3support + -release -cocoa -arch x86 + -confirm-license -opensource + -I /usr/X11R6/include -L /usr/X11R6/lib + -fast + EOS + + system configure.gsub("\n", ' ').strip.squeeze(' ') + system "make install" + + # fuck weird prl files + `find #{lib} -name \*.prl -delete` + # fuck crazy disk usage + `rm -r #{prefix+'doc'+'html'} #{prefix+'doc'+'src'}` + # wtf are these anyway? + `rm -r #{bin}/Assistant_adp.app #{bin}/pixeltool.app #{bin}/qhelpconverter.app` + # we specified no debug already! :P + `rm #{lib}/libQtUiTools_debug.a` + # meh + `rm #{prefix}/q3porting.xml` + end + + def caveats + "We agreed to the Qt opensource license for you.\nIf this is unacceptable you should uninstall :P" + end +end \ No newline at end of file diff --git a/Formula/taglib.rb b/Formula/taglib.rb index 48e76b5d77..2811decec2 100644 --- a/Formula/taglib.rb +++ b/Formula/taglib.rb @@ -1,12 +1,12 @@ -$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks require 'brewkit' -homepage='http://developer.kde.org/~wheeler/taglib.html' -url='http://developer.kde.org/~wheeler/files/src/taglib-1.5.tar.gz' -md5='7b557dde7425c6deb7bbedd65b4f2717' +class Taglib