Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 379 lines (342 sloc) 11.905 kb
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# Many Pathname operations use getwd when they shouldn't, and then throw
# odd exceptions. Reduce our support burden by showing a user-friendly error.
Dir.getwd rescue abort "The current working directory doesn't exist, cannot proceed."
HOMEBREW_BREW_FILE = ENV['HOMEBREW_BREW_FILE'] = File.expand_path(__FILE__)
require 'pathname'
HOMEBREW_LIBRARY_PATH = (Pathname.new(__FILE__).realpath.dirname.parent+"Library/Homebrew").to_s
$:.unshift(HOMEBREW_LIBRARY_PATH)
require 'global'
case ARGV.first
when '-h', '--help', '--usage', '-?', 'help', nil
puts ARGV.usage
exit 0
when '--version'
puts HOMEBREW_VERSION
exit 0
when '-v'
if ARGV.length > 1
puts "Homebrew #{HOMEBREW_VERSION}"
# continue in verbose mode
ARGV << ARGV.shift
else
puts HOMEBREW_VERSION
exit 0
end
end
case HOMEBREW_PREFIX.to_s when '/', '/usr'
# it may work, but I only see pain this route and don't want to support it
abort "Cowardly refusing to continue at this prefix: #{HOMEBREW_PREFIX}"
end
if MACOS_VERSION < 10.5
abort "Homebrew requires Leopard or higher. For Tiger support, see:\nhttp://github.com/sceaga/homebrew/tree/tiger"
end
def dump_config
require 'hardware'
bits = Hardware.bits
cores = Hardware.cores_as_words
llvm = llvm_build
gcc_42 = gcc_42_build
gcc_40 = gcc_40_build
sha = `cd #{HOMEBREW_REPOSITORY} && git rev-parse --verify HEAD 2> /dev/null`.chomp
kernel_arch = `uname -m`.chomp
puts <<-EOS
HOMEBREW_VERSION: #{HOMEBREW_VERSION}
HEAD: #{sha}
HOMEBREW_PREFIX: #{HOMEBREW_PREFIX}
HOMEBREW_CELLAR: #{HOMEBREW_CELLAR}
HOMEBREW_CACHE: #{HOMEBREW_CACHE}
HOMEBREW_REPOSITORY: #{HOMEBREW_REPOSITORY}
HOMEBREW_LIBRARY_PATH: #{HOMEBREW_LIBRARY_PATH}
Hardware: #{cores}-core #{bits}-bit #{Hardware.intel_family}
OS X: #{MACOS_FULL_VERSION}
Kernel Architecture: #{kernel_arch}
Ruby: #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}
GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"} (#{RECOMMENDED_GCC_40} or newer recommended)
GCC-4.2: #{gcc_42 ? "build #{gcc_42}" : "N/A"} (#{RECOMMENDED_GCC_42} or newer recommended)
LLVM: #{llvm ? "build #{llvm}" : "N/A" } #{llvm ? "(#{RECOMMENDED_LLVM} or newer recommended)" : "" }
MacPorts or Fink? #{macports_or_fink_installed?}
X11 installed? #{x11_installed?}
EOS
end
begin
require 'brew.h'
case arg = ARGV.shift
when '--cache'
if ARGV.named.empty?
puts HOMEBREW_CACHE
else
puts *ARGV.formulae.collect {|f| f.cached_download rescue '(built from source control)'}
end
when '--prefix'
if ARGV.named.empty?
puts HOMEBREW_PREFIX
else
puts *ARGV.formulae.collect {|f| f.prefix}
end
when '--repository'
puts HOMEBREW_REPOSITORY
when '--cellar'
if ARGV.named.empty?
puts HOMEBREW_CELLAR
else
puts *ARGV.formulae.collect {|f| HOMEBREW_CELLAR+f.name}
end
when '--config'
dump_config
when '--env'
require 'hardware'
require 'extend/ENV'
ENV.extend(HomebrewEnvExtension)
ENV.setup_build_environment
dump_build_env ENV
when 'home', 'homepage'
if ARGV.named.empty?
exec "open", HOMEBREW_WWW
else
exec "open", *ARGV.formulae.collect {|f| f.homepage}
end
when 'ls', 'list'
if ARGV.flag? '--unbrewed'
dirs = HOMEBREW_PREFIX.children.select { |pn| pn.directory? }.collect { |pn| pn.basename.to_s }
dirs -= ['Library', 'Cellar', '.git']
Dir.chdir HOMEBREW_PREFIX
exec 'find', *dirs + %w[-type f ( ! -iname .ds_store ! -iname brew )]
elsif ARGV.flag? '--versions'
if ARGV.named.empty?
to_list = HOMEBREW_CELLAR.children.select { |pn| pn.directory? }
else
to_list = ARGV.named.collect { |n| HOMEBREW_CELLAR+n }.select { |pn| pn.exist? }
end
to_list.each do |d|
versions = d.children.select { |pn| pn.directory? }.collect { |pn| pn.basename.to_s }
puts "#{d.basename} #{versions *' '}"
end
elsif ARGV.named.empty?
ENV['CLICOLOR']=nil
exec 'ls', *ARGV.options_only<<HOMEBREW_CELLAR if HOMEBREW_CELLAR.exist?
elsif ARGV.verbose? or not $stdout.tty?
exec "find", *ARGV.kegs+%w[-not -type d -print]
else
ARGV.kegs.each { |keg| PrettyListing.new keg }
end
when 'search', '-S'
if ARGV.include? '--macports'
exec "open", "http://www.macports.org/ports.php?by=name&substr=#{ARGV.next}"
elsif ARGV.include? '--fink'
exec "open", "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}"
end
check_for_blacklisted_formula(ARGV.named)
puts_columns search_brews(ARGV.first)
when 'edit'
if ARGV.named.empty?
# EDITOR isn't a good fit here, we need a GUI client that actually has
# a UI for projects, so apologies if this wasn't what you expected,
# please improve it! :)
exec 'mate', *Dir["#{HOMEBREW_REPOSITORY}/Library/*"]<<
"#{HOMEBREW_REPOSITORY}/bin/brew"<<
"#{HOMEBREW_REPOSITORY}/README.md"
else
# Don't use ARGV.formulae as that will throw if the file doesn't parse
paths = ARGV.named.collect do |name|
path = "#{HOMEBREW_REPOSITORY}/Library/Formula/#{ARGV.resolve_alias(name)}.rb"
unless File.exist? path
require 'formula'
raise FormulaUnavailableError, name
else
path
end
end
exec_editor *paths
end
when 'up', 'update'
abort "Please `brew install git' first." unless system "/usr/bin/which -s git"
require 'update'
updater = RefreshBrew.new
unless updater.update_from_masterbrew!
puts "Already up-to-date."
else
updater.report
end
when 'ln', 'link'
ARGV.kegs.each {|keg| puts "#{keg.link} links created for #{keg}"}
when 'unlink'
ARGV.kegs.each {|keg| puts "#{keg.unlink} links removed for #{keg}"}
when 'rm', 'uninstall', 'remove'
ARGV.kegs.each do |keg|
puts "Uninstalling #{keg}..."
keg.unlink
keg.uninstall
end
when 'prune'
prune
when 'create'
if ARGV.include? '--macports'
exec "open", "http://www.macports.org/ports.php?by=name&substr=#{ARGV.next}"
elsif ARGV.include? '--fink'
exec "open", "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}"
elsif ARGV.named.empty?
raise UsageError
else
exec_editor *ARGV.named.collect {|name| make name}
end
when 'diy', 'configure'
puts diy
when 'info', 'abv'
if ARGV.named.empty?
if ARGV.include? "--all"
require 'formula'
Formula.all.each do |f|
info f
puts '---'
end
else
puts `ls #{HOMEBREW_CELLAR} | wc -l`.strip+" kegs, "+HOMEBREW_CELLAR.abv
end
elsif ARGV[0][0..6] == 'http://' or ARGV[0][0..7] == 'https://' or ARGV[0][0..5] == 'ftp://'
path = Pathname.new(ARGV.shift)
/(.*?)[-_.]?#{path.version}/.match path.basename
unless $1.to_s.empty?
name = $1
else
name = path.stem
end
puts "#{name} #{path.version}"
else
ARGV.formulae.each{ |f| info f }
end
when 'cleanup'
if ARGV.named.empty?
require 'formula'
HOMEBREW_CELLAR.children.each do |rack|
begin
cleanup(rack.basename.to_s) if rack.directory?
rescue FormulaUnavailableError => e
opoo "Formula not found for #{e.name}"
end
end
prune # seems like a good time to do some additional cleanup
else
ARGV.named.each { |name| cleanup name}
end
when 'install'
check_for_blacklisted_formula(ARGV.named)
brew_install
when 'log'
Dir.chdir HOMEBREW_REPOSITORY
args = ARGV.options_only
args.unshift ARGV.formulae.first.path unless ARGV.named.empty?
exec "git", "log", *args
# For each formula given, show which other formulas depend on it.
# We only go one level up, ie. direct dependencies.
when 'uses'
uses = ARGV.formulae.map{ |f| Formula.all.select{ |ff| ff.deps.include? f.name }.map{|f| f.name} }.flatten.uniq
uses = uses.select { |f| Formula.factory(f).installed? } if ARGV.include? "--installed"
puts *uses.sort
when 'deps'
if ARGV.include?('--all')
require 'formula'
Formula.all.each do |f|
puts "#{f.name}:#{f.deps.join(' ')}"
end
elsif ARGV.include?("-1") or ARGV.include?("--1")
puts *ARGV.formulae.map{ |f| f.deps or [] }.flatten.uniq.sort
else
require 'formula_installer'
puts *ARGV.formulae.map{ |f| FormulaInstaller.expand_deps(f).map{|f| f.name} }.flatten.uniq.sort
end
when 'cat'
Dir.chdir HOMEBREW_REPOSITORY
exec "cat", ARGV.formulae.first.path, *ARGV.options_only
when 'outdated'
outdated_brews.each do |keg, name, version|
if $stdout.tty? and not ARGV.flag? '--quiet'
versions = keg.cd{ Dir['*'] }.join(', ')
puts "#{name} (#{versions} < #{version})"
else
puts name
end
end
when 'doctor', 'dr'
require 'brew_doctor'
brew_doctor
else
# Add example external commands to PATH before checking.
ENV['PATH'] += ":#{HOMEBREW_REPOSITORY}/Library/Contributions/examples"
# Check for an external shell command
if system "/usr/bin/which -s brew-#{arg}"
# Add some Homebrew vars to the ENV
['CACHE', 'CELLAR', 'LIBRARY_PATH', 'PREFIX', 'REPOSITORY'].each do |e|
ENV["HOMEBREW_#{e}"] = eval("HOMEBREW_#{e}")
end
exec("brew-#{arg}", *ARGV)
end
# Check for an external ruby command
external_rb = `/usr/bin/which brew-#{arg}.rb`.chomp
unless external_rb.empty?
require external_rb
exit 0
end
# Check for git commands
if ['branch', 'checkout', 'pull', 'push', 'rebase', 'reset'].include? arg
onoe "Unknown command: #{arg} (did you mean 'git #{arg}'?)"
else
onoe "Unknown command: #{arg}"
end
end
rescue FormulaUnspecifiedError
abort "This command requires a formula argument"
rescue KegUnspecifiedError
abort "This command requires a keg argument"
rescue UsageError
onoe "Invalid usage"
abort ARGV.usage
rescue SystemExit
puts "Kernel.exit" if ARGV.verbose?
raise
rescue Interrupt => e
puts # seemingly a newline is typical
exit 130
rescue BuildError => e
e.backtrace[1] =~ %r{Library/Formula/(.+)\.rb:(\d+)}
formula_name = $1
error_line = $2
puts "Exit status: #{e.exit_status}"
puts
puts "http://github.com/mxcl/homebrew/blob/master/Library/Formula/#{formula_name}.rb#L#{error_line}"
puts
ohai "Environment"
dump_config
puts
ohai "Build Flags"
dump_build_env e.env
onoe e
puts PLEASE_REPORT_BUG
# this feature can be slow (depends on network conditions and if github is up)
# so ideally we'd show feedback, eg. "checking for existing issues..." and
# then replace that string with the following when the github api returns
issues = issues_for_formula(formula_name)
puts "These existing issues may help you:", *issues unless issues.empty?
if e.was_running_configure?
puts "It looks like an autotools configure failed."
puts "Consider re-running the install with '-vd' to keep 'config.log' around:"
puts " brew install -vd #{formula_name}"
puts "Gist 'config.log' and any error output when reporting an issue."
puts "Remember to include your config information: brew --config"
end
puts
puts "Also try:"
puts " `brew doctor` to check your setup for common problems."
puts " `brew missing` to check installed packages for missing deps."
exit 1
rescue RuntimeError, SystemCallError => e
onoe e
puts e.backtrace if ARGV.debug?
exit 1
rescue Exception => e
onoe e
puts PLEASE_REPORT_BUG
puts e.backtrace
exit 1
end
Jump to Line
Something went wrong with that request. Please try again.