2011-03-16 02:46:46 +01:00
|
|
|
require 'pathname'
|
|
|
|
|
2009-10-15 14:42:19 +01:00
|
|
|
class Tty
|
|
|
|
class <<self
|
|
|
|
def blue; bold 34; end
|
|
|
|
def white; bold 39; end
|
|
|
|
def red; underline 31; end
|
|
|
|
def yellow; underline 33 ; end
|
|
|
|
def reset; escape 0; end
|
2009-11-11 18:36:50 +00:00
|
|
|
def em; underline 39; end
|
2009-10-15 14:42:19 +01:00
|
|
|
|
|
|
|
private
|
|
|
|
def color n
|
|
|
|
escape "0;#{n}"
|
|
|
|
end
|
|
|
|
def bold n
|
|
|
|
escape "1;#{n}"
|
|
|
|
end
|
|
|
|
def underline n
|
|
|
|
escape "4;#{n}"
|
|
|
|
end
|
|
|
|
def escape n
|
|
|
|
"\033[#{n}m" if $stdout.tty?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-08 14:05:09 +01:00
|
|
|
# args are additional inputs to puts until a nil arg is encountered
|
2009-09-16 19:29:43 +01:00
|
|
|
def ohai title, *sput
|
2009-10-23 16:05:32 +01:00
|
|
|
title = title.to_s[0, `/usr/bin/tput cols`.strip.to_i-4] unless ARGV.verbose?
|
2009-10-15 14:42:19 +01:00
|
|
|
puts "#{Tty.blue}==>#{Tty.white} #{title}#{Tty.reset}"
|
2010-10-25 21:11:45 -07:00
|
|
|
puts sput unless sput.empty?
|
2009-07-31 02:51:17 +01:00
|
|
|
end
|
2009-07-31 03:56:46 +01:00
|
|
|
|
|
|
|
def opoo warning
|
2009-10-15 14:42:19 +01:00
|
|
|
puts "#{Tty.red}Warning#{Tty.reset}: #{warning}"
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def onoe error
|
2009-10-01 15:41:15 +01:00
|
|
|
lines = error.to_s.split'\n'
|
2009-10-15 14:42:19 +01:00
|
|
|
puts "#{Tty.red}Error#{Tty.reset}: #{lines.shift}"
|
2010-10-25 21:11:45 -07:00
|
|
|
puts lines unless lines.empty?
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
|
2010-11-09 13:00:33 +00:00
|
|
|
|
2009-08-10 16:48:30 +01:00
|
|
|
def pretty_duration s
|
2009-09-03 20:58:33 +01:00
|
|
|
return "2 seconds" if s < 3 # avoids the plural problem ;)
|
|
|
|
return "#{s.to_i} seconds" if s < 120
|
|
|
|
return "%.1f minutes" % (s/60)
|
2009-08-10 16:48:30 +01:00
|
|
|
end
|
|
|
|
|
2010-08-20 10:01:49 -07:00
|
|
|
def interactive_shell f=nil
|
|
|
|
unless f.nil?
|
|
|
|
ENV['HOMEBREW_DEBUG_PREFIX'] = f.prefix
|
|
|
|
ENV['HOMEBREW_DEBUG_INSTALL'] = f.name
|
|
|
|
end
|
|
|
|
|
2010-06-11 17:18:05 -07:00
|
|
|
fork {exec ENV['SHELL'] }
|
2009-11-09 17:44:29 +00:00
|
|
|
Process.wait
|
|
|
|
unless $?.success?
|
|
|
|
puts "Aborting due to non-zero exit status"
|
|
|
|
exit $?
|
|
|
|
end
|
2009-07-31 03:56:46 +01:00
|
|
|
end
|
2009-08-11 12:20:55 -07:00
|
|
|
|
2010-01-13 09:00:51 +00:00
|
|
|
module Homebrew
|
|
|
|
def self.system cmd, *args
|
|
|
|
puts "#{cmd} #{args*' '}" if ARGV.verbose?
|
|
|
|
fork do
|
|
|
|
yield if block_given?
|
|
|
|
args.collect!{|arg| arg.to_s}
|
|
|
|
exec(cmd, *args) rescue nil
|
|
|
|
exit! 1 # never gets here unless exec failed
|
|
|
|
end
|
|
|
|
Process.wait
|
|
|
|
$?.success?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-11 12:20:55 -07:00
|
|
|
# Kernel.system but with exceptions
|
|
|
|
def safe_system cmd, *args
|
2010-09-11 20:22:54 +01:00
|
|
|
unless Homebrew.system cmd, *args
|
2011-03-14 13:30:46 -07:00
|
|
|
args = args.map{ |arg| arg.to_s.gsub " ", "\\ " } * " "
|
2010-09-11 20:22:54 +01:00
|
|
|
raise "Failure while executing: #{cmd} #{args}"
|
|
|
|
end
|
2010-01-13 09:00:51 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# prints no output
|
|
|
|
def quiet_system cmd, *args
|
|
|
|
Homebrew.system(cmd, *args) do
|
|
|
|
$stdout.close
|
|
|
|
$stderr.close
|
2009-11-09 17:44:29 +00:00
|
|
|
end
|
2009-08-11 12:20:55 -07:00
|
|
|
end
|
|
|
|
|
2009-09-04 15:28:18 +01:00
|
|
|
def curl *args
|
2010-11-26 09:43:07 -08:00
|
|
|
safe_system '/usr/bin/curl', '-f#LA', HOMEBREW_USER_AGENT, *args unless args.empty?
|
2009-08-11 12:20:55 -07:00
|
|
|
end
|
2009-09-04 15:22:25 -07:00
|
|
|
|
2011-01-01 00:49:05 +00:00
|
|
|
def puts_columns items, star_items=[]
|
2009-12-18 16:28:30 -08:00
|
|
|
return if items.empty?
|
|
|
|
|
2011-01-01 00:49:05 +00:00
|
|
|
if star_items && star_items.any?
|
|
|
|
items = items.map{|item| star_items.include?(item) ? "#{item}*" : item}
|
|
|
|
end
|
|
|
|
|
2009-09-22 20:43:06 +02:00
|
|
|
if $stdout.tty?
|
2009-11-14 13:43:07 +13:00
|
|
|
# determine the best width to display for different console sizes
|
2010-01-16 13:12:38 +00:00
|
|
|
console_width = `/bin/stty size`.chomp.split(" ").last.to_i
|
|
|
|
console_width = 80 if console_width <= 0
|
2009-11-14 13:43:07 +13:00
|
|
|
longest = items.sort_by { |item| item.length }.last
|
|
|
|
optimal_col_width = (console_width.to_f / (longest.length + 2).to_f).floor
|
|
|
|
cols = optimal_col_width > 1 ? optimal_col_width : 1
|
|
|
|
|
2010-03-06 03:11:30 +02:00
|
|
|
IO.popen("/usr/bin/pr -#{cols} -t -w#{console_width}", "w"){|io| io.puts(items) }
|
2009-09-22 20:43:06 +02:00
|
|
|
else
|
2010-10-25 21:11:45 -07:00
|
|
|
puts items
|
2009-09-22 20:43:06 +02:00
|
|
|
end
|
2009-09-04 15:22:25 -07:00
|
|
|
end
|
2009-09-05 14:03:41 -04:00
|
|
|
|
|
|
|
def exec_editor *args
|
2010-11-08 13:06:45 +00:00
|
|
|
return if args.to_s.empty?
|
|
|
|
|
2010-07-25 10:56:32 -07:00
|
|
|
editor = ENV['HOMEBREW_EDITOR'] || ENV['EDITOR']
|
2009-09-05 14:03:41 -04:00
|
|
|
if editor.nil?
|
2010-11-09 13:00:33 +00:00
|
|
|
editor = if system "/usr/bin/which -s mate"
|
|
|
|
'mate'
|
2010-07-25 10:56:32 -07:00
|
|
|
elsif system "/usr/bin/which -s edit"
|
2010-11-09 13:00:33 +00:00
|
|
|
'edit' # BBEdit / TextWrangler
|
2009-09-05 14:03:41 -04:00
|
|
|
else
|
2010-11-09 13:00:33 +00:00
|
|
|
'/usr/bin/vim' # Default to vim
|
2009-09-05 14:03:41 -04:00
|
|
|
end
|
|
|
|
end
|
2011-04-12 10:09:33 -07:00
|
|
|
|
|
|
|
# Invoke bash to evaluate env vars in $EDITOR
|
|
|
|
# This also gets us proper argument quoting.
|
|
|
|
# See: https://github.com/mxcl/homebrew/issues/5123
|
|
|
|
system "bash", "-c", editor + ' "$@"', "--", *args
|
2009-09-05 14:03:41 -04:00
|
|
|
end
|
2009-09-08 15:31:28 -07:00
|
|
|
|
2010-11-09 13:00:33 +00:00
|
|
|
# GZips the given paths, and returns the gzipped paths
|
2010-09-12 22:55:52 +02:00
|
|
|
def gzip *paths
|
|
|
|
paths.collect do |path|
|
|
|
|
system "/usr/bin/gzip", path
|
2010-11-09 13:00:33 +00:00
|
|
|
Pathname.new("#{path}.gz")
|
2010-09-12 22:55:52 +02:00
|
|
|
end
|
2010-01-29 10:15:33 -08:00
|
|
|
end
|
|
|
|
|
2010-05-10 10:14:20 -07:00
|
|
|
module ArchitectureListExtension
|
|
|
|
def universal?
|
|
|
|
self.include? :i386 and self.include? :x86_64
|
|
|
|
end
|
2011-03-19 09:49:17 -07:00
|
|
|
|
|
|
|
def remove_ppc!
|
|
|
|
self.delete :ppc7400
|
|
|
|
self.delete :ppc64
|
|
|
|
end
|
|
|
|
|
|
|
|
def as_arch_flags
|
|
|
|
self.collect{ |a| "-arch #{a}" }.join(' ')
|
|
|
|
end
|
2010-05-10 10:14:20 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
# Returns array of architectures that the given command or library is built for.
|
2010-01-13 11:14:58 +00:00
|
|
|
def archs_for_command cmd
|
2010-04-03 11:51:46 -07:00
|
|
|
cmd = cmd.to_s # If we were passed a Pathname, turn it into a string.
|
|
|
|
cmd = `/usr/bin/which #{cmd}` unless Pathname.new(cmd).absolute?
|
|
|
|
cmd.gsub! ' ', '\\ ' # Escape spaces in the filename.
|
|
|
|
|
2011-03-19 09:14:59 -07:00
|
|
|
lines = `/usr/bin/file -L #{cmd}`
|
|
|
|
archs = lines.to_a.inject([]) do |archs, line|
|
2010-04-03 11:51:46 -07:00
|
|
|
case line
|
2010-05-10 10:14:20 -07:00
|
|
|
when /Mach-O (executable|dynamically linked shared library) ppc/
|
2010-04-03 11:51:46 -07:00
|
|
|
archs << :ppc7400
|
2010-05-10 10:14:20 -07:00
|
|
|
when /Mach-O 64-bit (executable|dynamically linked shared library) ppc64/
|
2010-04-03 11:51:46 -07:00
|
|
|
archs << :ppc64
|
2010-05-10 10:14:20 -07:00
|
|
|
when /Mach-O (executable|dynamically linked shared library) i386/
|
2010-04-03 11:51:46 -07:00
|
|
|
archs << :i386
|
2010-05-10 10:14:20 -07:00
|
|
|
when /Mach-O 64-bit (executable|dynamically linked shared library) x86_64/
|
2010-04-03 11:51:46 -07:00
|
|
|
archs << :x86_64
|
|
|
|
else
|
|
|
|
archs
|
2009-09-08 15:31:28 -07:00
|
|
|
end
|
2010-04-03 11:51:46 -07:00
|
|
|
end
|
2010-05-10 10:14:20 -07:00
|
|
|
archs.extend(ArchitectureListExtension)
|
2009-09-08 15:31:28 -07:00
|
|
|
end
|
2009-10-15 12:36:09 +01:00
|
|
|
|
2009-12-17 12:41:54 -08:00
|
|
|
def inreplace path, before=nil, after=nil
|
2010-02-20 02:07:51 +00:00
|
|
|
[*path].each do |path|
|
2010-02-19 15:56:21 +00:00
|
|
|
f = File.open(path, 'r')
|
|
|
|
s = f.read
|
2009-12-17 12:41:54 -08:00
|
|
|
|
2010-02-19 15:56:21 +00:00
|
|
|
if before == nil and after == nil
|
2010-11-12 21:05:35 -08:00
|
|
|
s.extend(StringInreplaceExtension)
|
2010-02-19 15:56:21 +00:00
|
|
|
yield s
|
|
|
|
else
|
|
|
|
s.gsub!(before, after)
|
|
|
|
end
|
2009-12-17 12:41:54 -08:00
|
|
|
|
2010-02-19 15:56:21 +00:00
|
|
|
f.reopen(path, 'w').write(s)
|
|
|
|
f.close
|
|
|
|
end
|
2009-10-15 12:36:09 +01:00
|
|
|
end
|
2009-11-06 17:09:14 +00:00
|
|
|
|
|
|
|
def ignore_interrupts
|
|
|
|
std_trap = trap("INT") {}
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
trap("INT", std_trap)
|
|
|
|
end
|
2009-11-09 18:24:36 +00:00
|
|
|
|
|
|
|
def nostdout
|
|
|
|
if ARGV.verbose?
|
|
|
|
yield
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
require 'stringio'
|
|
|
|
real_stdout = $stdout
|
|
|
|
$stdout = StringIO.new
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
$stdout = real_stdout
|
|
|
|
end
|
|
|
|
end
|
2010-01-13 09:00:51 +00:00
|
|
|
end
|
2010-04-07 21:01:12 -07:00
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
module MacOS extend self
|
2011-03-16 02:46:46 +01:00
|
|
|
|
|
|
|
def default_cc
|
|
|
|
Pathname.new("/usr/bin/cc").realpath.basename.to_s
|
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def gcc_42_build_version
|
|
|
|
`/usr/bin/gcc-4.2 -v 2>&1` =~ /build (\d{4,})/
|
|
|
|
if $1
|
|
|
|
$1.to_i
|
|
|
|
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
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
2010-04-07 21:01:12 -07:00
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def gcc_40_build_version
|
|
|
|
`/usr/bin/gcc-4.0 -v 2>&1` =~ /build (\d{4,})/
|
|
|
|
if $1
|
|
|
|
$1.to_i
|
|
|
|
else
|
|
|
|
nil
|
Add command "brew --env"
"brew --env" will set up a build environment and then dump certain ENV
variables (CC, CXX, LD, CFLAGS, CXXFLAGS, MAKEFLAGS).
If any of CC, CXX, LD are symlinks, now also output the target compiler.
(Typically these will be symlinks from eg /usr/bin/cc to /usr/bin/gcc-4.2).
This is a diagnostic command which may be merged into --config, turned
into an external command, or removed if it doesn't turn out to be useful.
2010-07-13 14:20:52 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-11-13 22:45:22 +00:00
|
|
|
# usually /Developer
|
|
|
|
def xcode_prefix
|
|
|
|
@xcode_prefix ||= begin
|
|
|
|
path = `/usr/bin/xcode-select -print-path 2>&1`.chomp
|
|
|
|
path = Pathname.new path
|
|
|
|
if path.directory? and path.absolute?
|
|
|
|
path
|
|
|
|
elsif File.directory? '/Developer'
|
|
|
|
# we do this to support cowboys who insist on installing
|
|
|
|
# only a subset of Xcode
|
|
|
|
'/Developer'
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-09-11 20:22:54 +01:00
|
|
|
def llvm_build_version
|
2010-11-13 22:45:22 +00:00
|
|
|
unless xcode_prefix.to_s.empty?
|
|
|
|
llvm_gcc_path = xcode_prefix/"usr/bin/llvm-gcc"
|
|
|
|
# for Xcode 3 on OS X 10.5 this will not exist
|
|
|
|
if llvm_gcc_path.file?
|
|
|
|
`#{llvm_gcc_path} -v 2>&1` =~ /LLVM build (\d{4,})/
|
|
|
|
$1.to_i # if nil this raises and then you fix the regex
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
2010-04-07 21:01:12 -07:00
|
|
|
end
|
2010-06-29 10:21:40 -07:00
|
|
|
|
2010-11-09 13:00:33 +00:00
|
|
|
def x11_installed?
|
|
|
|
Pathname.new('/usr/X11/lib/libpng.dylib').exist?
|
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
|
|
|
|
def macports_or_fink_installed?
|
|
|
|
# See these issues for some history:
|
|
|
|
# http://github.com/mxcl/homebrew/issues/#issue/13
|
|
|
|
# http://github.com/mxcl/homebrew/issues/#issue/41
|
|
|
|
# http://github.com/mxcl/homebrew/issues/#issue/48
|
|
|
|
|
|
|
|
%w[port fink].each do |ponk|
|
|
|
|
path = `/usr/bin/which -s #{ponk}`
|
|
|
|
return ponk unless path.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
# 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|
|
|
|
|
return ponk if File.exist? ponk
|
|
|
|
end
|
|
|
|
|
|
|
|
# finally, sometimes people make their MacPorts or Fink read-only so they
|
|
|
|
# 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|
|
|
|
|
path = Pathname.new(path)
|
|
|
|
return path if path.exist? and not path.readable?
|
|
|
|
end
|
|
|
|
|
|
|
|
false
|
|
|
|
end
|
2011-03-18 10:30:26 -07:00
|
|
|
|
2011-04-08 11:16:37 -07:00
|
|
|
def leopard?
|
|
|
|
10.5 == MACOS_VERSION
|
|
|
|
end
|
|
|
|
|
|
|
|
def snow_leopard?
|
|
|
|
10.6 <= MACOS_VERSION # Actually Snow Leopard or newer
|
|
|
|
end
|
|
|
|
|
2011-03-18 10:30:26 -07:00
|
|
|
def prefer_64_bit?
|
2011-04-08 11:16:37 -07:00
|
|
|
Hardware.is_64_bit? and 10.6 <= MACOS_VERSION
|
2011-03-18 10:30:26 -07:00
|
|
|
end
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
module GitHub extend self
|
|
|
|
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|
|
2011-04-07 12:33:30 +02:00
|
|
|
issues << 'https://github.com/mxcl/homebrew/issues/#issue/%s' % issue['number']
|
2010-09-11 20:22:54 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
issues
|
|
|
|
rescue
|
|
|
|
[]
|
|
|
|
end
|
|
|
|
end
|