Refactor Formulae

Basically Formulae are now classes that get dynamically loaded by the
brew script. This gives me more flexability.
This commit is contained in:
Max Howell 2009-06-02 13:39:39 +01:00
parent d2c7fcac29
commit d6141137f2
26 changed files with 657 additions and 394 deletions

View File

@ -3,7 +3,10 @@
# Licensed as per the GPL version 3 # Licensed as per the GPL version 3
require 'find' require 'find'
require 'pathname' 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 def prune
n=0 n=0
@ -25,95 +28,224 @@ def prune
end end
end end
# entries lists '.' and '..' so 2 is minimum basically # 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 return n
end end
case ARGV[0] def shift_formulae
when 'brew', 'install' then name=Pathname.new ARGV.shift
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 ' '}"
when 'rm', 'uninstall' then return name if name.directory? and name.parent.realpath == $cellar
path=$root+'Cellar'+ARGV[1] return File.basename(name, '.rb') if name.file? and name.extname == '.rb' and name.parent.realpath == $formula
abort "#{ARGV[1]} is not installed" unless path.directory?
path.rmtree
prune
puts "#{path} removed"
when 'ln' then name=name.to_s
target=Pathname.new(ARGV[1]) raise "#{name} is an invalid name for a formula" if name.include? '/'
target=$root+'Cellar'+target unless target.exist?
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 def __class name
# we are one dir too high #remove invalid characters and camelcase
kids=target.children name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase }
abort "#{target} is empty :(" if kids.length == 0 end
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
#TODO you should mkdirs as you find them and symlink files otherwise def __rb name
#TODO consider using hardlinks $formula+(name+'.rb')
end
n=0 def __obj name
target.find do |from| require "#{__rb name}"
next if from == ARGV[1] #rubysucks 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? def ln name
to.mkpath unless to.exist? keg=$cellar+name
elsif from.file? keg=keg.realpath
tod=to.dirname
Dir.chdir(tod) do
`ln -sf "#{from.relative_path_from tod}"`
n+=1
end
end
end
puts "Created #{n} links"
when 'abv', 'stats', 'statistics' if keg.parent.parent == $root
cellar=$root+'Cellar' # we are one dir too high
print `find #{cellar} -type f | wc -l`.strip+' files, '+`du -hd0 #{cellar} | cut -d"\t" -f1`.strip 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 #TODO consider using hardlinks
puts "Pruned #{prune} files"
when 'prefix' # yeah indeed, you have to force anything you want in the main tree into
# Get the clean path to $prefix/Cellar/homebrew/brew/../../../ # these directories :P
# Don't resolve any symlinks of that final result. $n=0
# Rationale: if the user calls /usr/local/bin/brew but that will resolve lnd(keg, 'etc') {nil}
# to /Brewery/Cellar/homebrew/brew we should give /usr/local and not lnd(keg, 'include') {nil}
# /Brewery because the user probably has chosen /usr/local as the Homebrew
# to expose to the system. lnd(keg, 'lib') do |path|
if File.symlink? __FILE__ :mkpath if ['pkgconfig','php'].include? path.to_s
# using pathname as it will handle readlink returning abs or rel paths end
d=Pathname.new(__FILE__).dirname
puts File.expand_path(d+File.readlink(__FILE__)+'../../../') 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 else
# Dir.pwd resolves the symlink :P #rubysucks :mkpath
# 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__+'../../../')
end end
end
when 'cache' lnd(keg, 'share') do |path|
puts File.expand_path('~/Library/Application Support/Homebrew') 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 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 end

View File

