aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/brew245
1 files changed, 245 insertions, 0 deletions
diff --git a/bin/brew b/bin/brew
new file mode 100755
index 000000000..825872d93
--- /dev/null
+++ b/bin/brew
@@ -0,0 +1,245 @@
+#!/usr/bin/ruby
+
+require 'find'
+require 'pathname'
+$:.unshift Pathname.new(__FILE__).dirname.parent.realpath+'Library'+'Homebrew'
+require 'env'
+
+def prune
+ n=0
+ dirs=Array.new
+ $root.find do |path|
+ if path.directory?
+ name=path.relative_path_from($root).to_s
+ if name == '.git' or name == 'Cellar' or name == 'Library/Homebrew' or name == 'Library/Formula'
+ Find.prune
+ else
+ dirs<<path
+ end
+ elsif path.symlink?
+ resolved_path=path.dirname+path.readlink
+ unless resolved_path.exist?
+ path.unlink
+ n+=1
+ end
+ end
+ end
+ # entries lists '.' and '..' so 2 is minimum basically
+ dirs.sort.reverse_each do |d|
+ if d.children.length == 0
+ d.rmdir
+ n+=1
+ end
+ end
+ return n
+end
+
+def shift_formulae
+ name=Pathname.new ARGV.shift
+
+ 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
+
+ name=name.to_s
+ raise "#{name} is an invalid name for a formula" if name.include? '/'
+
+ return name if ($formula+(name+'.rb')).file?
+ return name if ($cellar+name).directory?
+
+ raise "No formula or keg for #{name} found"
+end
+
+def __class name
+ #remove invalid characters and camelcase
+ name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase }
+end
+
+def __rb name
+ $formula+(name+'.rb')
+end
+
+def __obj name
+ require "#{__rb name}"
+ o=eval(__class(name)).new
+ o.name=name
+ return o
+end
+
+def rm keg
+ #TODO if multiple versions don't rm all unless --force
+ path=$cellar+keg
+ path.rmtree
+ puts "#{path} removed (#{prune} files)"
+end
+
+def ln name
+ keg=$cellar+name
+ keg=keg.realpath
+
+ 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
+
+ # yeah indeed, you have to force anything you need in the main tree into
+ # these directories :P
+ # NOTE that not everything needs to be in the main tree
+ # TODO consider using hardlinks
+ $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
+ :mkpath
+ end
+ end
+
+ lnd(keg, 'share') do |path|
+ includes=(1..9).collect {|x| "man/man#{x}"} <<'man'<<'doc'<<'locale'<<'info'
+ :mkpath if includes.include? path.to_s
+ 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
+ # 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 }
+ ohai 'Finishing up'
+ o.clean
+ 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