aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew
diff options
context:
space:
mode:
authorMax Howell2009-07-24 15:10:01 +0100
committerMax Howell2009-07-24 23:57:54 +0100
commitfb5aefd4a053d718637ea8690c6eeba2d6e56008 (patch)
tree9f6e1a91e04963985093cb60e4764cf62d9f316b /Library/Homebrew
parent5eb9d6519d9411a4715d06efcb7b0c7480e3f01d (diff)
downloadbrew-0.3.tar.bz2
Refactor--object orientate where sensible0.3
Diffstat (limited to 'Library/Homebrew')
-rw-r--r--Library/Homebrew/brewkit.rb371
-rw-r--r--Library/Homebrew/env.rb95
-rw-r--r--Library/Homebrew/formula.rb263
-rw-r--r--Library/Homebrew/keg.rb153
-rwxr-xr-xLibrary/Homebrew/unittest.rb2
5 files changed, 514 insertions, 370 deletions
diff --git a/Library/Homebrew/brewkit.rb b/Library/Homebrew/brewkit.rb
index a32f015d5..f5d819f1b 100644
--- a/Library/Homebrew/brewkit.rb
+++ b/Library/Homebrew/brewkit.rb
@@ -15,9 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with Homebrew. If not, see <http://www.gnu.org/licenses/>.
-require 'pathname'
require 'osx/cocoa' # to get number of cores
-require 'env'
+require 'formula'
# optimise all the way to eleven, references:
# http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel
@@ -38,343 +37,7 @@ unless $root.to_s == '/usr/local'
end
-def ohai title
- n=`tput cols`.strip.to_i-4
- puts "\033[0;34m==>\033[0;0;1m #{title[0,n]}\033[0;0m"
-end
-
-def cache
- cache=File.expand_path "~/Library/Caches/Homebrew"
- FileUtils.mkpath cache
- return cache
-end
-
-class BuildError <RuntimeError
- def initialize cmd
- super "Build failed during: #{cmd}"
- end
-end
-
-# pass in the basename of the filename _without_ any file extension
-def extract_version basename
- # eg. boost_1_39_0
- /((\d+_)+\d+)$/.match basename
- return $1.gsub('_', '.') if $1
-
- # eg. foobar-4.5.1-1
- /-((\d+\.)*\d+-\d+)$/.match basename
- return $1 if $1
-
- # eg. foobar-4.5.1
- /-((\d+\.)*\d+)$/.match basename
- return $1 if $1
-
- # eg. foobar-4.5.1b
- /-((\d+\.)*\d+([abc]|rc\d))$/.match basename
- return $1 if $1
-
- # eg foobar-4.5.0-beta1
- /-((\d+\.)*\d+-beta\d+)$/.match basename
- return $1 if $1
-
- # eg. foobar4.5.1
- /((\d+\.)*\d+)$/.match basename
- return $1 if $1
-
- # eg. otp_src_R13B (this is erlang's style)
- # eg. astyle_1.23_macosx.tar.gz
- basename.scan /_([^_]+)/ do |match|
- return match.first if /\d/.match $1
- end
-end
-
-
-# make our code neater
-class Pathname
- def mv dst
- FileUtils.mv to_s, dst
- end
-
- def rename dst
- dst=Pathname.new dst
- dst.unlink if dst.exist?
- mv dst
- end
-
- def install src
- if src.is_a? Array
- src.each {|src| install src }
- elsif File.exist? src
- mkpath
- if File.symlink? src
- # we cp symlinks because FileUtils.mv is shit and won't mv a symlink
- # if its final destination has an invalid target! FFS. Ruby is shit.
- FileUtils.cp src, to_s
- else
- # we mv when possible as it is faster and you should only be using
- # this function when installing from the temporary build directory
- FileUtils.mv src, to_s
- end
- end
- end
-
- def cp dst
- if file?
- FileUtils.cp to_s, dst
- else
- FileUtils.cp_r to_s, dst
- end
- end
-
- # for filetypes we support
- def extname
- /\.(zip|tar\.(gz|bz2)|tgz)$/.match to_s
- return ".#{$1}" if $1
- return File.extname(to_s)
- end
-
- # for filetypes we support, basename without extension
- def stem
- return File.basename(to_s, extname)
- end
-end
-
-
-# the base class variety of formula, you don't get a prefix, so it's not really
-# useful. See the derived classes for fun and games.
-class AbstractFormula
- require 'find'
- require 'fileutils'
-
- # fuck knows, ruby is weird
- # TODO please fix!
- 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 version
- @version
- end
- def name
- @name
- end
-
- def initialize name=nil
- @name=name
- # 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
- end
-
-public
- def prefix
- raise "@name.nil!" if @name.nil?
- raise "@version.nil?" if @version.nil?
- $cellar+@name+@version
- end
- def bin
- prefix+'bin'
- end
- def doc
- prefix+'share'+'doc'+name
- end
- def man
- prefix+'share'+'man'
- end
- def man1
- prefix+'share'+'man'+'man1'
- end
- def lib
- prefix+'lib'
- end
- def include
- prefix+'include'
- end
-
- def caveats
- nil
- end
-
- # yields self with current working directory set to the uncompressed tarball
- def brew
- ohai "Downloading #{@url}"
- Dir.chdir cache do
- tmp=tgz=nil
- begin
- tgz=Pathname.new(fetch()).realpath
- md5=`md5 -q "#{tgz}"`.strip
- raise "MD5 mismatch: #{md5}" unless @md5 and md5 == @md5.downcase
-
- # 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
- end
- end
-
- def clean
- #TODO strip libexec too
- [bin,lib].each {|path| path.find do |path|
- if not path.file?
- next
- elsif path.extname == '.la'
- # .la files are stupid
- path.unlink
- else
- fo=`file -h #{path}`
- args=nil
- perms=0444
- if fo =~ /Mach-O dynamically linked shared library/
- args='-SxX'
- elsif fo =~ /Mach-O executable/ # defaults strip everything
- args='' # still do the strip
- perms=0544
- elsif fo =~ /script text executable/
- perms=0544
- end
- if args
- puts "Stripping: #{path}" if ARGV.include? '--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,mktm this fixes it
- tmp=`mktemp -t #{path.basename}`.strip
- `strip -o #{tmp} #{path}`
- `cat #{tmp} > #{path}`
- File.unlink tmp
- end
- end
- path.chmod perms
- end
- end}
-
- # remove empty directories
- `perl -MFile::Find -e"finddepth(sub{rmdir},'#{prefix}')"`
- end
-
-protected
- def uncompress path
- path.dirname
- end
-
-private
- def fetch
- %r[http://(www.)?github.com/.*/(zip|tar)ball/].match @url
- if $2
- # curl doesn't do the redirect magic that we would like, so we get a
- # stupidly named file, this is why wget would be beter, but oh well
- tgz="#{@name}-#{@version}.#{$2=='tar' ? 'tgz' : $2}"
- oarg="-o #{tgz}"
- else
- oarg='-O' #use the filename that curl gets
- 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}"`
- raise "Download failed" unless $? == 0
- else
- puts "File already downloaded and cached"
- end
- return tgz
- end
-
- def method_added method
- raise 'You cannot override Formula.brew' if method == 'brew'
- end
-end
-
-# somewhat useful, it'll raise if you call prefix, but it'll unpack a tar/zip
-# for you, check the md5, and allow you to yield from brew
-class UnidentifiedFormula <AbstractFormula
- def initialize name=nil
- super name
- end
-
-private
- def uncompress(path)
- if path.extname == '.zip'
- `unzip -qq "#{path}"`
- else
- `tar xf "#{path}"`
- end
-
- raise "Compression tool failed" if $? != 0
-
- entries=Dir['*']
- 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
-end
-
-# this is what you will mostly use, reimplement install, prefix won't raise
-class Formula <UnidentifiedFormula
- def initialize name
- super name
- @version=extract_version Pathname.new(File.basename(@url)).stem unless @version
- end
-end
-
-# see ack.rb for an example usage
-class ScriptFileFormula <AbstractFormula
- def install
- bin.install name
- end
-end
-
-class GithubGistFormula <ScriptFileFormula
- def initialize
- super File.basename(url)
- @version=File.basename(File.dirname(url))[0,6]
- end
-end
+######################################################################## utils
def inreplace(path, before, after)
before=before.to_s.gsub('"', '\"').gsub('/', '\/')
@@ -385,34 +48,6 @@ def inreplace(path, before, after)
#TODO optimise it by taking before and after as arrays
#Bah, just make the script writers do it themselves with a standard collect block
#TODO use ed -- less to escape
+ #TODO the above doesn't escape all regexp symbols!
`perl -pi -e "s/#{before}/#{after}/g" "#{path}"`
end
-
-def system cmd
- ohai cmd
-
- out=''
- IO.popen("#{cmd} 2>&1") do |f|
- until f.eof?
- s=f.gets
- if ARGV.include? '--verbose'
- puts s
- else
- out+=s
- end
- end
- end
-
- unless $? == 0
- puts out unless ARGV.include? '--verbose' #already did that above
- raise BuildError.new(cmd)
- end
-end
-
-####################################################################### script
-if $0 == __FILE__
- d=$cellar.parent+'bin'
- d.mkpath unless d.exist?
- Dir.chdir d
- Pathname.new('brew').make_symlink Pathname.new('../Cellar')+'homebrew'+'brew'
-end \ No newline at end of file
diff --git a/Library/Homebrew/env.rb b/Library/Homebrew/env.rb
index 951d9f9dc..dbba19e8a 100644
--- a/Library/Homebrew/env.rb
+++ b/Library/Homebrew/env.rb
@@ -21,4 +21,97 @@ $root=Pathname.new(__FILE__).dirname.parent.parent.realpath
$formula=$root+'Library'+'Formula'
$cellar=$root+'Cellar'
-HOMEBREW_VERSION='0.2' \ No newline at end of file
+HOMEBREW_VERSION='0.3'
+HOMEBREW_CACHE=File.expand_path "~/Library/Caches/Homebrew"
+
+
+######################################################################## utils
+def ohai title
+ n=`tput cols`.strip.to_i-4
+ puts "\033[0;34m==>\033[0;0;1m #{title[0,n]}\033[0;0m"
+end
+
+
+############################################################### class Pathname
+# we enhance Pathname to make our code more legible
+# of course this kind of thing is evil, but meh
+class Pathname
+ def mv dst
+ FileUtils.mv to_s, dst
+ end
+
+ def rename dst
+ dst=Pathname.new dst
+ dst.unlink if dst.exist?
+ mv dst
+ end
+
+ def install src
+ if src.is_a? Array
+ src.each {|src| install src }
+ elsif File.exist? src
+ mkpath
+ if File.symlink? src
+ # we use the BSD mv command because FileUtils copies the target and
+ # not the link! I'm beginning to wish I'd used Python quite honestly!
+ `mv #{src} #{to_s}`
+ else
+ # we mv when possible as it is faster and you should only be using
+ # this function when installing from the temporary build directory
+ FileUtils.mv src, to_s
+ end
+ end
+ end
+
+ def cp dst
+ if file?
+ FileUtils.cp to_s, dst
+ else
+ FileUtils.cp_r to_s, dst
+ end
+ end
+
+ # extended to support the double extensions .tar.gz and .tar.bz2
+ def extname
+ /(\.tar\.(gz|bz2))$/.match to_s
+ return $1 if $1
+ return File.extname(to_s)
+ end
+
+ # for filetypes we support, basename without extension
+ def stem
+ return File.basename(to_s, extname)
+ end
+
+ def version
+ # eg. boost_1_39_0
+ /((\d+_)+\d+)$/.match stem
+ return $1.gsub('_', '.') if $1
+
+ # eg. foobar-4.5.1-1
+ /-((\d+\.)*\d+-\d+)$/.match stem
+ return $1 if $1
+
+ # eg. foobar-4.5.1
+ /-((\d+\.)*\d+)$/.match stem
+ return $1 if $1
+
+ # eg. foobar-4.5.1b
+ /-((\d+\.)*\d+([abc]|rc\d))$/.match stem
+ return $1 if $1
+
+ # eg foobar-4.5.0-beta1
+ /-((\d+\.)*\d+-beta\d+)$/.match stem
+ return $1 if $1
+
+ # eg. foobar4.5.1
+ /((\d+\.)*\d+)$/.match stem
+ return $1 if $1
+
+ # eg. otp_src_R13B (this is erlang's style)
+ # eg. astyle_1.23_macosx.tar.gz
+ stem.scan /_([^_]+)/ do |match|
+ return match.first if /\d/.match $1
+ end
+ end
+end
diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb
new file mode 100644
index 000000000..443ab1de1
--- /dev/null
+++ b/Library/Homebrew/formula.rb
@@ -0,0 +1,263 @@
+# Copyright 2009 Max Howell <max@methylblue.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+require 'env'
+
+class BuildError <RuntimeError
+ def initialize cmd
+ super "Build failed during: #{cmd}"
+ end
+end
+
+# the base class variety of formula, you don't get a prefix, so it's not really
+# useful. See the derived classes for fun and games.
+class AbstractFormula
+ require 'find'
+ require 'fileutils'
+
+ # fuck knows, ruby is weird
+ # TODO please fix!
+ 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 version
+ @version
+ end
+ def name
+ @name
+ end
+
+ # if the dir is there, but it's empty we consider it not installed
+ def installed?
+ return prefix.children.count > 0
+ rescue
+ return false
+ end
+
+ def initialize name=nil
+ @name=name
+ # 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
+ end
+
+public
+ def prefix
+ raise "@name.nil!" if @name.nil?
+ raise "@version.nil?" if @version.nil?
+ $cellar+@name+@version
+ end
+ def bin
+ prefix+'bin'
+ end
+ def doc
+ prefix+'share'+'doc'+name
+ end
+ def man
+ prefix+'share'+'man'
+ end
+ def man1
+ man+'man1'
+ end
+ def lib
+ prefix+'lib'
+ end
+ def include
+ prefix+'include'
+ end
+
+ def caveats
+ nil
+ end
+
+ # 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
+ else
+ out=''
+ IO.popen "#{cmd} 2>&1" do |f|
+ until f.eof?
+ out+=f.gets
+ end
+ end
+ puts out unless $? == 0
+ end
+
+ raise BuildError.new(cmd) unless $? == 0
+ end
+
+ # yields self with current working directory set to the uncompressed tarball
+ def brew
+ ohai "Downloading #{@url}"
+ FileUtils.mkpath HOMEBREW_CACHE
+ Dir.chdir HOMEBREW_CACHE do
+ tmp=tgz=nil
+ begin
+ tgz=Pathname.new(fetch()).realpath
+ md5=`md5 -q "#{tgz}"`.strip
+ raise "MD5 mismatch: #{md5}" unless @md5 and md5 == @md5.downcase
+
+ # 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
+ end
+ end
+
+protected
+ # returns the directory where the archive was uncompressed
+ # in this Abstract case we assume there is no archive
+ def uncompress path
+ path.dirname
+ end
+
+private
+ def fetch
+ %r[http://(www.)?github.com/.*/(zip|tar)ball/].match @url
+ if $2
+ # curl doesn't do the redirect magic that we would like, so we get a
+ # stupidly named file, this is why wget would be beter, but oh well
+ tgz="#{@name}-#{@version}.#{$2=='tar' ? 'tgz' : $2}"
+ oarg="-o #{tgz}"
+ else
+ oarg='-O' #use the filename that curl gets
+ 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}"`
+ raise "Download failed" unless $? == 0
+ else
+ puts "File already downloaded and cached"
+ end
+ return tgz
+ end
+
+ def method_added method
+ raise 'You cannot override Formula.brew' if method == 'brew'
+ end
+end
+
+# somewhat useful, it'll raise if you call prefix, but it'll unpack a tar/zip
+# for you, check the md5, and allow you to yield from brew
+class UnidentifiedFormula <AbstractFormula
+ def initialize name=nil
+ super name
+ end
+
+private
+ def uncompress(path)
+ if path.extname == '.zip'
+ `unzip -qq "#{path}"`
+ else
+ `tar xf "#{path}"`
+ end
+
+ raise "Compression tool failed" if $? != 0
+
+ entries=Dir['*']
+ 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
+end
+
+# this is what you will mostly use, reimplement install, prefix won't raise
+class Formula <UnidentifiedFormula
+ def initialize name
+ super name
+ @version=Pathname.new(@url).version unless @version
+ end
+
+ def self.class name
+ #remove invalid characters and camelcase
+ name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase }
+ end
+
+ def self.path name
+ $formula+(name.downcase+'.rb')
+ end
+
+ def self.create name
+ require Formula.path(name)
+ return eval(Formula.class(name)).new(name)
+ rescue
+ raise "No formula for #{name}"
+ end
+end
+
+# see ack.rb for an example usage
+class ScriptFileFormula <AbstractFormula
+ def install
+ bin.install name
+ end
+end
+
+class GithubGistFormula <ScriptFileFormula
+ def initialize
+ super File.basename(url)
+ @version=File.basename(File.dirname(url))[0,6]
+ end
+end
diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb
new file mode 100644
index 000000000..8330c650f
--- /dev/null
+++ b/Library/Homebrew/keg.rb
@@ -0,0 +1,153 @@
+# Copyright 2009 Max Howell <max@methylblue.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+require 'env'
+require 'formula'
+
+class Keg
+ attr_reader :path, :version, :name
+
+ def initialize formula
+ if formula.is_a? AbstractFormula
+ @path=formula.prefix
+ @name=formula.name
+ @version=formula.version
+ elsif formula.is_a? Pathname
+ # TODO
+ elsif formula.is_a? String
+ kids=($cellar+formula).children
+ raise "Multiple versions installed" if kids.length > 1
+ @path=kids[0]
+ @name=formula
+ @version=@path.basename
+ end
+ end
+
+ def clean
+ # TODO unset write permission more
+ %w[bin lib].each {|d| (Pathname.new(path)+d).find do |path|
+ if not path.file?
+ next
+ elsif path.extname == '.la'
+ # .la files are stupid
+ path.unlink
+ else
+ fo=`file -h #{path}`
+ args=nil
+ perms=0444
+ if fo =~ /Mach-O dynamically linked shared library/
+ args='-SxX'
+ elsif fo =~ /Mach-O executable/ # defaults strip everything
+ args='' # still do the strip
+ perms=0544
+ elsif fo =~ /script text executable/
+ perms=0544
+ end
+ if args
+ puts "Stripping: #{path}" if ARGV.include? '--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,mktm this fixes it
+ tmp=`mktemp -t #{path.basename}`.strip
+ `strip -o #{tmp} #{path}`
+ `cat #{tmp} > #{path}`
+ File.unlink tmp
+ end
+ end
+ path.chmod perms
+ end
+ end}
+
+ # remove empty directories TODO Rubyize!
+ `perl -MFile::Find -e"finddepth(sub{rmdir},'#{path}')"`
+ end
+
+ def rm
+ if path.directory?
+ FileUtils.chmod_R 0777, path # ensure we have permission to delete
+ path.rmtree
+ end
+ end
+
+private
+ def __symlink_relative_to from, to
+ tod=to.dirname
+ tod.mkpath
+ Dir.chdir(tod) do
+ #TODO use Ruby function so we get exceptions
+ #NOTE Ruby functions are fucked up!
+ `ln -sf "#{from.relative_path_from tod}"`
+ @n+=1
+ end
+ end
+
+ # symlinks a directory recursively into our FHS tree
+ def __ln start
+ start=path+start
+ return unless start.directory?
+
+ start.find do |from|
+ next if from == start
+
+ prune=false
+
+ relative_path=from.relative_path_from path
+ to=$root+relative_path
+
+ if from.file?
+ __symlink_relative_to from, to
+ elsif from.directory?
+ # no need to put .app bundles in the path, the user can just use
+ # spotlight, or the open command and actual mac apps use an equivalent
+ Find.prune if from.extname.to_s == '.app'
+
+ branch=from.relative_path_from start
+
+ case yield branch when :skip
+ Find.prune
+ when :mkpath
+ to.mkpath
+ @n+=1
+ else
+ __symlink_relative_to from, to
+ Find.prune
+ end
+ end
+ end
+ end
+
+public
+ def ln
+ # yeah indeed, you have to force anything you need in the main tree into
+ # these dirs REMEMBER that *NOT* everything needs to be in the main tree
+ # TODO consider using hardlinks
+ @n=0
+
+ __ln('etc') {:mkpath}
+ __ln('bin') {:link}
+ __ln('lib') {|path| :mkpath if ['pkgconfig','php'].include? path.to_s}
+ __ln('include') {:link}
+
+ mkpaths=(1..9).collect {|x| "man/man#{x}"} <<'man'<<'doc'<<'locale'<<'info'<<'aclocal'
+ __ln('share') {|path| :mkpath if mkpaths.include? path.to_s}
+
+ return @n
+ end
+end \ No newline at end of file
diff --git a/Library/Homebrew/unittest.rb b/Library/Homebrew/unittest.rb
index 84f0d3f81..7b15b2949 100755
--- a/Library/Homebrew/unittest.rb
+++ b/Library/Homebrew/unittest.rb
@@ -2,7 +2,7 @@
$:.unshift File.dirname(__FILE__)
require 'test/unit'
-require 'brewkit'
+require 'formula'
require 'stringio'
class TestFormula <Formula