@ -2,8 +2,7 @@
# Licensed as per the GPL version 3 # Licensed as per the GPL version 3
require 'pathname' require 'pathname'
$agent = "Homebrew 0.1 (Ruby; Mac OS X 10.5 Leopard)" HOMEBREW_VERSION='0.1'
$cellar = Pathname.new(__FILE__).dirname.parent.realpath
# optimise all the way to eleven, references: # optimise all the way to eleven, references:
# http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel # http://en.gentoo-wiki.com/wiki/Safe_Cflags/Intel
@ -18,9 +17,9 @@ ENV['CC']='gcc-4.2'
ENV['CXX']='g++-4.2' ENV['CXX']='g++-4.2'
ENV['MAKEFLAGS']='-j2' ENV['MAKEFLAGS']='-j2'
unless $cellar.parent.to_s == '/usr/local' unless $root.to_s == '/usr/local'
ENV['CPPFLAGS']="-I#{$cellar.parent}/include" ENV['CPPFLAGS']='-I'+$root+'include'
ENV['LDFLAGS']="-L#{$cellar.parent}/lib" ENV['LDFLAGS']='-L'+$root+'lib'
end end
@ -35,21 +34,59 @@ def appsupport
return appsupport return appsupport
end 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 class Formula
require 'find' require 'find'
require 'fileutils' require 'fileutils'
# if you reimplement, assign @name, @version, @url and @md5 # fuck knows, ruby is weird
def initialize(url, md5) def self.url
@name = File.basename $0, '.rb' #original script that the interpreter started @url
@url = url end
@md5 = md5 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 # pls improve this version extraction crap
filename=File.basename url filename=File.basename @url
i=filename.index /[-_]\d/ i=filename.index /[-_]\d/
unless i.nil? 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 @version=$1
# if there are no dots replace underscores, boost do this, the bastards! # if there are no dots replace underscores, boost do this, the bastards!
@version.gsub!('_', '.') unless @version.include? '.' @version.gsub!('_', '.') unless @version.include? '.'
@ -59,26 +96,57 @@ class Formula
@version = $1 @version = $1
end end
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 #yields a Pathname object for the installation prefix
def brew def brew
raise "@name.nil?" if @name.nil?
raise "@version.nil?" if @version.nil?
# disabled until the regexp makes sense :P # disabled until the regexp makes sense :P
#raise "@name does not validate to our regexp" unless /^\w+$/ =~ @name #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}" ohai "Downloading #{@url}"
Dir.chdir appsupport do Dir.chdir appsupport do
tgz=Pathname.new(fetch()).realpath tgz=Pathname.new(fetch()).realpath
md5=`md5 -q "#{tgz}"`.strip 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 # we make an additional subdirectory so know exactly what we are
# recursively deleting later # recursively deleting later
@ -86,26 +154,27 @@ class Formula
# can't handle being built in a directory with spaces in it :P # can't handle being built in a directory with spaces in it :P
tmp=nil tmp=nil
begin begin
tmp=`mktemp -dt #{@name}-#{@version}`.strip tmp=`mktemp -dt #{File.basename @url}`.strip
Dir.chdir tmp do Dir.chdir tmp do
Dir.chdir uncompress(tgz) do Dir.chdir uncompress(tgz) do
caveats = yield prefix prefix.mkpath
yield self
if caveats if caveats
ohai "Caveats" ohai "Caveats"
puts caveats puts caveats
ohai "Summary"
end end
#TODO copy changelog or CHANGES file to pkg root, #TODO copy changelog or CHANGES file to pkg root,
#TODO maybe README, etc. to versioned root #TODO maybe README, etc. to versioned root
end end
end end
rescue rescue Interrupt, RuntimeError
if ARGV.include? '--debug' if ARGV.include? '--debug'
# debug mode allows the packager to intercept a failed build and # debug mode allows the packager to intercept a failed build and
# investigate the problems # investigate the problems
puts "Rescued build at: #{tmp}" puts "Rescued build at: #{tmp}"
exit! 1 exit! 1
else else
FileUtils.rm_rf prefix
raise raise
end end
ensure ensure
@ -115,27 +184,26 @@ class Formula
ohai 'Finishing up' 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| prefix.find do |path|
if path==prefix #rubysucks if path==prefix #rubysucks
next next
elsif path.file? elsif path.file?
fo=`file -h #{path}` if path.extname == '.la'
args=nil path.unlink
args='-SxX' if fo =~ /Mach-O dynamically linked shared library/ else
args='' if fo =~ /Mach-O executable/ #defaults strip everything fo=`file -h #{path}`
if args args=nil
puts "Stripping: #{path}" if ARGV.include? '--verbose' args='-SxX' if fo =~ /Mach-O dynamically linked shared library/
`strip #{args} #{path}` args='' if fo =~ /Mach-O executable/ #defaults strip everything
if args
puts "Stripping: #{path}" if ARGV.include? '--verbose'
`strip #{args} #{path}`
end
end end
elsif path.directory? and path!=prefix+'bin' and path!=prefix+'lib' elsif path.directory? and path!=prefix+'bin' and path!=prefix+'lib'
Find.prune Find.prune
end end
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
end end
@ -159,8 +227,10 @@ protected
tgz=File.expand_path File.basename(@url) tgz=File.expand_path File.basename(@url)
end end
agent="Homebrew #{HOMEBREW_VERSION} (Ruby #{VERSION}; Mac OS X 10.5 Leopard)"
unless File.exists? tgz unless File.exists? tgz
`curl -#LA "#{$agent}" #{oarg} "#{@url}"` `curl -#LA "#{agent}" #{oarg} "#{@url}"`
raise "Download failed" unless $? == 0 raise "Download failed" unless $? == 0
else else
puts "File already downloaded and cached" puts "File already downloaded and cached"
@ -178,9 +248,15 @@ protected
raise "Compression tool failed" if $? != 0 raise "Compression tool failed" if $? != 0
entries=Dir['*'] entries=Dir['*']
raise "Empty tar!" if entries.nil? or entries.length == 0 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 raise "Empty tarball!"
return entries.first 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
def cache? def cache?
@ -193,22 +269,21 @@ private
end end
end end
# you have to reimplement initialize to set the version, for example usage # see ack.rb for an example usage
# see the ack script class UncompressedScriptFormula <Formula
class UncompressedScriptFormula < Formula
def initialize(url)
@url=url
@name=File.basename url
end
def uncompress path def uncompress path
path.dirname path.dirname
end end
def cache? def cache?
false false
end end
def install
FileUtils.cp name, bin
(bin+name).chmod 0544
end
end end
class GithubGistFormula < Formula class GithubGistFormula <Formula
def initialize(url, md5) def initialize(url, md5)
@url=url @url=url
@name=File.basename url @name=File.basename url
@ -225,7 +300,7 @@ class GithubGistFormula < Formula
end end
def uncompress path def uncompress path
File.dirname path path.dirname
end end
end end
@ -259,19 +334,6 @@ def system cmd
end end
end end
# force a prettier exception handler unless --verbose or HOMEBREW_DEBUG
Kernel.at_exit {
if $! and not (ARGV.include? '--verbose' or ENV['HOMEBREW_DEBUG'])
if $!.kind_of? Interrupt #control-c
puts # seeimgly a newline is more typical
exit! 130
elsif $!.kind_of? StandardError
puts "\033[1;31mError\033[0;0m: #{$!}"
exit! 1
end
end
}
########################################################################script ########################################################################script
if $0 == __FILE__ if $0 == __FILE__
d=$cellar.parent+'bin' d=$cellar.parent+'bin'

