2010-01-13 11:07:05 +00:00
FORMULA_META_FILES = %w[ README README.md ChangeLog COPYING LICENSE LICENCE COPYRIGHT AUTHORS ]
2011-01-08 20:21:30 +00:00
PLEASE_REPORT_BUG = " #{ Tty . white } Please follow the instructions to report this bug at: #{ Tty . em } \n https://github.com/mxcl/homebrew/wiki/new-issue #{ Tty . reset } "
2009-09-30 17:45:14 +01:00
2009-12-05 17:28:01 +00:00
def check_for_blacklisted_formula names
return if ARGV . force?
names . each do | name |
case name
2010-06-17 21:33:14 -07:00
when 'tex' , 'tex-live' , 'texlive' then abort <<-EOS.undent
Installing TeX from source is weird and gross , requires a lot of patches ,
and only builds 32 - bit ( and thus can ' t use Homebrew deps on Snow Leopard . )
2009-12-05 17:28:01 +00:00
2010-06-17 21:33:14 -07:00
We recommend using a MacTeX distribution :
http : / / www . tug . org / mactex /
EOS
2009-12-05 17:28:01 +00:00
2010-06-17 21:33:14 -07:00
when 'mercurial' , 'hg' then abort <<-EOS.undent
Mercurial can be install thusly :
brew install pip && pip install mercurial
2009-12-05 17:28:01 +00:00
EOS
2010-06-29 15:04:58 -07:00
2011-02-12 15:52:11 -08:00
when 'npm' then abort <<-EOS.undent
npm can be installed thusly by following the instructions at
http : / /n pmjs . org /
To do it in one line , use this command :
curl http : / /n pmjs . org / install . sh | sudo sh
EOS
2010-06-29 15:04:58 -07:00
when 'setuptools' then abort <<-EOS.undent
When working with a Homebrew - built Python , distribute is preferred
2010-09-26 18:06:43 -07:00
over setuptools , and can be used as the prerequisite for pip .
2010-06-29 15:04:58 -07:00
Install distribute using :
brew install distribute
EOS
2009-12-05 17:28:01 +00:00
end
end
end
2009-09-28 17:01:44 +01:00
def __make url , name
2009-08-10 16:48:30 +01:00
require 'formula'
2010-03-22 21:19:20 -07:00
require 'digest'
2009-12-22 08:50:10 -05:00
require 'erb'
2009-08-10 16:48:30 +01:00
2009-12-22 08:50:10 -05:00
path = Formula . path ( name )
2009-08-10 16:48:30 +01:00
raise " #{ path } already exists " if path . exist?
2010-03-09 02:12:38 +00:00
if Formula . aliases . include? name and not ARGV . force?
2010-09-22 12:32:16 -07:00
realname = Formula . resolve_alias ( name )
2010-03-09 02:12:38 +00:00
raise <<-EOS.undent
2010-09-22 12:32:16 -07:00
" #{ name } " is an alias for formula " #{ realname } " .
2010-03-09 02:12:38 +00:00
Please check that you are not creating a duplicate .
To force creation use - - force .
EOS
2009-11-16 15:31:15 -08:00
end
2009-08-10 16:48:30 +01:00
2009-12-22 08:50:10 -05:00
if ARGV . include? '--cmake'
mode = :cmake
elsif ARGV . include? '--autotools'
mode = :autotools
else
mode = nil
end
2010-03-22 14:10:31 -07:00
version = Pathname . new ( url ) . version
2009-12-22 08:50:10 -05:00
if version . nil?
2010-03-22 14:10:31 -07:00
opoo " Version cannot be determined from URL. "
puts " You'll need to add an explicit 'version' to the formula. "
else
puts " Version detected as #{ version } . "
end
2010-03-22 21:19:20 -07:00
md5 = ''
if ARGV . include? " --cache " and version != nil
strategy = detect_download_strategy url
if strategy == CurlDownloadStrategy
d = strategy . new url , name , version , nil
the_tarball = d . fetch
2010-03-23 19:56:20 -05:00
md5 = the_tarball . md5
2010-03-22 21:19:20 -07:00
puts " MD5 is #{ md5 } "
else
puts " --cache requested, but we can only cache formulas that use Curl. "
end
end
2009-12-22 08:50:10 -05:00
formula_template = <<-EOS
require 'formula'
class #{Formula.class_s name} <Formula
url '#{url}'
homepage ''
md5 '#{md5}'
< % if mode == :cmake % >
depends_on 'cmake'
< % elsif mode == nil % >
# depends_on 'cmake'
< % end % >
def install
2010-08-11 14:22:44 -07:00
< % if mode == :cmake % >
2009-12-22 08:50:10 -05:00
system " cmake . \# {std_cmake_parameters} "
2010-08-11 14:22:44 -07:00
< % elsif mode == :autotools % >
system " ./configure " , " --disable-debug " , " --disable-dependency-tracking " ,
" --prefix= \# {prefix} "
< % else % >
system " ./configure " , " --disable-debug " , " --disable-dependency-tracking " ,
" --prefix= \# {prefix} "
2009-12-22 08:50:10 -05:00
# system "cmake . \#{std_cmake_parameters}"
2010-08-11 14:22:44 -07:00
< % end % >
2009-12-22 08:50:10 -05:00
system " make install "
2009-08-10 16:48:30 +01:00
end
2009-12-22 08:50:10 -05:00
end
EOS
2009-08-10 16:48:30 +01:00
2009-12-22 08:50:10 -05:00
path . write ( ERB . new ( formula_template , nil , '>' ) . result ( binding ) )
2009-08-10 16:48:30 +01:00
return path
end
2009-09-28 17:01:44 +01:00
def make url
path = Pathname . new url
/ (.*?)[-_.]? #{ path . version } / . match path . basename
unless $1 . to_s . empty?
name = $1
else
print " Formula name [ #{ path . stem } ]: "
gots = $stdin . gets . chomp
if gots . empty?
name = path . stem
else
name = gots
end
end
2009-10-01 15:42:36 +01:00
2009-10-15 16:34:23 +01:00
force_text = " If you really want to make this formula use --force. "
case name . downcase
2010-09-27 18:36:14 -07:00
when 'vim' , 'screen'
2010-08-29 19:06:49 +02:00
raise <<-EOS
#{name} is blacklisted for creation
Apple distributes this program with OS X .
#{force_text}
EOS
2010-09-27 18:36:14 -07:00
when 'libarchive' , 'libpcap'
2010-08-29 19:06:49 +02:00
raise <<-EOS
#{name} is blacklisted for creation
Apple distributes this library with OS X , you can find it in / usr / lib .
#{force_text}
EOS
2010-09-27 18:36:14 -07:00
when 'libxml' , 'libxlst' , 'freetype' , 'libpng'
2009-10-01 15:42:36 +01:00
raise <<-EOS
#{name} is blacklisted for creation
Apple distributes this library with OS X , you can find it in / usr / X11 / lib .
However not all build scripts look here , so you may need to call ENV . x11 or
ENV . libxml2 in your formula ' s install function .
2009-10-15 16:34:23 +01:00
#{force_text}
2009-10-01 15:42:36 +01:00
EOS
2010-09-27 18:36:14 -07:00
when 'rubygem'
2009-11-06 15:06:42 +00:00
raise " Sorry RubyGems comes with OS X so we don't package it. \n \n #{ force_text } "
2010-09-27 18:36:14 -07:00
when 'wxwidgets'
2010-01-16 15:40:14 +00:00
raise <<-EOS
#{name} is blacklisted for creation
An older version of wxWidgets is provided by Apple with OS X , but
a formula for wxWidgets 2 . 8 . 10 is provided :
brew install wxmac
#{force_text}
EOS
2009-10-15 16:34:23 +01:00
end unless ARGV . force?
2009-10-01 15:42:36 +01:00
2009-09-28 17:01:44 +01:00
__make url , name
end
2009-11-25 19:57:47 -08:00
def github_info name
formula_name = Formula . path ( name ) . basename
2010-07-27 17:44:43 +02:00
user = 'mxcl'
branch = 'master'
2009-11-25 19:57:47 -08:00
if system " /usr/bin/which -s git "
2010-07-27 17:44:43 +02:00
gh_user = ` git config --global github.user 2>/dev/null ` . chomp
/ ^ \ * \ s*(.*) / . match ( ` git --work-tree= #{ HOMEBREW_REPOSITORY } branch 2>/dev/null ` )
unless $1 . nil? || $1 . empty? || gh_user . empty?
branch = $1 . chomp
user = gh_user
end
2009-11-25 19:57:47 -08:00
end
2009-12-12 16:22:54 +00:00
return " http://github.com/ #{ user } /homebrew/commits/ #{ branch } /Library/Formula/ #{ formula_name } "
2009-11-25 19:57:47 -08:00
end
2009-09-28 17:01:44 +01:00
2010-03-09 02:13:33 +00:00
def info f
2010-07-27 06:37:49 -07:00
exec 'open' , github_info ( f . name ) if ARGV . flag? '--github'
2009-08-10 16:48:30 +01:00
puts " #{ f . name } #{ f . version } "
puts f . homepage
2009-11-25 19:57:47 -08:00
puts " Depends on: #{ f . deps . join ( ', ' ) } " unless f . deps . empty?
2009-10-17 02:46:39 -04:00
2009-08-10 16:48:30 +01:00
if f . prefix . parent . directory?
kids = f . prefix . parent . children
kids . each do | keg |
2010-09-02 11:47:18 -04:00
next if keg . basename . to_s == '.DS_Store'
2009-08-10 16:48:30 +01:00
print " #{ keg } ( #{ keg . abv } ) "
2010-09-24 11:55:21 -05:00
print " * " if f . installed_prefix == keg and kids . length > 1
2009-08-10 16:48:30 +01:00
puts
end
else
puts " Not installed "
end
if f . caveats
puts
puts f . caveats
puts
end
2010-03-09 02:13:33 +00:00
history = github_info ( f . name )
2009-11-25 19:57:47 -08:00
puts history if history
2009-08-10 16:48:30 +01:00
rescue FormulaUnavailableError
# check for DIY installation
d = HOMEBREW_PREFIX + name
if d . directory?
ohai " DIY Installation "
d . children . each { | keg | puts " #{ keg } ( #{ keg . abv } ) " }
else
raise " No such formula or keg "
end
end
2010-01-06 23:38:07 +00:00
def issues_for_formula name
# bit basic as depends on the issue at github having the exact name of the
# formula in it. Which for stuff like objective-caml is unlikely. So we
# really should search for aliases too.
name = f . name if Formula === name
require 'open-uri'
require 'yaml'
issues = [ ]
open ( " http://github.com/api/v2/yaml/issues/search/mxcl/homebrew/open/ " + name ) do | f |
YAML :: load ( f . read ) [ 'issues' ] . each do | issue |
issues << 'http://github.com/mxcl/homebrew/issues/#issue/%s' % issue [ 'number' ]
end
end
issues
rescue
[ ]
end
2009-08-10 16:48:30 +01:00
2009-12-22 11:31:54 -06:00
def cleanup name
require 'formula'
f = Formula . factory name
2010-08-20 08:53:38 -07:00
formula_cellar = f . prefix . parent
2009-12-22 11:31:54 -06:00
2010-08-20 08:53:38 -07:00
if f . installed? and formula_cellar . directory?
2009-12-22 11:31:54 -06:00
kids = f . prefix . parent . children
kids . each do | keg |
2010-09-24 11:55:21 -05:00
next if f . installed_prefix == keg
2009-12-22 11:31:54 -06:00
print " Uninstalling #{ keg } ... "
FileUtils . rm_rf keg
puts
end
2010-02-16 15:35:37 +01:00
else
2010-08-20 08:53:38 -07:00
# If the cellar only has one version installed, don't complain
# that we can't tell which one to keep.
if formula_cellar . children . length > 1
opoo " Skipping #{ name } : most recent version #{ f . version } not installed "
end
2009-12-22 11:31:54 -06:00
end
end
2009-08-10 16:48:30 +01:00
def clean f
2010-08-21 11:06:02 -07:00
require 'cleaner'
2009-08-10 16:48:30 +01:00
Cleaner . new f
2009-09-21 16:12:01 -07:00
# Hunt for empty folders and nuke them unless they are
2009-09-22 11:38:22 +01:00
# protected by f.skip_clean?
2009-09-21 16:12:01 -07:00
# We want post-order traversal, so put the dirs in a stack
# and then pop them off later.
2009-09-22 11:38:22 +01:00
paths = [ ]
f . prefix . find do | path |
paths << path if path . directory?
2009-09-21 16:12:01 -07:00
end
2009-09-22 11:38:22 +01:00
2009-09-21 16:12:01 -07:00
until paths . empty? do
2009-09-22 11:38:22 +01:00
d = paths . pop
if d . children . empty? and not f . skip_clean? d
puts " rmdir: #{ d } (empty) " if ARGV . verbose?
d . rmdir
2009-09-21 16:12:01 -07:00
end
end
2009-08-10 16:48:30 +01:00
end
def prune
$n = 0
$d = 0
dirs = Array . new
2009-08-12 09:43:16 +08:00
paths = %w[ bin sbin etc lib include share ] . collect { | d | HOMEBREW_PREFIX + d }
2009-08-10 16:48:30 +01:00
paths . each do | path |
path . find do | path |
path . extend ObserverPathnameExtension
if path . symlink?
path . unlink unless path . resolved_path_exists?
elsif path . directory?
dirs << path
end
end
end
dirs . sort . reverse_each { | d | d . rmdir_if_possible }
if $n == 0 and $d == 0
puts " Nothing pruned " if ARGV . verbose?
else
# always showing symlinks text is deliberate
print " Pruned #{ $n } symbolic links "
2009-08-08 14:10:32 +01:00
print " and #{ $d } directories " if $d > 0
2009-08-10 16:48:30 +01:00
puts " from #{ HOMEBREW_PREFIX } "
end
end
2009-08-12 13:43:51 +01:00
def diy
path = Pathname . getwd
2009-08-22 17:09:42 +01:00
if ARGV . include? '--set-version'
version = ARGV . next
else
version = path . version
2010-02-28 23:40:26 +00:00
raise " Couldn't determine version, try --set-version " if version . to_s . empty?
2009-08-22 17:09:42 +01:00
end
if ARGV . include? '--set-name'
name = ARGV . next
else
path . basename . to_s =~ / (.*?)-? #{ version } /
if $1 . nil? or $1 . empty?
name = path . basename
else
name = $1
end
end
2009-08-12 13:43:51 +01:00
prefix = HOMEBREW_CELLAR + name + version
if File . file? 'CMakeLists.txt'
" -DCMAKE_INSTALL_PREFIX= #{ prefix } "
elsif File . file? 'Makefile.am'
" --prefix= #{ prefix } "
2010-02-28 23:40:26 +00:00
else
raise " Couldn't determine build system "
2009-08-12 13:43:51 +01:00
end
end
2009-10-26 18:14:39 +00:00
def macports_or_fink_installed?
2009-09-27 23:55:40 +01:00
# See these issues for some history:
# http://github.com/mxcl/homebrew/issues/#issue/13
2009-09-28 12:53:10 +13:00
# http://github.com/mxcl/homebrew/issues/#issue/41
2009-09-27 23:55:40 +01:00
# http://github.com/mxcl/homebrew/issues/#issue/48
2009-10-26 18:14:39 +00:00
2009-09-27 23:55:40 +01:00
%w[ port fink ] . each do | ponk |
path = ` /usr/bin/which -s #{ ponk } `
2009-10-26 18:14:39 +00:00
return ponk unless path . empty?
2009-09-23 16:41:47 +01:00
end
2009-10-26 18:14:39 +00:00
2009-09-27 23:55:40 +01:00
# we do the above check because macports can be relocated and fink may be
# able to be relocated in the future. This following check is because if
# fink and macports are not in the PATH but are still installed it can
# *still* break the build -- because some build scripts hardcode these paths:
%w[ /sw/bin/fink /opt/local/bin/port ] . each do | ponk |
2009-10-26 18:14:39 +00:00
return ponk if File . exist? ponk
2009-09-27 23:55:40 +01:00
end
2009-10-26 18:14:39 +00:00
# finally, sometimes people make their MacPorts or Fink read-only so they
2009-09-27 23:55:40 +01:00
# can quickly test Homebrew out, but still in theory obey the README's
# advise to rename the root directory. This doesn't work, many build scripts
# error out when they try to read from these now unreadable directories.
%w[ /sw /opt/local ] . each do | path |
2009-10-26 18:14:39 +00:00
path = Pathname . new ( path )
return path if path . exist? and not path . readable?
2009-09-23 16:41:47 +01:00
end
2009-10-26 18:14:39 +00:00
false
2009-09-23 16:41:47 +01:00
end
2009-09-24 21:46:04 +01:00
2009-09-25 19:04:34 +12:00
def versions_of ( keg_name )
2010-01-13 05:36:37 +00:00
` /bin/ls #{ HOMEBREW_CELLAR } / #{ keg_name } ` . collect { | version | version . strip } . reverse
2009-09-25 19:04:34 +12:00
end
2010-06-08 11:13:22 -07:00
def outdated_brews
require 'formula'
results = [ ]
HOMEBREW_CELLAR . subdirs . each do | keg |
2010-06-21 21:22:34 +09:00
# Skip kegs with no versions installed
2010-06-08 11:13:22 -07:00
next unless keg . subdirs
2010-06-21 21:22:34 +09:00
# Skip HEAD formulae, consider them "evergreen"
next if keg . subdirs . collect { | p | p . basename . to_s } . include? " HEAD "
2010-06-08 11:13:22 -07:00
name = keg . basename . to_s
if ( not ( f = Formula . factory ( name ) ) . installed? rescue nil )
results << [ keg , name , f . version ]
end
end
return results
end
2010-06-17 10:45:16 -07:00
def search_brews text
require " formula "
2010-03-09 02:14:44 +00:00
return Formula . names if text . to_s . empty?
rx = if text =~ %r{ ^/(.*)/$ }
Regexp . new ( $1 )
2010-06-17 10:45:16 -07:00
else
2010-03-09 02:14:44 +00:00
/ .* #{ Regexp . escape text } .* /i
2010-06-17 11:20:23 -07:00
end
2010-03-09 02:14:44 +00:00
aliases = Formula . aliases
results = ( Formula . names + aliases ) . grep rx
2010-06-17 11:20:23 -07:00
# Filter out aliases when the full name was also found
2010-03-09 02:14:44 +00:00
results . reject do | alias_name |
if aliases . include? alias_name
2010-09-22 12:32:16 -07:00
results . include? Formula . resolve_alias ( alias_name )
2010-03-09 02:14:44 +00:00
end
2010-06-17 10:45:16 -07:00
end
end
2010-06-23 12:59:02 -07:00
def brew_install
require 'formula_installer'
require 'hardware'
############################################################ sanity checks
case Hardware . cpu_type when :ppc , :dunno
abort " Sorry, Homebrew does not support your computer's CPU architecture. \n " +
" For PPC support, see: http://github.com/sceaga/homebrew/tree/powerpc "
end
raise " Cannot write to #{ HOMEBREW_CELLAR } " if HOMEBREW_CELLAR . exist? and not HOMEBREW_CELLAR . writable?
raise " Cannot write to #{ HOMEBREW_PREFIX } " unless HOMEBREW_PREFIX . writable?
################################################################# warnings
begin
if MACOS_VERSION > = 10 . 6
2010-09-07 13:23:43 -07:00
opoo " You should upgrade to Xcode 3.2.3 " if llvm_build < RECOMMENDED_LLVM
2010-06-23 12:59:02 -07:00
else
opoo " You should upgrade to Xcode 3.1.4 " if ( gcc_40_build < RECOMMENDED_GCC_40 ) or ( gcc_42_build < RECOMMENDED_GCC_42 )
end
rescue
# the reason we don't abort is some formula don't require Xcode
# TODO allow formula to declare themselves as "not needing Xcode"
opoo " Xcode is not installed! Builds may fail! "
end
if macports_or_fink_installed?
2010-10-16 23:41:24 -04:00
opoo " It appears you have MacPorts or Fink installed. "
puts " Software installed with MacPorts and Fink are known to cause problems. "
puts " If you experience issues try uninstalling these tools. "
2010-06-23 12:59:02 -07:00
end
################################################################# install!
installer = FormulaInstaller . new
installer . install_deps = ! ARGV . include? ( '--ignore-dependencies' )
ARGV . formulae . each do | f |
if not f . installed? or ARGV . force?
installer . install f
else
puts " Formula already installed: #{ f . prefix } "
end
end
end
2009-09-24 21:46:04 +01:00
########################################################## class PrettyListing
class PrettyListing
def initialize path
Pathname . new ( path ) . children . sort { | a , b | a . to_s . downcase < = > b . to_s . downcase } . each do | pn |
case pn . basename . to_s
when 'bin' , 'sbin'
pn . find { | pnn | puts pnn unless pnn . directory? }
when 'lib'
print_dir pn do | pnn |
# dylibs have multiple symlinks and we don't care about them
( pnn . extname == '.dylib' or pnn . extname == '.pc' ) and not pnn . symlink?
end
else
2009-09-30 17:45:14 +01:00
if pn . directory?
2010-09-12 22:10:28 +01:00
if pn . symlink?
puts " #{ pn } -> #{ pn . readlink } "
else
print_dir pn
end
2010-10-12 15:24:00 -04:00
elsif not ( FORMULA_META_FILES . include? pn . basename . to_s or pn . basename . to_s == '.DS_Store' )
2009-09-30 17:45:14 +01:00
puts pn
end
2009-09-24 21:46:04 +01:00
end
end
end
private
def print_dir root
dirs = [ ]
remaining_root_files = [ ]
other = ''
root . children . sort . each do | pn |
if pn . directory?
dirs << pn
elsif block_given? and yield pn
puts pn
other = 'other '
else
2010-10-12 15:24:00 -04:00
remaining_root_files << pn unless pn . basename . to_s == '.DS_Store'
2009-09-24 21:46:04 +01:00
end
end
dirs . each do | d |
files = [ ]
d . find { | pn | files << pn unless pn . directory? }
print_remaining_files files , d
end
print_remaining_files remaining_root_files , root , other
end
def print_remaining_files files , root , other = ''
case files . length
when 0
# noop
when 1
2010-10-25 21:11:45 -07:00
puts files
2009-09-24 21:46:04 +01:00
else
2009-09-30 00:27:15 +01:00
puts " #{ root } / ( #{ files . length } #{ other } files) "
2009-09-24 21:46:04 +01:00
end
end
end
2010-03-16 13:08:32 -07:00
def gcc_42_build
2009-11-09 18:47:26 +00:00
` /usr/bin/gcc-4.2 -v 2>&1 ` =~ / build ( \ d{4,}) /
2009-12-01 10:51:46 +00:00
if $1
$1 . to_i
2009-12-30 19:21:48 +00:00
elsif system " /usr/bin/which gcc "
# Xcode 3.0 didn't come with gcc-4.2
# We can't change the above regex to use gcc because the version numbers
# are different and thus, not useful.
# FIXME I bet you 20 quid this causes a side effect — magic values tend to
401
2009-12-01 10:51:46 +00:00
else
nil
end
2009-11-09 18:47:26 +00:00
end
2010-03-16 13:08:32 -07:00
alias :gcc_build :gcc_42_build # For compatibility
def gcc_40_build
` /usr/bin/gcc-4.0 -v 2>&1 ` =~ / build ( \ d{4,}) /
if $1
$1 . to_i
else
nil
end
end
2009-11-09 18:47:26 +00:00
def llvm_build
if MACOS_VERSION > = 10 . 6
2010-04-15 13:07:59 -07:00
xcode_path = ` /usr/bin/xcode-select -print-path ` . chomp
return nil if xcode_path . empty?
2010-06-16 13:32:09 -07:00
` #{ xcode_path } /usr/bin/llvm-gcc -v 2>&1 ` =~ / LLVM build ( \ d{4,}) /
2009-11-09 18:47:26 +00:00
$1 . to_i
end
end
2010-09-22 13:37:11 -07:00
2010-10-01 21:08:42 -07:00
def xcode_version
` xcodebuild -version 2>&1 ` =~ / Xcode ( \ d( \ . \ d)*) /
return $1 ? $1 : nil
end
2010-09-22 13:37:11 -07:00
def _compiler_recommendation build , recommended
message = ( ! build . nil? && build < recommended ) ? " ( #{ recommended } or newer recommended) " : " "
return build , message
end