Refactor--object orientate where sensible
This commit is contained in:
parent
5eb9d6519d
commit
fb5aefd4a0
@ -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
|
@ -21,4 +21,97 @@ $root=Pathname.new(__FILE__).dirname.parent.parent.realpath
|
||||
$formula=$root+'Library'+'Formula'
|
||||
$cellar=$root+'Cellar'
|
||||
|
||||
HOMEBREW_VERSION='0.2'
|
||||
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
|
||||
|
263
Library/Homebrew/formula.rb
Normal file
263
Library/Homebrew/formula.rb
Normal file
@ -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
|
153
Library/Homebrew/keg.rb
Normal file
153
Library/Homebrew/keg.rb
Normal file
@ -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
|
@ -2,7 +2,7 @@
|
||||
|
||||
$:.unshift File.dirname(__FILE__)
|
||||
require 'test/unit'
|
||||
require 'brewkit'
|
||||
require 'formula'
|
||||
require 'stringio'
|
||||
|
||||
class TestFormula <Formula
|
||||
|
33
README
33
README
@ -1,7 +1,7 @@
|
||||
Homebrew
|
||||
========
|
||||
Homebrew's purpose is the same as MacPorts or Fink, ie. to let you easily
|
||||
install other open source software on your Mac.
|
||||
Homebrew's purpose is basically the same as MacPorts or Fink, ie. to let you
|
||||
easily install other open source software on your Mac.
|
||||
|
||||
Here's why you may prefer Homebrew to the alternatives:
|
||||
|
||||
@ -34,30 +34,43 @@ Here's why you may prefer Homebrew to the alternatives:
|
||||
Homebrew will automatically open it for you to tweak with TextMate or
|
||||
$EDITOR.
|
||||
|
||||
Or skip going via a package entirely, just install into the Cellar and use
|
||||
"brew ln" to symlink it into the main tree.
|
||||
6. DIY package installation
|
||||
MacPorts doesn't support the beta version? Need an older version? Need
|
||||
custom compile flags? The Homebrew toolchain is carefully segregated so
|
||||
you can just build your own stuff while still reaping the benefits of
|
||||
package management.
|
||||
|
||||
6. Optimisation
|
||||
Just install to the Cellar and then call brew ln to symlink that
|
||||
installation into /usr/local, eg.
|
||||
|
||||
./configure --prefix=/usr/local/Cellar/wget/1.10
|
||||
make install
|
||||
brew ln wget
|
||||
|
||||
This means you can also install multiple versions of the same package and
|
||||
switch on demand.
|
||||
|
||||
7. Optimisation
|
||||
We optimise for Leopard Intel, binaries are stripped, compile flags
|
||||
tweaked. Nobody wants crappy, slow software. Apart from MacPorts and Fink.
|
||||
|
||||
7. Integration with existing OS X technologies
|
||||
8. Integration with existing OS X technologies
|
||||
Homebrew integrates with Ruby gems, CPAN and Python disttools. These tools
|
||||
exist already and do the job great. We don't reinvent the wheel, we just
|
||||
improve it by making these tools install with more management options.
|
||||
|
||||
8. Complimenting what OS X already has
|
||||
9. Complimenting what OS X already has
|
||||
Macports is an autarky. You get a duplicate copy of libz, OpenSSL, Python
|
||||
etc. They do this to support OS X Tiger, etc. more easily. We don't support
|
||||
Tiger, we duplicate nothing. Homebrew compliments OS X, it doesn't seek to
|
||||
operate independently of it.
|
||||
|
||||
9. Homebrew has a beer theme
|
||||
A. Homebrew has a beer theme
|
||||
Beer goggles will help you to evangelise Homebrew more effectively.
|
||||
|
||||
X. Homebrew helps you get chicks
|
||||
B. Homebrew helps get you chicks
|
||||
There's no conclusive scientific evidence as yet, but I firmly believe it's
|
||||
just a matter of statistics and time.
|
||||
just a matter of time and statistics.
|
||||
|
||||
I know I've made it sound so awesome you can hardly wait to rip MacPorts out
|
||||
and embrace the fresh hoppy taste of Homebrew, but I should point out that it
|
||||
|
370
bin/brew
370
bin/brew
@ -8,6 +8,7 @@ require 'env'
|
||||
# often causes Ruby to throw exception ffs
|
||||
Dir.chdir '/' unless File.directory? ENV['PWD']
|
||||
|
||||
######################################################################## funcs
|
||||
def prune
|
||||
n=0
|
||||
dirs=Array.new
|
||||
@ -37,130 +38,113 @@ def prune
|
||||
return n
|
||||
end
|
||||
|
||||
def formulize name
|
||||
name=Pathname.new name
|
||||
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 shift_formulae_from_ARGV
|
||||
fae=Array.new
|
||||
i=0
|
||||
while name=ARGV[i]
|
||||
unless name[0,1] == '-'
|
||||
fae<<formulize(ARGV.shift).to_s
|
||||
# we actually remove formulae from ARGV so that any other analysis of ARGV
|
||||
# only includes relevent arguments
|
||||
# TODO require will throw if no formula, so we should catch no?
|
||||
def extract_named_args
|
||||
args=Array.new
|
||||
ARGV.delete_if do |arg|
|
||||
if arg[0,1] == '-'
|
||||
false
|
||||
else
|
||||
i+=1
|
||||
args<<arg
|
||||
true
|
||||
end
|
||||
end
|
||||
raise "You must specify a formula" if fae.empty?
|
||||
return fae
|
||||
return args
|
||||
end
|
||||
|
||||
def __class name
|
||||
#remove invalid characters and camelcase
|
||||
name.capitalize.gsub(/[-_\s]([a-zA-Z0-9])/) { $1.upcase }
|
||||
def extract_kegs
|
||||
require 'keg'
|
||||
kegs=extract_named_args.collect {|name| Keg.new name}
|
||||
raise "Expecting the name of a keg or formula, eg:\n\tbrew #{ARGV.join ' '} wget" if kegs.empty?
|
||||
return kegs
|
||||
end
|
||||
|
||||
def __rb name
|
||||
$formula+(name+'.rb')
|
||||
end
|
||||
|
||||
def __obj name
|
||||
require "#{__rb name}"
|
||||
return eval(__class(name)).new(name)
|
||||
end
|
||||
|
||||
def rm keg
|
||||
#TODO if multiple versions don't rm all unless --force
|
||||
path=$cellar+keg
|
||||
`chmod -R u+rw #{path}` # we leave things read only
|
||||
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') {:mkdir}
|
||||
lnd(keg, 'include') {:link}
|
||||
lnd(keg, 'bin') {:link}
|
||||
lnd(keg, 'lib') {|path| :mkpath if ['pkgconfig','php'].include? path.to_s}
|
||||
lnd(keg, 'share') do |path|
|
||||
mkpaths=(1..9).collect {|x| "man/man#{x}"} <<'man'<<'doc'<<'locale'<<'info'<<'aclocal'
|
||||
:mkpath if mkpaths.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
|
||||
def abv keg=nil
|
||||
path=keg ? keg.path : $cellar
|
||||
if path.directory?
|
||||
`find #{path} -type f | wc -l`.strip+' files, '+`du -hd0 #{path} | cut -d"\t" -f1`.strip
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# symlinks a directory recursively into our FHS tree
|
||||
def lnd keg, start
|
||||
start=keg+start
|
||||
return unless start.directory?
|
||||
def install formula
|
||||
require 'keg'
|
||||
|
||||
start.find do |from|
|
||||
next if from == start
|
||||
raise "#{formula.name} already installed!\n\t#{formula.prefix}" if formula.installed?
|
||||
|
||||
prune=false
|
||||
relative_path=from.relative_path_from keg
|
||||
to=$root+relative_path
|
||||
beginning = Time.now
|
||||
|
||||
if 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'
|
||||
|
||||
cmd=yield from.relative_path_from(start)
|
||||
|
||||
if :skip == cmd
|
||||
Find.prune
|
||||
elsif :mkpath == cmd
|
||||
to.mkpath
|
||||
$n+=1
|
||||
formula.brew do
|
||||
if ARGV.include? '--interactive'
|
||||
ohai "Entering interactive mode"
|
||||
puts "Type `exit' to return and finalize the installation"
|
||||
puts "Install to this prefix: #{formula.prefix}"
|
||||
pid=fork
|
||||
if pid.nil?
|
||||
exec 'bash'
|
||||
else
|
||||
symlink_relative_to from, to
|
||||
Find.prune
|
||||
Process.wait pid
|
||||
end
|
||||
elsif ARGV.include? '--help'
|
||||
ohai './configure --help'
|
||||
puts `./configure --help`
|
||||
exit
|
||||
else
|
||||
formula.prefix.mkpath
|
||||
formula.install
|
||||
%w[README ChangeLog COPYING COPYRIGHT AUTHORS].each do |file|
|
||||
formula.prefix.install file if File.file? file
|
||||
end
|
||||
elsif from.file?
|
||||
symlink_relative_to from, to
|
||||
end
|
||||
end
|
||||
ohai 'Finishing up'
|
||||
keg=Keg.new formula
|
||||
keg.clean
|
||||
keg.ln
|
||||
if formula.caveats
|
||||
ohai "Caveats"
|
||||
puts formula.caveats
|
||||
ohai "Summary"
|
||||
end
|
||||
puts "#{keg.path}: "+abv(keg)+", built in #{pretty_duration Time.now-beginning}"
|
||||
rescue Exception
|
||||
formula.prefix.rmtree
|
||||
raise
|
||||
end
|
||||
|
||||
def mk 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 File.exist? path
|
||||
|
||||
f=File.new path, 'w'
|
||||
f.puts "require 'brewkit'"
|
||||
f.puts
|
||||
f.puts "class #{Formula.class $1} <Formula"
|
||||
f.puts " @url='#{url}'"
|
||||
f.puts " @homepage=''" # second because you fill in these two first
|
||||
f.puts " @md5=''"
|
||||
f.puts
|
||||
f.puts " def install"
|
||||
f.puts " system \"./configure --disable-debug --prefix='\#{prefix}'\""
|
||||
f.puts " system \"make install\""
|
||||
f.puts " end"
|
||||
f.print "end"
|
||||
f.close
|
||||
|
||||
return path
|
||||
end
|
||||
|
||||
def prefix
|
||||
Pathname.new(__FILE__).dirname.parent.expand_path
|
||||
end
|
||||
|
||||
def usage
|
||||
@ -181,11 +165,6 @@ Commands:
|
||||
EOS
|
||||
end
|
||||
|
||||
def abv keg=''
|
||||
keg=$cellar+keg
|
||||
return nil if not File.directory? keg
|
||||
`find #{keg} -type f | wc -l`.strip+' files, '+`du -hd0 #{keg} | cut -d"\t" -f1`.strip
|
||||
end
|
||||
|
||||
######################################################################## utils
|
||||
def pretty_duration s
|
||||
@ -197,144 +176,77 @@ end
|
||||
######################################################################### impl
|
||||
begin
|
||||
case ARGV.shift
|
||||
when 'prune'
|
||||
puts "Pruned #{prune} files"
|
||||
when '--prefix'
|
||||
# we use the cwd because __FILE__ can be relative and expand_path
|
||||
# resolves the symlink for the working directory if fed a relative path
|
||||
# NOTE we don't use Dir.pwd because it resolves the symlink :(
|
||||
cwd=Pathname.new `pwd`.strip
|
||||
puts File.expand_path(cwd+__FILE__+'../../')
|
||||
when '--cache'
|
||||
puts File.expand_path('~/Library/Application Support/Homebrew')
|
||||
when '-h', '--help', '--usage', '-?'
|
||||
puts usage
|
||||
when '-v', '--version'
|
||||
puts HOMEBREW_VERSION
|
||||
when 'list'
|
||||
fae=shift_formulae_from_ARGV.collect do |name|
|
||||
keg=$cellar+name
|
||||
keg.directory? ? keg : nil
|
||||
end
|
||||
raise 'No such keg' if fae.first.nil? and fae.length == 1
|
||||
puts `find #{fae.join' '} -type f -print`
|
||||
when 'macports'
|
||||
exec "open 'http://www.macports.org/ports.php?by=name&substr=#{ARGV.shift}'"
|
||||
when '--prefix' then puts prefix
|
||||
when '--cache' then puts Homebrew::cache
|
||||
when '-h', '--help', '--usage', '-?' then puts usage
|
||||
when '-v', '--version' then puts HOMEBREW_VERSION
|
||||
when 'macports' then exec "open 'http://www.macports.org/ports.php?by=name&substr=#{ARGV.shift}'"
|
||||
|
||||
when 'ls', 'list'
|
||||
dirs=extract_kegs.collect {|keg| keg.path}
|
||||
exec "find #{dirs.join' '} -not -type d -print"
|
||||
|
||||
when 'edit'
|
||||
if ARGV.empty?
|
||||
exec "mate #{$formula} #{$root}/Library/Homebrew #{$root}/bin/brew #{$root}/README"
|
||||
else
|
||||
exec "mate #{$formula}/#{ARGV.shift}.rb"
|
||||
paths=extract_kegs.collect {|keg| keg.formula_path.to_s.gsub ' ', '\\ '}
|
||||
exec "mate #{paths.join ' '}"
|
||||
end
|
||||
|
||||
when 'install'
|
||||
shift_formulae_from_ARGV.each do |name|
|
||||
beginning = Time.now
|
||||
o=__obj(name)
|
||||
begin
|
||||
raise "#{o.prefix} already exists!" if o.prefix.exist?
|
||||
o.brew do
|
||||
if ARGV.include? '--interactive'
|
||||
ohai "Entering interactive mode, type `exit' to return to finalize installation"
|
||||
puts "Install to this prefix: #{o.prefix}"
|
||||
pid=fork
|
||||
if pid.nil?
|
||||
exec 'bash'
|
||||
else
|
||||
Process.wait pid
|
||||
end
|
||||
elsif ARGV.include? '--help'
|
||||
ohai './configure --help'
|
||||
puts `./configure --help`
|
||||
exit
|
||||
else
|
||||
o.prefix.mkpath
|
||||
o.install
|
||||
%w[README ChangeLog COPYING COPYRIGHT AUTHORS].each do |file|
|
||||
FileUtils.cp file, o.prefix if File.file? file
|
||||
end
|
||||
#this is common, and we don't want it
|
||||
versioned_docs=o.doc.parent+"#{o.name}-#{o.version}"
|
||||
versioned_docs.rename o.doc if versioned_docs.exist?
|
||||
end
|
||||
end
|
||||
ohai 'Finishing up'
|
||||
o.clean
|
||||
ln name
|
||||
if o.caveats
|
||||
ohai "Caveats"
|
||||
puts o.caveats
|
||||
ohai "Summary"
|
||||
end
|
||||
puts "#{o.prefix}: "+abv(name)+", built in #{pretty_duration Time.now-beginning}"
|
||||
rescue Exception
|
||||
FileUtils.rm_rf o.prefix
|
||||
raise
|
||||
end
|
||||
require 'formula'
|
||||
extract_named_args.each do |name|
|
||||
install Formula.create(name)
|
||||
end
|
||||
|
||||
when 'ln'
|
||||
when 'ln', 'link'
|
||||
n=0
|
||||
shift_formulae_from_ARGV.each {|name| n+=ln name}
|
||||
(kegs=extract_kegs).each do |keg|
|
||||
n+=nn=keg.ln
|
||||
puts "Created #{nn} links for #{keg.name}" if kegs.length > 1
|
||||
end
|
||||
puts "Created #{n} links"
|
||||
|
||||
when 'rm', 'uninstall'
|
||||
shift_formulae_from_ARGV.each {|name| rm name}
|
||||
extract_kegs.each do |keg|
|
||||
puts "Removing #{keg.name}..."
|
||||
keg.rm
|
||||
end
|
||||
print "Pruning #{prefix}/..."
|
||||
puts " #{prune} symbolic links pruned"
|
||||
|
||||
when 'mk'
|
||||
require 'brewkit'
|
||||
url=ARGV.shift
|
||||
version=extract_version File.basename(url, Pathname.new(url).extname)
|
||||
when 'prune'
|
||||
puts "Pruned #{prune} symbolic links"
|
||||
|
||||
/(.*?)[-_.]?#{version}/.match File.basename(url)
|
||||
raise "Couldn't parse name from #{url}" if $1.nil? or $1.empty?
|
||||
|
||||
path=$formula+($1.downcase+'.rb')
|
||||
raise "#{path} already exists!" if File.exist? path
|
||||
|
||||
f=File.new path, 'w'
|
||||
f.puts "require 'brewkit'"
|
||||
f.puts
|
||||
f.puts "class #{__class $1} <Formula"
|
||||
f.puts " @url='#{url}'"
|
||||
f.puts " @homepage=''" # second because you fill in these two first
|
||||
f.puts " @md5=''"
|
||||
f.puts
|
||||
f.puts " def install"
|
||||
f.puts " system \"./configure --disable-debug --prefix='\#{prefix}'\""
|
||||
f.puts " system \"make install\""
|
||||
f.puts " end"
|
||||
f.print "end"
|
||||
f.close
|
||||
|
||||
if Kernel.system "which mate > /dev/null" and $? == 0
|
||||
exec "mate #{path}"
|
||||
when 'mk', 'make'
|
||||
paths=ARGV.collect {|arg| mk arg}
|
||||
if paths.empty?
|
||||
raise "Invalid URL"
|
||||
elsif Kernel.system "which mate > /dev/null" and $? == 0
|
||||
paths=paths.collect {|path| path.to_s.gsub " ", "\\ "}
|
||||
exec "mate #{paths.join ' '}"
|
||||
else
|
||||
puts path
|
||||
puts paths.join("\n")
|
||||
end
|
||||
|
||||
when 'info','abv'
|
||||
when 'info', 'abv'
|
||||
if ARGV.empty?
|
||||
puts abv
|
||||
elsif ARGV[0][0..6] == 'http://'
|
||||
puts Pathname.new(ARGV.shift).version
|
||||
else
|
||||
if ARGV[0][0..6] == 'http://'
|
||||
require 'brewkit'
|
||||
path=Pathname.new ARGV[0]
|
||||
basename=File.basename path, path.extname
|
||||
v=extract_version basename
|
||||
puts v
|
||||
else
|
||||
o=__obj shift_formulae_from_ARGV[0]
|
||||
puts "#{o.name} #{o.version}"
|
||||
puts o.homepage
|
||||
if abv=abv(o.name)
|
||||
ohai "Installation"
|
||||
puts abv
|
||||
end
|
||||
if o.caveats
|
||||
ohai 'Caveats'
|
||||
puts o.caveats
|
||||
end
|
||||
#TODO show outdated status and that
|
||||
keg=extract_kegs[0]
|
||||
frm=Formula.create keg.name
|
||||
puts "#{keg.name} #{keg.version}"
|
||||
puts frm.homepage
|
||||
if keg.installed?
|
||||
puts "#{abv keg} (installed to #{keg.path})"
|
||||
end
|
||||
if frm.caveats
|
||||
ohai 'Caveats'
|
||||
puts frm.caveats
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user