View File

@ -1,64 +1,77 @@
#!/usr/bin/ruby #!/usr/bin/ruby
cwd=File.dirname(__FILE__) $:.unshift File.dirname(__FILE__)
$:.unshift cwd #rubysucks require 'pathname'
$root=Pathname.new(__FILE__).realpath.dirname.parent.parent
$cellar=$root+'Cellar'
require 'brewkit' require 'brewkit'
require 'test/unit' require 'test/unit'
$cellar=Pathname.new(cwd).parent.realpath
class BeerTasting < Test::Unit::TestCase
class TestFormula <Formula
def initialize url, md5
@url=url
@md5=md5
@name='test'
super()
end
end
class BeerTasting <Test::Unit::TestCase
def test_version_all_dots def test_version_all_dots
r=Formula.new "http://example.com/foo.bar.la.1.14.zip", 'nomd5' r=TestFormula.new "http://example.com/foo.bar.la.1.14.zip", 'nomd5'
assert_equal '1.14', r.version assert_equal '1.14', r.version
end end
def test_version_underscore_separator def test_version_underscore_separator
r=Formula.new "http://example.com/grc_1.1.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/grc_1.1.tar.gz", 'nomd5'
assert_equal '1.1', r.version assert_equal '1.1', r.version
end end
def test_version_underscores_all_the_way def test_version_underscores_all_the_way
r=Formula.new "http://example.com/boost_1_39_0.tar.bz2", 'nomd5' r=TestFormula.new "http://example.com/boost_1_39_0.tar.bz2", 'nomd5'
assert_equal '1.39.0', r.version assert_equal '1.39.0', r.version
end end
def test_version_internal_dash def test_version_internal_dash
r=Formula.new "http://example.com/foo-arse-1.1-2.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/foo-arse-1.1-2.tar.gz", 'nomd5'
assert_equal '1.1-2', r.version assert_equal '1.1-2', r.version
end end
def test_version_single_digit def test_version_single_digit
r=Formula.new "http://example.com/foo_bar.45.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/foo_bar.45.tar.gz", 'nomd5'
assert_equal '45', r.version assert_equal '45', r.version
end end
def test_noseparator_single_digit def test_noseparator_single_digit
r=Formula.new "http://example.com/foo_bar45.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/foo_bar45.tar.gz", 'nomd5'
assert_equal '45', r.version assert_equal '45', r.version
end end
def test_version_developer_that_hates_us_format def test_version_developer_that_hates_us_format
r=Formula.new "http://example.com/foo-bar-la.1.2.3.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/foo-bar-la.1.2.3.tar.gz", 'nomd5'
assert_equal '1.2.3', r.version assert_equal '1.2.3', r.version
end end
def test_version_regular def test_version_regular
r=Formula.new "http://example.com/foo_bar-1.21.tar.gz", 'nomd5' r=TestFormula.new "http://example.com/foo_bar-1.21.tar.gz", 'nomd5'
assert_equal '1.21', r.version assert_equal '1.21', r.version
end end
def test_yet_another_version
r=TestFormula.new "http://example.com/mad-0.15.1b.tar.gz", 'nomd5'
assert_equal '0.15.1b', r.version
end
def test_prefix def test_prefix
url='http://www.methylblue.com/test-0.1.tar.gz' url='http://www.methylblue.com/test-0.1.tar.gz'
md5='d496ea538a21dc4bb8524a8888baf88c' md5='d496ea538a21dc4bb8524a8888baf88c'
begin #rubysyntaxFAIL TestFormula.new(url, md5).brew do |f|
Formula.new(url, md5).brew do |prefix| prefix=f.prefix
# we test for +/unittest/0.1 because we derive @name from $0 # we test for +/unittest/0.1 because we derive @name from $0
assert_equal File.expand_path(prefix), ($cellar+'unittest'+'0.1').to_s assert_equal File.expand_path(prefix), ($cellar+'test'+'0.1').to_s
assert_kind_of Pathname, prefix assert_kind_of Pathname, prefix
end
rescue IOError => e
# this is not an error, cook will throw as nothing was installed
raise unless e.errno == Errno::ENOENT
end end
end end
end end

View File

@ -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

View File

@ -1,22 +1,10 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
require 'fileutils'
homepage='http://betterthangrep.com/' class Ack <UncompressedScriptFormula
class AckFormula < UncompressedScriptFormula
def initialize def initialize
super('http://ack.googlecode.com/svn/tags/1.88/ack')
@version='1.88' @version='1.88'
@url="http://ack.googlecode.com/svn/tags/#{@version}/ack"
@md5='8009a13ab0fc66047bea0ea2ad89419c' @md5='8009a13ab0fc66047bea0ea2ad89419c'
@homepage='http://betterthangrep.com/'
end end
end
ack=AckFormula.new
ack.brew do |prefix|
bin=prefix+'bin'
bin.mkpath
FileUtils.cp ack.name, bin
(bin+ack.name).chmod 0544
nil
end end

12
Formula/asciidoc.rb Normal file
View File

@ -0,0 +1,12 @@
require 'brewkit'
class Asciidoc <Formula
@url='http://www.methods.co.nz/asciidoc/asciidoc-8.4.4.tar.gz'
@md5='579bcd5762b177ee0ddccece8c34724b'
@homepage='http://www.methods.co.nz/asciidoc'
def install
system "./configure --disable-debug --prefix='#{prefix}'"
system "make install"
end
end

View File

@ -1,17 +1,16 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.boost.org' class Boost <Formula
url='http://kent.dl.sourceforge.net/sourceforge/boost/boost_1_39_0.tar.bz2' @homepage='http://www.boost.org'
md5='a17281fd88c48e0d866e1a12deecbcc0' @url='http://kent.dl.sourceforge.net/sourceforge/boost/boost_1_39_0.tar.bz2'
@md5='a17281fd88c48e0d866e1a12deecbcc0'
Formula.new(url, md5).brew do |prefix| def install
lib=prefix+'lib' #TODO we can save 6300 links if we just had the intelligence to symlink
# we specify libdir too because the script is apparently broken #the include/boost dir and not more
#TODO we can save 6300 links if we just had the intelligence to symlink the # we specify libdir too because the script is apparently broken
# include/boost dir and not more system "./bootstrap.sh --prefix='#{prefix}' --libdir='#{lib}'"
system "./bjam --layout=system --prefix='#{prefix}' --libdir='#{lib}' install"
system "./bootstrap.sh --prefix='#{prefix}' --libdir='#{lib}'" end
system "./bjam --layout=system --prefix='#{prefix}' --libdir='#{lib}' install"
end end

View File

@ -1,19 +1,13 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
require 'fileutils'
url='http://www.cmake.org/files/v2.6/cmake-2.6.3.tar.gz' class Cmake <Formula
md5='5ba47a94ce276f326abca1fd72a7e7c6' @url='http://www.cmake.org/files/v2.6/cmake-2.6.3.tar.gz'
@md5='5ba47a94ce276f326abca1fd72a7e7c6'
Formula.new(url, md5).brew do |prefix| def install
system "./bootstrap --prefix=#{prefix} --system-libs" system "./bootstrap --prefix=#{prefix} --system-libs"
system "make" system "make install"
system "make install"
['man','doc'].each { |d| (prefix+d).mv prefix+'share' }
# the people who develop cmake are just idiots end
share=prefix+'share'
FileUtils.mv prefix+'man', share
FileUtils.mv prefix+'doc', share
nil
end end

View File

@ -1,29 +1,42 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.digitalmars.com/d/' class Dmd <Formula
url='http://ftp.digitalmars.com/dmd.1.043.zip' @homepage='http://www.digitalmars.com/d/'
md5='6c83b7296cb84090a9ebc11ab0fb94a2' @url='http://ftp.digitalmars.com/dmd.1.043.zip'
@md5='6c83b7296cb84090a9ebc11ab0fb94a2'
Formula.new(url, md5).brew do |prefix| def doc
ohai "make" #use d and not dmd, rationale: meh
prefix.mkpath prefix+'share'+'doc'+'d'
FileUtils.cp_r 'osx/bin', prefix end
FileUtils.cp_r 'osx/lib', prefix
FileUtils.cp_r 'man', prefix
FileUtils.cp_r 'src', prefix
share=prefix+'share'+'doc'+'d' def install
html=share+'html' ohai "install"
samples=share+'examples' #examples is the more typical directory name FileUtils.cp_r 'osx/bin', prefix
html.mkpath FileUtils.cp_r 'osx/lib', prefix
samples.mkpath FileUtils.cp_r 'man/man1', man
FileUtils.cp_r 'src', prefix
FileUtils.cp_r Dir['html/d/*'], html unless ARGV.include? '--no-html' #lol
FileUtils.cp_r Dir['samples/d/*'], samples unless ARGV.include? '--no-samples' man5=man+'man5'
man5.mkpath
(man+'man1'+'dmd.conf.5').mv man5
#lol ends
html=doc+'html'
samples=doc+'examples' #examples is the more typical directory name
html.mkpath
samples.mkpath
FileUtils.cp_r Dir['html/d/*'], html unless ARGV.include? '--no-html'
FileUtils.cp_r Dir['samples/d/*'], samples unless ARGV.include? '--no-samples'
# zip files suck # zip files suck TODO FileUtils.chmod
Dir.chdir(prefix+'bin') { `chmod u+x dmd dumpobj obj2asm` } Dir.chdir(bin) { `chmod u+x dmd dumpobj obj2asm` }
nil (prefix+'bin'+'dmd.conf').open('w') do |f|
f.puts "[Environment]"
f.puts "DFLAGS=-I#{prefix}/src/phobos -L-L#{prefix}/lib"
end
end
end end

View File

@ -1,17 +1,21 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.fftw.org' class Fftw <Formula
url='http://www.fftw.org/fftw-3.2.1.tar.gz' @homepage='http://www.fftw.org'
md5='712d3f33625a0a76f5758648d4b925f7' @url='http://www.fftw.org/fftw-3.2.1.tar.gz'
@md5='712d3f33625a0a76f5758648d4b925f7'
Formula.new(url, md5).brew do |prefix| def install
configure=<<-EOS configure=<<-EOS
./configure --enable-shared --disable-debug --prefix='#{prefix}' ./configure --enable-shared --disable-debug --prefix='#{prefix}'
--enable-threads --enable-single --enable-sse --enable-threads --enable-single --enable-sse
--disable-dependency-tracking --disable-dependency-tracking
--disable-fortran --disable-fortran
EOS EOS
system configure.gsub("\n", ' ').strip.squeeze(' ') system configure.gsub("\n", ' ').strip.squeeze(' ')
system "make install" system "make install"
#wtf file?
(prefix+'share'+'info'+'dir').unlink
end
end end

View File

@ -1,12 +1,20 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://git-scm.com' class GitManuals <Formula
url='http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2' @url='http://kernel.org/pub/software/scm/git/git-manpages-1.6.3.1.tar.bz2'
md5='c1f4aab741359c29f0fbf28563ac7387' @md5='971d573e8f261feb83290a59728c2b33'
end
Formula.new(url, md5).brew do |prefix| class Git <Formula
system "./configure --disable-debug --prefix='#{prefix}'" @url='http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2'
system "make" @md5='c1f4aab741359c29f0fbf28563ac7387'
system "make install" @homepage='http://git-scm.com'
def install
system "./configure --prefix='#{prefix}' --disable-debug"
system "make install"
# the manuals come separately, well sort of, it's easier this way though
GitManuals.new.brew { FileUtils.mv Dir['*'], man }
end
end end

View File

@ -1,6 +1,4 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
require 'fileutils'
def profile_string def profile_string
<<-sput <<-sput
@ -33,36 +31,40 @@ case ARGV[0]
end end
######################################################################### cook ######################################################################### cook
homepage='http://korpus.juls.savba.sk/~garabik/software/grc.html' class Grc <Formula
url='http://korpus.juls.savba.sk/~garabik/software/grc/grc_1.1.tar.gz' @homepage='http://korpus.juls.savba.sk/~garabik/software/grc.html'
md5='eeb612aba2fff14cbaf1f3bec7e1eb60' @url='http://korpus.juls.savba.sk/~garabik/software/grc/grc_1.1.tar.gz'
@md5='eeb612aba2fff14cbaf1f3bec7e1eb60'
Formula.new(url, md5).brew do |prefix| def install
ohai "make" ohai "make"
#TODO we should deprefixify since it's python and thus possible #TODO we should deprefixify since it's python and thus possible
inreplace 'grc', '/etc', prefix+'etc' inreplace 'grc', '/etc', prefix+'etc'
inreplace 'grc.1', '/etc', prefix+'etc' inreplace 'grc.1', '/etc', prefix+'etc'
inreplace 'grcat', '/usr/local', prefix inreplace 'grcat', '/usr/local', prefix
inreplace 'grcat.1', '/usr/local', prefix inreplace 'grcat.1', '/usr/local', prefix
FileUtils.mkpath prefix FileUtils.mkpath prefix
Dir.chdir prefix do Dir.chdir prefix do
FileUtils.mkpath 'bin' FileUtils.mkpath 'bin'
FileUtils.mkpath 'share/grc' FileUtils.mkpath 'share/grc'
FileUtils.mkpath 'share/man/man1' FileUtils.mkpath 'share/man/man1'
FileUtils.mkpath 'etc' FileUtils.mkpath 'etc'
end
`cp -fv grc grcat #{prefix}/bin`
`cp -fv conf.* #{prefix}/share/grc`
`cp -fv grc.conf #{prefix}/etc`
`cp -fv grc.1 grcat.1 #{prefix}/share/man/man1`
end end
def caveats
<<-EOS
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:
`cp -fv grc grcat #{prefix}/bin` ruby #{$0} --profile >> ~/.profile
`cp -fv conf.* #{prefix}/share/grc`
`cp -fv grc.conf #{prefix}/etc`
`cp -fv grc.1 grcat.1 #{prefix}/share/man/man1`
<<-nruter EOS
grc won't work as is. One option is to add some aliases to your ~/.profile end
file. Homebrew can do that for you, just execute this command: end
ruby #{$0} --profile >> ~/.profile
nruter
end

View File

@ -1,11 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://lame.sourceforge.net/' class Lame <Formula
url='http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz' @homepage='http://lame.sourceforge.net/'
md5='719dae0ee675d0c16e0e89952930ed35' @url='http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz'
@md5='719dae0ee675d0c16e0e89952930ed35'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debug --prefix='#{prefix}' --enable-nasm" system "./configure --disable-debug --prefix='#{prefix}' --enable-nasm"
system "make install" # if this fails, split into two steps system "make install"
end
end end

View File

@ -1,14 +1,19 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://github.com/mxcl/liblastfm/' class Liblastfm <Formula
url='http://github.com/mxcl/liblastfm/tarball/0.3.0' @homepage='http://github.com/mxcl/liblastfm/'
md5='b348917689b90f3f40125d0968f0b643' @url='http://github.com/mxcl/liblastfm/tarball/0.3.0'
@md5='08e90275ccd06476426a5002d1dad762'
external_deps=['qmake'] def deps
dep_test_bin 'qmake' or 'qt'
dep_test_lib 'fftw3f' or 'fftw'
dep_test_lib 'samplerate' or 'libsamplerate'
end
Formula.new(url, md5).brew do |prefix| def install
system "./configure --release --prefix '#{prefix}'" system "./configure --release --prefix '#{prefix}'"
system "make" system "make"
system "make install" system "make install"
end
end end

View File

@ -1,11 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.xiph.org/ogg/' class Libogg <Formula
url='http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz' @homepage='http://www.xiph.org/ogg/'
md5='eaf7dc6ebbff30975de7527a80831585' @url='http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz'
@md5='eaf7dc6ebbff30975de7527a80831585'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debug --prefix='#{prefix}'" system "./configure --disable-debug --prefix='#{prefix}'"
system "make install" system "make install"
end
end end

View File

@ -1,11 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.mega-nerd.com/SRC' class Libsamplerate <Formula
url='http://www.mega-nerd.com/SRC/libsamplerate-0.1.7.tar.gz' @homepage='http://www.mega-nerd.com/SRC'
md5='ad093e60ec44f0a60de8e29983ddbc0f' @url='http://www.mega-nerd.com/SRC/libsamplerate-0.1.7.tar.gz'
@md5='ad093e60ec44f0a60de8e29983ddbc0f'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debug --prefix='#{prefix}'" system "./configure --disable-debug --prefix='#{prefix}'"
system "make install" system "make install"
end
end end

View File

@ -1,12 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.underbit.com/products/mad/' class Mad <Formula
url='http://kent.dl.sourceforge.net/sourceforge/mad/libmad-0.15.1b.tar.gz' @homepage='http://www.underbit.com/products/mad/'
md5='1be543bc30c56fb6bea1d7bf6a64e66c' @url='http://kent.dl.sourceforge.net/sourceforge/mad/libmad-0.15.1b.tar.gz'
@md5='1be543bc30c56fb6bea1d7bf6a64e66c'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debugging --enable-fpm=intel --prefix='#{prefix}'" system "./configure --disable-debugging --enable-fpm=intel --prefix='#{prefix}'"
system "make" system "make install"
system "make install" end
end end

View File

@ -1,15 +1,14 @@
require 'pathname'
$root=Pathname.new(__FILE__).dirname.parent
$:.unshift "#{$root}/Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://pkgconfig.freedesktop.org' class PkgConfig <Formula
url='http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz' @homepage='http://pkgconfig.freedesktop.org'
md5='d922a88782b64441d06547632fd85744' @url='http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz'
@md5='d922a88782b64441d06547632fd85744'
#TODO depend on our glib? --with-installed-glib #TODO depend on our glib? --with-installed-glib
Formula.new(url, md5).brew do |prefix| def install
system "./configure --with-pc-path=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:#{$root}/lib/pkgconfig --disable-debug --prefix='#{prefix}'" system "./configure --with-pc-path=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:#{$root}/lib/pkgconfig --disable-debug --prefix='#{prefix}'"
system "make install" system "make install"
end
end end

View File

@ -1,13 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://pmt.sourceforge.net/pngcrush/' class Pngcrush <Formula
url='http://kent.dl.sourceforge.net/sourceforge/pmt/pngcrush-1.6.17.tar.bz2' @homepage='http://pmt.sourceforge.net/pngcrush/'
md5='8ba31ae9b1b14e7648df320fd1ed27c7' @url='http://kent.dl.sourceforge.net/sourceforge/pmt/pngcrush-1.6.17.tar.bz2'
@md5='8ba31ae9b1b14e7648df320fd1ed27c7'
Formula.new(url, md5).brew do |prefix| def install
system "make" system "make"
bin=prefix+'bin' FileUtils.cp 'pngcrush', bin
bin.mkpath end
FileUtils.cp 'pngcrush', bin
end end

43
Formula/qt.rb Normal file
View File

@ -0,0 +1,43 @@
require 'brewkit'
class Qt <Formula
@url='http://get.qtsoftware.com/qt/source/qt-mac-opensource-src-4.5.1.tar.gz'
@md5='9fc0e96197df6db48a0628ac4d63e0dd'
@homepage='http://www.qtsoftware.com'
def install
if version == '4.5.1'
# Reported 6 months ago (at 4.5.0-rc1), still not fixed in the this release! :(
makefiles=['plugins/sqldrivers/sqlite/sqlite.pro', '3rdparty/webkit/WebCore/WebCore.pro']
makefiles.each { |makefile| `echo 'LIBS += -lsqlite3' >> 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

View File

@ -1,12 +1,12 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://developer.kde.org/~wheeler/taglib.html' class Taglib <Formula
url='http://developer.kde.org/~wheeler/files/src/taglib-1.5.tar.gz' @url='http://developer.kde.org/~wheeler/files/src/taglib-1.5.tar.gz'
md5='7b557dde7425c6deb7bbedd65b4f2717' @md5='7b557dde7425c6deb7bbedd65b4f2717'
@homepage='http://developer.kde.org/~wheeler/taglib.html'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debug --prefix='#{prefix}'" system "./configure --disable-debug --prefix='#{prefix}'"
system "make" system "make install"
system "make install" end
end end

View File

@ -1,21 +1,10 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
require 'fileutils'
homepage='http://gist.github.com/116587' class Term <UncompressedScriptFormula
class TermFormula < UncompressedScriptFormula
def initialize def initialize
super('http://github.com/liyanage/macosx-shell-scripts/raw/e29f7eaa1eb13d78056dec85dc517626ab1d93e3/term') @url='http://github.com/liyanage/macosx-shell-scripts/raw/e29f7eaa1eb13d78056dec85dc517626ab1d93e3/term'
@md5='1bbf4509a50224b27ac8c20d3fe8682e' @md5='1bbf4509a50224b27ac8c20d3fe8682e'
@version='2.1' @version='2.1'
@homepage='http://gist.github.com/116587'
end end
end
term=TermFormula.new
term.brew do |prefix|
bin=(prefix+'bin')
bin.mkpath
FileUtils.cp term.name, bin
nil
end end

View File

@ -1,12 +1,13 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://www.gnu.org/software/wget/' class Wget <Formula
url='http://ftp.gnu.org/gnu/wget/wget-1.11.4.tar.bz2' @homepage='http://www.gnu.org/software/wget/'
md5='f5076a8c2ec2b7f334cb6e3059820f9c' @url='http://ftp.gnu.org/gnu/wget/wget-1.11.4.tar.bz2'
@md5='f5076a8c2ec2b7f334cb6e3059820f9c'
Formula.new(url, md5).brew do |prefix| def install
system "./configure --disable-debug --prefix='#{prefix}'" system "./configure --disable-debug --prefix='#{prefix}'"
system "make" system "make"
system "make install" system "make install"
end
end end

View File

@ -1,16 +1,16 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://xmlrpc-c.sourceforge.net/' class XmlrpcC <Formula
url='http://kent.dl.sourceforge.net/sourceforge/xmlrpc-c/xmlrpc-c-1.06.33.tgz' @url='http://kent.dl.sourceforge.net/sourceforge/xmlrpc-c/xmlrpc-c-1.06.33.tgz'
md5='7dda4d8c5d26ae877d3809e428ce7962' @md5='7dda4d8c5d26ae877d3809e428ce7962'
@homepage='http://xmlrpc-c.sourceforge.net/'
Formula.new(url, md5).brew do |prefix| def install
ENV['MAKEFLAGS']='' #parallel build doesn't work ENV['MAKEFLAGS']='' #parallel build doesn't work
# choosing --enable-libxml2-backend to lose some weight and not statically # choosing --enable-libxml2-backend to lose some weight and not statically
# link in expat # link in expat
#NOTE seemingly it isn't possible to build dylibs with this thing #NOTE seemingly it isn't possible to build dylibs with this thing
system "./configure --disable-debug --enable-libxml2-backend --prefix='#{prefix}'" system "./configure --disable-debug --enable-libxml2-backend --prefix='#{prefix}'"
system "make" system "make install"
system "make install" end
end end

View File

@ -1,16 +1,21 @@
$:.unshift "#{File.dirname __FILE__}/../Cellar/homebrew" #rubysucks
require 'brewkit' require 'brewkit'
homepage='http://lloyd.github.com/yajl/' class Yajl <Formula
url='http://github.com/lloyd/yajl/tarball/1.0.5' @homepage='http://lloyd.github.com/yajl/'
md5='f4a3cbc764c43231ed1aedc54438b69b' @url='http://github.com/lloyd/yajl/tarball/1.0.5'
@md5='f4a3cbc764c43231ed1aedc54438b69b'
deps=['cmake'] def deps
dep_test_bin 'cmake'
end
Formula.new(url, md5).brew do |prefix| def install
ENV['MAKEFLAGS']='' # can't do parallel builds
inreplace 'configure', 'cmake \.\.', "cmake -DCMAKE_INSTALL_PREFIX='#{prefix}' \.\."
# I have pushed this fix upstream
system "./configure --prefix '#{prefix}'" inreplace 'configure', 'cmake \.\.', "cmake -DCMAKE_INSTALL_PREFIX='#{prefix}' \.\." if @version == "1.0.5"
system "make install"
system "./configure --prefix '#{prefix}'"
system "make install"
end
end end

5
README
View File

@ -128,12 +128,15 @@ Congratulations, you have contributed to an open source project!
Contributing Contributing
============ ============
New Formulas New Formulae
------------ ------------
Relative to every other stupid packaging system ever, this is trivial. Just Relative to every other stupid packaging system ever, this is trivial. Just
fork it at: http://github.com/mxcl/homebrew and create a new recipe. Then ask fork it at: http://github.com/mxcl/homebrew and create a new recipe. Then ask
me to pull. Using git made all this so much easier. me to pull. Using git made all this so much easier.
HomeBrew is not an Autarky so any dependencies outside of OS X that a package
may require may be installed separately. We have functions to help with that.
Code Code
---- ----
Yes please! Fork and improve :) Yes please! Fork and improve :)