aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'Library/Homebrew/cmd')
-rw-r--r--Library/Homebrew/cmd/--cache.rb9
-rw-r--r--Library/Homebrew/cmd/--cellar.rb9
-rw-r--r--Library/Homebrew/cmd/--config.rb66
-rw-r--r--Library/Homebrew/cmd/--env.rb32
-rw-r--r--Library/Homebrew/cmd/--prefix.rb9
-rw-r--r--Library/Homebrew/cmd/--repository.rb5
-rw-r--r--Library/Homebrew/cmd/cat.rb10
-rw-r--r--Library/Homebrew/cmd/cleanup.rb42
-rw-r--r--Library/Homebrew/cmd/create.rb153
-rw-r--r--Library/Homebrew/cmd/deps.rb14
-rw-r--r--Library/Homebrew/cmd/diy.rb34
-rw-r--r--Library/Homebrew/cmd/doctor.rb633
-rw-r--r--Library/Homebrew/cmd/edit.rb26
-rw-r--r--Library/Homebrew/cmd/home.rb9
-rw-r--r--Library/Homebrew/cmd/info.rb92
-rw-r--r--Library/Homebrew/cmd/install.rb87
-rw-r--r--Library/Homebrew/cmd/link.rb8
-rw-r--r--Library/Homebrew/cmd/list.rb88
-rw-r--r--Library/Homebrew/cmd/log.rb10
-rw-r--r--Library/Homebrew/cmd/outdated.rb28
-rw-r--r--Library/Homebrew/cmd/prune.rb31
-rw-r--r--Library/Homebrew/cmd/search.rb42
-rw-r--r--Library/Homebrew/cmd/uninstall.rb31
-rw-r--r--Library/Homebrew/cmd/unlink.rb8
-rw-r--r--Library/Homebrew/cmd/update.rb159
-rw-r--r--Library/Homebrew/cmd/uses.rb25
26 files changed, 1660 insertions, 0 deletions
diff --git a/Library/Homebrew/cmd/--cache.rb b/Library/Homebrew/cmd/--cache.rb
new file mode 100644
index 000000000..f0a5b22f2
--- /dev/null
+++ b/Library/Homebrew/cmd/--cache.rb
@@ -0,0 +1,9 @@
+module Homebrew extend self
+ def __cache
+ if ARGV.named.empty?
+ puts HOMEBREW_CACHE
+ else
+ puts ARGV.formulae.map{ |f| f.cached_download }
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/--cellar.rb b/Library/Homebrew/cmd/--cellar.rb
new file mode 100644
index 000000000..c7e140dc5
--- /dev/null
+++ b/Library/Homebrew/cmd/--cellar.rb
@@ -0,0 +1,9 @@
+module Homebrew extend self
+ def __cellar
+ if ARGV.named.empty?
+ puts HOMEBREW_CELLAR
+ else
+ puts ARGV.formulae.map{ |f| HOMEBREW_CELLAR/f }
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/--config.rb b/Library/Homebrew/cmd/--config.rb
new file mode 100644
index 000000000..7a70df007
--- /dev/null
+++ b/Library/Homebrew/cmd/--config.rb
@@ -0,0 +1,66 @@
+require 'hardware'
+
+module Homebrew extend self
+ def __config
+ puts config_s
+ end
+
+ def llvm
+ @llvm ||= MacOS.llvm_build_version
+ end
+
+ def gcc_42
+ @gcc_42 ||= MacOS.gcc_42_build_version
+ end
+
+ def gcc_40
+ @gcc_40 ||= MacOS.gcc_40_build_version
+ end
+
+ def xcode_version
+ `xcodebuild -version 2>&1` =~ /Xcode (\d(\.\d)*)/
+ $1
+ end
+
+ def llvm_recommendation
+ "(#{RECOMMENDED_LLVM} or newer recommended)" if llvm and llvm < RECOMMENDED_LLVM
+ end
+
+ def gcc_42_recommendation
+ "(#{RECOMMENDED_GCC_42} or newer recommended)" if gcc_42 and gcc_42 < RECOMMENDED_GCC_42
+ end
+
+ def gcc_40_recommendation
+ "(#{RECOMMENDED_GCC_40} or newer recommended)" if gcc_40.nil? and gcc_40 < RECOMMENDED_GCC_40
+ end
+
+ def sha
+ sha = `cd #{HOMEBREW_REPOSITORY} && git rev-parse --verify HEAD 2> /dev/null`.chomp
+ if sha.empty? then "(none)" else sha end
+ end
+
+ def system_ruby
+ Pathname.new('/usr/bin/ruby').realpath.to_s
+ end
+
+ def config_s; <<-EOS.undent
+ HOMEBREW_VERSION: #{HOMEBREW_VERSION}
+ HEAD: #{sha}
+ HOMEBREW_PREFIX: #{HOMEBREW_PREFIX}
+ HOMEBREW_CELLAR: #{HOMEBREW_CELLAR}
+ HOMEBREW_REPOSITORY: #{HOMEBREW_REPOSITORY}
+ HOMEBREW_LIBRARY_PATH: #{HOMEBREW_LIBRARY_PATH}
+ Hardware: #{Hardware.cores_as_words}-core #{Hardware.bits}-bit #{Hardware.intel_family}
+ OS X: #{MACOS_FULL_VERSION}
+ Kernel Architecture: #{`uname -m`.chomp}
+ Ruby: #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}
+ /usr/bin/ruby => #{system_ruby}
+ Xcode: #{xcode_version}
+ GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"} #{gcc_40_recommendation}
+ GCC-4.2: #{gcc_42 ? "build #{gcc_42}" : "N/A"} #{gcc_42_recommendation}
+ LLVM: #{llvm ? "build #{llvm}" : "N/A" } #{llvm_recommendation}
+ MacPorts or Fink? #{macports_or_fink_installed?}
+ X11 installed? #{x11_installed?}
+ EOS
+ end
+end
diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb
new file mode 100644
index 000000000..07623171d
--- /dev/null
+++ b/Library/Homebrew/cmd/--env.rb
@@ -0,0 +1,32 @@
+require 'extend/ENV'
+require 'hardware'
+
+module Homebrew extend self
+ def __env
+ ENV.extend(HomebrewEnvExtension)
+ ENV.setup_build_environment
+ dump_build_env ENV
+ end
+
+ def dump_build_env env
+ puts %["--use-llvm" was specified] if ARGV.include? '--use-llvm'
+
+ %w[ CC CXX LD ].each do |k|
+ value = env[k]
+ if value
+ results = value
+ if File.exists? value and File.symlink? value
+ target = Pathname.new(value)
+ results += " => #{target.realpath}"
+ end
+ puts "#{k}: #{results}"
+ end
+ end
+
+ %w[ CFLAGS CXXFLAGS CPPFLAGS LDFLAGS MACOSX_DEPLOYMENT_TARGET MAKEFLAGS PKG_CONFIG_PATH
+ HOMEBREW_DEBUG HOMEBREW_VERBOSE HOMEBREW_USE_LLVM HOMEBREW_SVN ].each do |k|
+ value = env[k]
+ puts "#{k}: #{value}" if value
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/--prefix.rb b/Library/Homebrew/cmd/--prefix.rb
new file mode 100644
index 000000000..9a15203a9
--- /dev/null
+++ b/Library/Homebrew/cmd/--prefix.rb
@@ -0,0 +1,9 @@
+module Homebrew extend self
+ def __prefix
+ if ARGV.named.empty?
+ puts HOMEBREW_PREFIX
+ else
+ puts ARGV.formulae.map{ |f| f.prefix }
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/--repository.rb b/Library/Homebrew/cmd/--repository.rb
new file mode 100644
index 000000000..f14ab9901
--- /dev/null
+++ b/Library/Homebrew/cmd/--repository.rb
@@ -0,0 +1,5 @@
+module Homebrew extend self
+ def __repository
+ puts HOMEBREW_REPOSITORY
+ end
+end
diff --git a/Library/Homebrew/cmd/cat.rb b/Library/Homebrew/cmd/cat.rb
new file mode 100644
index 000000000..a87eba61e
--- /dev/null
+++ b/Library/Homebrew/cmd/cat.rb
@@ -0,0 +1,10 @@
+module Homebrew extend self
+ def cat
+ # do not "fix" this to support multiple arguments, the output would be
+ # unparsable, if the user wants to cat multiple formula they can call
+ # brew cat multiple times.
+
+ cd HOMEBREW_REPOSITORY
+ exec "cat", ARGV.formulae.first.path, *ARGV.options_only
+ end
+end
diff --git a/Library/Homebrew/cmd/cleanup.rb b/Library/Homebrew/cmd/cleanup.rb
new file mode 100644
index 000000000..f5e4637ec
--- /dev/null
+++ b/Library/Homebrew/cmd/cleanup.rb
@@ -0,0 +1,42 @@
+require 'formula'
+require 'cmd/prune'
+
+module Homebrew extend self
+ def cleanup
+ if ARGV.named.empty?
+ HOMEBREW_CELLAR.children.each do |rack|
+ begin
+ cleanup_formula rack.basename.to_s if rack.directory?
+ rescue FormulaUnavailableError => e
+ opoo "Formula not found for #{e.name}"
+ end
+ end
+ # seems like a good time to do some additional cleanup
+ Homebrew.prune
+ else
+ ARGV.formulae.each do |f|
+ cleanup_formula f
+ end
+ end
+ end
+
+ def cleanup_formula f
+ f = Formula.factory f
+ rack = f.prefix.parent
+
+ if f.installed? and rack.directory?
+ rack.children.each do |keg|
+ if f.installed_prefix != keg
+ print "Uninstalling #{keg}..."
+ rm_rf keg
+ puts
+ end
+ end
+ elsif rack.children.length > 1
+ # If the cellar only has one version installed, don't complain
+ # that we can't tell which one to keep.
+ opoo "Skipping #{name}: most recent version #{f.version} not installed"
+ end
+ end
+
+end
diff --git a/Library/Homebrew/cmd/create.rb b/Library/Homebrew/cmd/create.rb
new file mode 100644
index 000000000..e21c9a524
--- /dev/null
+++ b/Library/Homebrew/cmd/create.rb
@@ -0,0 +1,153 @@
+require 'formula'
+
+module Homebrew extend self
+ def 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
+ paths = ARGV.named.map do |url|
+ fc = FormulaCreator.new
+ fc.url = url
+ fc.mode = if ARGV.include? '--cmake'
+ :cmake
+ elsif ARGV.include? '--autotools'
+ :autotools
+ end
+
+ if fc.name.to_s.strip.empty?
+ path = Pathname.new url
+ print "Formula name [#{path.stem}]: "
+ fc.name = __gets || path.stem
+ end
+
+ unless ARGV.force?
+ if msg = blacklisted?(fc.name)
+ raise "#{msg}\n\nIf you really want to make this formula use --force."
+ end
+
+ if Formula.aliases.include? fc.name
+ realname = Formula.caniconical_name fc.name
+ raise <<-EOS.undent
+ The formula #{realname} is already aliased to #{fc.name}
+ Please check that you are not creating a duplicate.
+ To force creation use --force.
+ EOS
+ end
+ end
+ fc.generate
+ fc.path
+ end
+ exec_editor *paths
+ end
+ end
+
+ def __gets
+ gots = $stdin.gets.chomp
+ if gots.empty? then nil else gots end
+ end
+
+ def blacklisted? name
+ case name.downcase
+ when 'vim', 'screen' then <<-EOS.undent
+ #{name} is blacklisted for creation
+ Apple distributes this program with OS X.
+ EOS
+ when 'libarchive', 'libpcap' then <<-EOS.undent
+ #{name} is blacklisted for creation
+ Apple distributes this library with OS X, you can find it in /usr/lib.
+ EOS
+ when 'libxml', 'libxlst', 'freetype', 'libpng' then <<-EOS.undent
+ #{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.
+ EOS
+ when /^rubygems?$/
+ "Sorry RubyGems comes with OS X so we don't package it."
+ when 'wxwidgets' then <<-EOS.undent
+ #{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
+ EOS
+ end
+ end
+end
+
+class FormulaCreator
+ attr :url
+ attr :md5
+ attr :name, true
+ attr :path
+ attr :mode, true
+
+ def url= url
+ @url = url
+ path = Pathname.new url
+ /(.*?)[-_.]?#{path.version}/.match path.basename
+ @name = $1
+ @path = Formula.path $1
+ end
+
+ def version
+ Pathname.new(url).version
+ end
+
+ def generate
+ raise "#{path} already exists" if path.exist?
+ raise VersionUndetermined if version.nil?
+
+ require 'digest'
+ require 'erb'
+
+ if version.nil?
+ 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
+
+ unless ARGV.include? "--no-md5" and version
+ strategy = detect_download_strategy url
+ @md5 = strategy.new(url, name, version, nil).fetch.md5 if strategy == CurlDownloadStrategy
+ end
+
+ path.write ERB.new(template, nil, '>').result(binding)
+ end
+
+ def template; <<-EOS.undent
+ 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
+ <% if mode == :cmake %>
+ system "cmake . \#{std_cmake_parameters}"
+ <% elsif mode == :autotools %>
+ system "./configure", "--disable-debug", "--disable-dependency-tracking",
+ "--prefix=\#{prefix}"
+ <% else %>
+ system "./configure", "--disable-debug", "--disable-dependency-tracking",
+ "--prefix=\#{prefix}"
+ # system "cmake . \#{std_cmake_parameters}"
+ <% end %>
+ system "make install"
+ end
+ end
+ EOS
+ end
+end
diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb
new file mode 100644
index 000000000..2e9a723f4
--- /dev/null
+++ b/Library/Homebrew/cmd/deps.rb
@@ -0,0 +1,14 @@
+module Homebrew extend self
+ def deps
+ puts if ARGV.include?('--all')
+ require 'formula'
+ Formula.all.each do |f|
+ "#{f.name}:#{f.deps.join(' ')}"
+ end
+ elsif ARGV.include?("-1") or ARGV.include?("--1")
+ *ARGV.formulae.map{ |f| f.deps or [] }.flatten.uniq.sort
+ else
+ *ARGV.formulae.map{ |f| f.recursive_deps.map{ |f| f.name } }.flatten.uniq.sort
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/diy.rb b/Library/Homebrew/cmd/diy.rb
new file mode 100644
index 000000000..174626afc
--- /dev/null
+++ b/Library/Homebrew/cmd/diy.rb
@@ -0,0 +1,34 @@
+module Homebrew extend self
+ def diy
+ path = Pathname.getwd
+
+ version = if ARGV.include? '--set-version'
+ ARGV.next
+ elsif path.version.to_s.empty?
+ raise "Couldn't determine version, try --set-version"
+ else
+ path.version
+ end
+
+ name = if ARGV.include? '--set-name'
+ ARGV.next
+ else
+ path.basename.to_s =~ /(.*?)-?#{version}/
+ if $1.to_s.empty?
+ path.basename
+ else
+ $1
+ end
+ end
+
+ prefix = HOMEBREW_CELLAR/name/version
+
+ if File.file? 'CMakeLists.txt'
+ puts "-DCMAKE_INSTALL_PREFIX=#{prefix}"
+ elsif File.file? 'Makefile.am'
+ puts "--prefix=#{prefix}"
+ else
+ raise "Couldn't determine build system"
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb
new file mode 100644
index 000000000..bad3a5dc0
--- /dev/null
+++ b/Library/Homebrew/cmd/doctor.rb
@@ -0,0 +1,633 @@
+class Volumes
+ def initialize
+ @volumes = []
+ raw_mounts=`mount`
+ raw_mounts.split("\n").each do |line|
+ case line
+ when /^(.+) on (\S+) \(/
+ @volumes << [$1, $2]
+ end
+ end
+ # Sort volumes by longest path prefix first
+ @volumes.sort! {|a,b| b[1].length <=> a[1].length}
+ end
+
+ def which path
+ @volumes.each_index do |i|
+ vol = @volumes[i]
+ return i if is_prefix?(vol[1], path)
+ end
+
+ return -1
+ end
+end
+
+
+def is_prefix? prefix, longer_string
+ p = prefix.to_s
+ longer_string.to_s[0,p.length] == p
+end
+
+# Installing MacGPG2 interferes with Homebrew in a big way
+# http://sourceforge.net/projects/macgpg2/files/
+def check_for_macgpg2
+ if File.exist? "/Applications/start-gpg-agent.app" or
+ File.exist? "/Library/Receipts/libiconv1.pkg"
+ puts <<-EOS.undent
+ If you have installed MacGPG2 via the package installer, several other
+ checks in this script will turn up problems, such as stray .dylibs in
+ /usr/local and permissions issues with share and man in /usr/local/.
+
+ EOS
+ end
+end
+
+def check_for_stray_dylibs
+ unbrewed_dylibs = Dir['/usr/local/lib/*.dylib'].select { |f| File.file? f and not File.symlink? f }
+
+ # Dylibs which are generally OK should be added to this list,
+ # with a short description of the software they come with.
+ white_list = {
+ "libfuse.2.dylib" => "MacFuse",
+ "libfuse_ino64.2.dylib" => "MacFuse"
+ }
+
+ bad_dylibs = unbrewed_dylibs.reject {|d| white_list.key? File.basename(d) }
+ return if bad_dylibs.empty?
+
+ opoo "Unbrewed dylibs were found in /usr/local/lib"
+ puts <<-EOS.undent
+ You have unbrewed dylibs in /usr/local/lib. If you didn't put them there on purpose,
+ they could cause problems when building Homebrew formulae.
+
+ Unexpected dylibs (delete if they are no longer needed):
+ EOS
+ puts *bad_dylibs.collect { |f| " #{f}" }
+ puts
+end
+
+def check_for_x11
+ unless x11_installed?
+ opoo "X11 not installed."
+ puts <<-EOS.undent
+ You don't have X11 installed as part of your Xcode installation.
+ This isn't required for all formulae, but is expected by some.
+
+ EOS
+ end
+end
+
+def check_for_nonstandard_x11
+ return unless File.exists? '/usr/X11'
+ x11 = Pathname.new('/usr/X11')
+ if x11.symlink?
+ puts <<-EOS.undent
+ "/usr/X11" was found, but it is a symlink to:
+ #{x11.resolved_path}
+
+ Homebrew's X11 support has only be tested with Apple's X11.
+ In particular, "XQuartz" and "XDarwin" are not known to be compatible.
+
+ EOS
+ end
+end
+
+def check_for_other_package_managers
+ if macports_or_fink_installed?
+ puts <<-EOS.undent
+ You have Macports or Fink installed. This can cause trouble.
+ You don't have to uninstall them, but you may like to try temporarily
+ moving them away, eg.
+
+ sudo mv /opt/local ~/macports
+
+ EOS
+ end
+end
+
+def check_gcc_versions
+ gcc_42 = gcc_42_build
+ gcc_40 = gcc_40_build
+
+ if gcc_42 == nil
+ puts <<-EOS.undent
+ We couldn't detect gcc 4.2.x. Some formulae require this compiler.
+
+ EOS
+ elsif gcc_42 < RECOMMENDED_GCC_42
+ puts <<-EOS.undent
+ Your gcc 4.2.x version is older than the recommended version. It may be advisable
+ to upgrade to the latest release of Xcode.
+
+ EOS
+ end
+
+ if gcc_40 == nil
+ puts <<-EOS.undent
+ We couldn't detect gcc 4.0.x. Some formulae require this compiler.
+
+ EOS
+ elsif gcc_40 < RECOMMENDED_GCC_40
+ puts <<-EOS.undent
+ Your gcc 4.0.x version is older than the recommended version. It may be advisable
+ to upgrade to the latest release of Xcode.
+
+ EOS
+ end
+end
+
+def check_cc_symlink
+ which_cc = Pathname.new('/usr/bin/cc').realpath.basename.to_s
+ if which_cc == "llvm-gcc-4.2"
+ puts <<-EOS.undent
+ You changed your cc to symlink to llvm.
+ This bypasses LLVM checks, and some formulae may mysteriously fail to work.
+ You may want to change /usr/bin/cc to point back at gcc.
+
+ To force Homebrew to use LLVM, you can set the "HOMEBREW_LLVM" environmental
+ variable, or pass "--use-llvm" to "brew install".
+
+ EOS
+ end
+end
+
+def __check_subdir_access base
+ target = HOMEBREW_PREFIX+base
+ return unless target.exist?
+
+ cant_read = []
+
+ target.find do |d|
+ next unless d.directory?
+ cant_read << d unless d.writable?
+ end
+
+ cant_read.sort!
+ if cant_read.length > 0
+ puts <<-EOS.undent
+ Some folders in #{target} aren't writable.
+ This can happen if you "sudo make install" software that isn't managed
+ by Homebrew. If a brew tries to add locale information to one of these
+ folders, then the install will fail during the link step.
+ You should probably `chown` them:
+
+ EOS
+ puts *cant_read.collect { |f| " #{f}" }
+ puts
+ end
+end
+
+def check_access_share_locale
+ __check_subdir_access 'share/locale'
+end
+
+def check_access_share_man
+ __check_subdir_access 'share/man'
+end
+
+def check_access_pkgconfig
+ # If PREFIX/lib/pkgconfig already exists, "sudo make install" of
+ # non-brew installed software may cause installation failures.
+ pkgconfig = HOMEBREW_PREFIX+'lib/pkgconfig'
+ return unless pkgconfig.exist?
+
+ unless pkgconfig.writable?
+ puts <<-EOS.undent
+ #{pkgconfig} isn't writable.
+ This can happen if you "sudo make install" software that isn't managed
+ by Homebrew. If a brew tries to write a .pc file to this folder, the
+ install will fail during the link step.
+
+ You should probably `chown` #{pkgconfig}
+
+ EOS
+ end
+end
+
+def check_access_include
+ # Installing MySQL manually (for instance) can chown include to root.
+ include_folder = HOMEBREW_PREFIX+'include'
+ return unless include_folder.exist?
+
+ unless include_folder.writable?
+ puts <<-EOS.undent
+ #{include_folder} isn't writable.
+ This can happen if you "sudo make install" software that isn't managed
+ by Homebrew. If a brew tries to write a header file to this folder, the
+ install will fail during the link step.
+
+ You should probably `chown` #{include_folder}
+
+ EOS
+ end
+end
+
+def check_access_etc
+ etc_folder = HOMEBREW_PREFIX+'etc'
+ return unless etc_folder.exist?
+
+ unless etc_folder.writable?
+ puts <<-EOS.undent
+ #{etc_folder} isn't writable.
+ This can happen if you "sudo make install" software that isn't managed
+ by Homebrew. If a brew tries to write a file to this folder, the install
+ will fail during the link step.
+
+ You should probably `chown` #{etc_folder}
+
+ EOS
+ end
+end
+
+def check_usr_bin_ruby
+ if /^1\.9/.match RUBY_VERSION
+ puts <<-EOS.undent
+ Ruby version #{RUBY_VERSION} is unsupported.
+ Homebrew is developed and tested on Ruby 1.8.x, and may not work correctly
+ on Ruby 1.9.x. Patches are accepted as long as they don't break on 1.8.x.
+
+ EOS
+ end
+end
+
+def check_homebrew_prefix
+ unless HOMEBREW_PREFIX.to_s == '/usr/local'
+ puts <<-EOS.undent
+ You can install Homebrew anywhere you want, but some brews may only work
+ correctly if you install to /usr/local.
+
+ EOS
+ end
+end
+
+def check_user_path
+ seen_prefix_bin = false
+ seen_prefix_sbin = false
+ seen_usr_bin = false
+
+ paths = ENV['PATH'].split(':').collect{|p| File.expand_path p}
+
+ paths.each do |p|
+ if p == '/usr/bin'
+ seen_usr_bin = true
+ unless seen_prefix_bin
+ puts <<-EOS.undent
+ /usr/bin is in your PATH before Homebrew's bin. This means that system-
+ provided programs will be used before Homebrew-provided ones. This is an
+ issue if you install, for instance, Python.
+
+ Consider editing your .bashrc to put:
+ #{HOMEBREW_PREFIX}/bin
+ ahead of /usr/bin in your $PATH.
+
+ EOS
+ end
+ end
+
+ seen_prefix_bin = true if p == "#{HOMEBREW_PREFIX}/bin"
+ seen_prefix_sbin = true if p == "#{HOMEBREW_PREFIX}/sbin"
+ end
+
+ unless seen_prefix_bin
+ puts <<-EOS.undent
+ Homebrew's bin was not found in your path. Some brews depend
+ on other brews that install tools to bin.
+
+ You should edit your .bashrc to add:
+ #{HOMEBREW_PREFIX}/bin
+ to $PATH.
+
+ EOS
+ end
+
+ unless seen_prefix_sbin
+ puts <<-EOS.undent
+ Some brews install binaries to sbin instead of bin, but Homebrew's
+ sbin was not found in your path.
+
+ Consider editing your .bashrc to add:
+ #{HOMEBREW_PREFIX}/sbin
+ to $PATH.
+
+ EOS
+ end
+end
+
+def check_which_pkg_config
+ binary = `/usr/bin/which pkg-config`.chomp
+ return if binary.empty?
+
+ unless binary == "#{HOMEBREW_PREFIX}/bin/pkg-config"
+ puts <<-EOS.undent
+ You have a non-brew 'pkg-config' in your PATH:
+ #{binary}
+
+ `./configure` may have problems finding brew-installed packages using
+ this other pkg-config.
+
+ EOS
+ end
+end
+
+def check_pkg_config_paths
+ binary = `/usr/bin/which pkg-config`.chomp
+ return if binary.empty?
+
+ # Use the debug output to determine which paths are searched
+ pkg_config_paths = []
+
+ debug_output = `pkg-config --debug 2>&1`
+ debug_output.split("\n").each do |line|
+ line =~ /Scanning directory '(.*)'/
+ pkg_config_paths << $1 if $1
+ end
+
+ # Check that all expected paths are being searched
+ unless pkg_config_paths.include? "/usr/X11/lib/pkgconfig"
+ puts <<-EOS.undent
+ Your pkg-config is not checking "/usr/X11/lib/pkgconfig" for packages.
+ Earlier versions of the pkg-config formula did not add this path
+ to the search path, which means that other formula may not be able
+ to find certain dependencies.
+
+ To resolve this issue, re-brew pkg-config with:
+ brew rm pkg-config && brew install pkg-config
+
+ EOS
+ end
+end
+
+def check_for_gettext
+ if %w[lib/libgettextlib.dylib
+ lib/libintl.dylib
+ include/libintl.h ].any? { |f| File.exist? "#{HOMEBREW_PREFIX}/#{f}" }
+ puts <<-EOS.undent
+ gettext was detected in your PREFIX.
+
+ The gettext provided by Homebrew is "keg-only", meaning it does not
+ get linked into your PREFIX by default.
+
+ If you `brew link gettext` then a large number of brews that don't
+ otherwise have a `depends_on 'gettext'` will pick up gettext anyway
+ during the `./configure` step.
+
+ If you have a non-Homebrew provided gettext, other problems will happen
+ especially if it wasn't compiled with the proper architectures.
+
+ EOS
+ end
+end
+
+def check_for_iconv
+ if %w[lib/libiconv.dylib
+ include/iconv.h ].any? { |f| File.exist? "#{HOMEBREW_PREFIX}/#{f}" }
+ puts <<-EOS.undent
+ libiconv was detected in your PREFIX.
+
+ Homebrew doesn't provide a libiconv formula, and expects to link against
+ the system version in /usr/lib.
+
+ If you have a non-Homebrew provided libiconv, many formulae will fail
+ to compile or link, especially if it wasn't compiled with the proper
+ architectures.
+
+ EOS
+ end
+end
+
+def check_for_config_scripts
+ real_cellar = HOMEBREW_CELLAR.realpath
+
+ config_scripts = []
+
+ paths = ENV['PATH'].split(':').collect{|p| File.expand_path p}
+ paths.each do |p|
+ next if ['/usr/bin', '/usr/sbin', '/usr/X11/bin', "#{HOMEBREW_PREFIX}/bin", "#{HOMEBREW_PREFIX}/sbin"].include? p
+ next if p =~ %r[^(#{real_cellar.to_s}|#{HOMEBREW_CELLAR.to_s})]
+
+ configs = Dir["#{p}/*-config"]
+ # puts "#{p}\n #{configs * ' '}" unless configs.empty?
+ config_scripts << [p, configs.collect {|p| File.basename(p)}] unless configs.empty?
+ end
+
+ unless config_scripts.empty?
+ puts <<-EOS.undent
+ Some "config" scripts were found in your path, but not in system or Homebrew folders.
+
+ `./configure` scripts often look for *-config scripts to determine if software packages
+ are installed, and what additional flags to use when compiling and linking.
+
+ Having additional scripts in your path can confuse software installed via Homebrew if
+ the config script overrides a system or Homebrew provided script of the same name.
+
+ EOS
+
+ config_scripts.each do |pair|
+ puts pair[0]
+ puts " " + pair[1] * " "
+ end
+ puts
+ end
+end
+
+def check_for_dyld_vars
+ if ENV['DYLD_LIBRARY_PATH']
+ puts <<-EOS.undent
+ Setting DYLD_LIBARY_PATH can break dynamic linking.
+ You should probably unset it.
+
+ EOS
+ end
+end
+
+def check_for_symlinked_cellar
+ if HOMEBREW_CELLAR.symlink?
+ puts <<-EOS.undent
+ Symlinked Cellars can cause problems.
+ Your Homebrew Cellar is a symlink: #{HOMEBREW_CELLAR}
+ which resolves to: #{HOMEBREW_CELLAR.realpath}
+
+ The recommended Homebrew installations are either:
+ (A) Have Cellar be a real folder inside of your HOMEBREW_PREFIX
+ (B) Symlink "bin/brew" into your prefix, but don't symlink "Cellar".
+
+ Older installations of Homebrew may have created a symlinked Cellar, but this can
+ cause problems when two formula install to locations that are mapped on top of each
+ other during the linking step.
+
+ EOS
+ end
+end
+
+def check_for_multiple_volumes
+ volumes = Volumes.new
+
+ # Find the volumes for the TMP folder & HOMEBREW_CELLAR
+ real_cellar = HOMEBREW_CELLAR.realpath
+
+ tmp_prefix = ENV['HOMEBREW_TEMP'] || '/tmp'
+ tmp=Pathname.new `/usr/bin/mktemp -d #{tmp_prefix}/homebrew-brew-doctor-XXXX`.strip
+ real_temp = tmp.realpath.parent
+
+ where_cellar = volumes.which real_cellar
+ where_temp = volumes.which real_temp
+
+ unless where_cellar == where_temp
+ puts <<-EOS.undent
+ Your Cellar & TEMP folders are on different volumes.
+
+ OS X won't move relative symlinks across volumes unless the target file
+ already exists.
+
+ Brews known to be affected by this are Git and Narwhal.
+
+ You should set the "HOMEBREW_TEMP" environmental variable to a suitable
+ folder on the same volume as your Cellar.
+
+ EOS
+ end
+end
+
+def check_for_git
+ git = `/usr/bin/which git`.chomp
+ if git.empty?
+ puts <<-EOS.undent
+ "Git" was not found in your path.
+
+ Homebrew uses Git for several internal functions, and some formulae
+ use Git checkouts instead of stable tarballs.
+
+ You may want to do:
+ brew install git
+
+ EOS
+ end
+end
+
+def check_for_autoconf
+ which_autoconf = `/usr/bin/which autoconf`.chomp
+ unless (which_autoconf == '/usr/bin/autoconf' or which_autoconf == '/Developer/usr/bin/autoconf')
+ puts <<-EOS.undent
+ You have an "autoconf" in your path blocking the system version at:
+ #{which_autoconf}
+
+ Custom autoconf in general and autoconf 2.66 in particular has issues
+ and will cause some Homebrew formulae to fail.
+
+ EOS
+ end
+end
+
+def __check_linked_brew f
+ links_found = []
+
+ Pathname.new(f.prefix).find do |src|
+ dst=HOMEBREW_PREFIX+src.relative_path_from(f.prefix)
+ next unless dst.symlink?
+
+ dst_points_to = dst.realpath()
+ next unless dst_points_to.to_s == src.to_s
+
+ if src.directory?
+ Find.prune
+ else
+ links_found << dst
+ end
+ end
+
+ return links_found
+end
+
+def check_for_linked_kegonly_brews
+ require 'formula'
+
+ warnings = Hash.new
+
+ Formula.all.each do |f|
+ next unless f.keg_only? and f.installed?
+ links = __check_linked_brew f
+ warnings[f.name] = links unless links.empty?
+ end
+
+ unless warnings.empty?
+ puts <<-EOS.undent
+ Some keg-only formula are linked into the Cellar.
+
+ Linking a keg-only formula, such as gettext, into the cellar with
+ `brew link f` will cause other formulae to detect them during the
+ `./configure` step. This may cause problems when compiling those
+ other formulae.
+
+ Binaries provided by keg-only formulae may override system binaries
+ with other strange results.
+
+ You may wish to `brew unlink` these brews:
+ EOS
+
+ puts *warnings.keys.collect { |f| " #{f}" }
+ end
+end
+
+def check_for_other_vars
+ target_var = ENV['MACOSX_DEPLOYMENT_TARGET']
+ return if target_var.nil? or target_var.empty?
+
+ unless target_var == MACOS_VERSION.to_s
+ puts <<-EOS.undent
+ $MACOSX_DEPLOYMENT_TARGET was set to #{target_var}
+ This is used by Fink, but having it set to a value different from the
+ current system version (#{MACOS_VERSION}) can cause problems, compiling
+ Git for instance, and should probably be removed.
+
+ EOS
+ end
+end
+
+module Homebrew extend self
+def doctor
+ read, write = IO.pipe
+
+ if fork == nil
+ read.close
+ $stdout.reopen write
+
+ check_usr_bin_ruby
+ check_homebrew_prefix
+ check_for_macgpg2
+ check_for_stray_dylibs
+ check_gcc_versions
+ check_cc_symlink
+ check_for_other_package_managers
+ check_for_x11
+ check_for_nonstandard_x11
+ check_access_share_locale
+ check_access_share_man
+ check_access_include
+ check_access_etc
+ check_user_path
+ check_which_pkg_config
+ check_pkg_config_paths
+ check_access_pkgconfig
+ check_for_gettext
+ check_for_config_scripts
+ check_for_dyld_vars
+ check_for_other_vars
+ check_for_symlinked_cellar
+ check_for_multiple_volumes
+ check_for_git
+ check_for_autoconf
+ check_for_linked_kegonly_brews
+
+ exit! 0
+ else
+ write.close
+
+ unless (out = read.read).chomp.empty?
+ puts out
+ else
+ puts "Your OS X is ripe for brewing."
+ puts "Any troubles you may be experiencing are likely purely psychosomatic."
+ end
+ end
+end
+end
diff --git a/Library/Homebrew/cmd/edit.rb b/Library/Homebrew/cmd/edit.rb
new file mode 100644
index 000000000..6ab91dccf
--- /dev/null
+++ b/Library/Homebrew/cmd/edit.rb
@@ -0,0 +1,26 @@
+require 'formula'
+
+module Homebrew extend self
+ def 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', HOMEBREW_REPOSITORY/"bin/brew",
+ HOMEBREW_REPOSITORY/'README.md',
+ HOMEBREW_REPOSITORY/".gitignore",
+ *Dir[HOMEBREW_REPOSITORY/"Library/*"]
+ else
+ # Don't use ARGV.formulae as that will throw if the file doesn't parse
+ paths = ARGV.named.map do |name|
+ HOMEBREW_REPOSITORY/"Library/Formula/#{Formula.caniconical_name name}.rb"
+ end
+ unless ARGV.force?
+ paths.each do |path|
+ raise FormulaUnavailableError, path.basename('.rb').to_s unless path.file?
+ end
+ end
+ exec_editor *paths
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/home.rb b/Library/Homebrew/cmd/home.rb
new file mode 100644
index 000000000..a91607988
--- /dev/null
+++ b/Library/Homebrew/cmd/home.rb
@@ -0,0 +1,9 @@
+module Homebrew extend self
+ def home
+ if ARGV.named.empty?
+ exec "open", HOMEBREW_WWW
+ else
+ exec "open", *ARGV.formulae.map{ |f| f.homepage }
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb
new file mode 100644
index 000000000..7f9767e07
--- /dev/null
+++ b/Library/Homebrew/cmd/info.rb
@@ -0,0 +1,92 @@
+require 'formula'
+
+module Homebrew extend self
+ def info
+ if ARGV.named.empty?
+ if ARGV.include? "--all"
+ Formula.each do |f|
+ info_formula f
+ puts '---'
+ end
+ else
+ puts "#{HOMEBREW_CELLAR.children.length} kegs, #{HOMEBREW_CELLAR.abv}"
+ end
+ elsif valid_url ARGV[0]
+ 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_formula f }
+ end
+ end
+
+ def github_info name
+ formula_name = Formula.path(name).basename
+ user = 'mxcl'
+ branch = 'master'
+
+ if system "/usr/bin/which -s git"
+ 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
+ end
+
+ "http://github.com/#{user}/homebrew/commits/#{branch}/Library/Formula/#{formula_name}"
+ end
+
+ def info_formula f
+ exec 'open', github_info(f.name) if ARGV.flag? '--github'
+
+ puts "#{f.name} #{f.version}"
+ puts f.homepage
+
+ puts "Depends on: #{f.deps*', '}" unless f.deps.empty?
+
+ rack = f.prefix.parent
+ if rack.directory?
+ kegs = rack.children
+ kegs.each do |keg|
+ next if keg.basename.to_s == '.DS_Store'
+ print "#{keg} (#{keg.abv})"
+ print " *" if f.installed_prefix == keg and kegs.length > 1
+ puts
+ end
+ else
+ puts "Not installed"
+ end
+
+ if f.caveats
+ puts
+ puts f.caveats
+ puts
+ end
+
+ history = github_info f.name
+ puts history if history
+
+ 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
+
+ private
+
+ def valid_url u
+ u[0..6] == 'http://' or u[0..7] == 'https://' or u[0..5] == 'ftp://'
+ end
+
+end
diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb
new file mode 100644
index 000000000..ed5fb6777
--- /dev/null
+++ b/Library/Homebrew/cmd/install.rb
@@ -0,0 +1,87 @@
+require 'formula_installer'
+require 'hardware'
+
+module Homebrew extend self
+ def install
+ brew_install
+ end
+end
+
+def brew_install
+ ############################################################ 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
+ opoo "You should upgrade to Xcode 3.2.3" if llvm_build < RECOMMENDED_LLVM
+ 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?
+ 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."
+ 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
+
+def check_for_blacklisted_formula names
+ return if ARGV.force?
+
+ names.each do |name|
+ case name
+ 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.)
+
+ We recommend using a MacTeX distribution:
+ http://www.tug.org/mactex/
+ EOS
+
+ when 'mercurial', 'hg' then abort <<-EOS.undent
+ Mercurial can be install thusly:
+ brew install pip && pip install mercurial
+ EOS
+
+ when 'npm' then abort <<-EOS.undent
+ npm can be installed thusly by following the instructions at
+ http://npmjs.org/
+
+ To do it in one line, use this command:
+ curl http://npmjs.org/install.sh | sudo sh
+ EOS
+
+ when 'setuptools' then abort <<-EOS.undent
+ When working with a Homebrew-built Python, distribute is preferred
+ over setuptools, and can be used as the prerequisite for pip.
+
+ Install distribute using:
+ brew install distribute
+ EOS
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb
new file mode 100644
index 000000000..5565309e2
--- /dev/null
+++ b/Library/Homebrew/cmd/link.rb
@@ -0,0 +1,8 @@
+module Homebrew extend self
+ def link
+ ARGV.kegs.each do |keg|
+ print "Linking #{keg}... "
+ puts "#{keg.link} links created"
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/list.rb b/Library/Homebrew/cmd/list.rb
new file mode 100644
index 000000000..8e35530fd
--- /dev/null
+++ b/Library/Homebrew/cmd/list.rb
@@ -0,0 +1,88 @@
+module Homebrew extend self
+ def list
+ if ARGV.flag? '--unbrewed'
+ dirs = HOMEBREW_PREFIX.children.select{ |pn| pn.directory? }.map{ |pn| pn.basename.to_s }
+ dirs -= %w[Library Cellar .git]
+ cd HOMEBREW_PREFIX
+ exec 'find', *dirs + %w[-type f ( ! -iname .ds_store ! -iname brew )]
+ elsif ARGV.flag? '--versions'
+ if ARGV.named.empty?
+ HOMEBREW_CELLAR.children.select{ |pn| pn.directory? }
+ else
+ ARGV.named.map{ |n| HOMEBREW_CELLAR/n }.select{ |pn| pn.exist? }
+ end.each do |d|
+ versions = d.children.select{ |pn| pn.directory? }.map{ |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
+ end
+end
+
+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
+ if pn.directory?
+ if pn.symlink?
+ puts "#{pn} -> #{pn.readlink}"
+ else
+ print_dir pn
+ end
+ elsif not (FORMULA_META_FILES + ['.DS_Store']).include? pn.basename.to_s
+ puts pn
+ end
+ end
+ end
+ end
+
+ 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
+ remaining_root_files << pn unless pn.basename.to_s == '.DS_Store'
+ 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
+ puts files
+ else
+ puts "#{root}/ (#{files.length} #{other}files)"
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/log.rb b/Library/Homebrew/cmd/log.rb
new file mode 100644
index 000000000..ceb0c8e02
--- /dev/null
+++ b/Library/Homebrew/cmd/log.rb
@@ -0,0 +1,10 @@
+module Homebrew extend self
+ def log
+ cd HOMEBREW_REPOSITORY
+ if ARGV.named.empty?
+ exec "git", "log", *ARGV.options_only
+ else
+ exec "git", "log", *ARGV.formulae.map(&:path), *ARGV.options_only
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/outdated.rb b/Library/Homebrew/cmd/outdated.rb
new file mode 100644
index 000000000..37fba0f99
--- /dev/null
+++ b/Library/Homebrew/cmd/outdated.rb
@@ -0,0 +1,28 @@
+require 'formula'
+
+module Homebrew extend self
+ def 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
+ end
+
+ def outdated_brews
+ HOMEBREW_CELLAR.subdirs.map do |rack|
+ # Skip kegs with no versions installed
+ next unless rack.subdirs
+
+ # Skip HEAD formulae, consider them "evergreen"
+ next if rack.subdirs.map{ |keg| keg.basename.to_s }.include? "HEAD"
+
+ name = rack.basename.to_s
+ f = Formula.factory name rescue nil
+ [rack, name, f.version] if f and not f.installed?
+ end.compact
+ end
+end \ No newline at end of file
diff --git a/Library/Homebrew/cmd/prune.rb b/Library/Homebrew/cmd/prune.rb
new file mode 100644
index 000000000..ba4bbc8e5
--- /dev/null
+++ b/Library/Homebrew/cmd/prune.rb
@@ -0,0 +1,31 @@
+module Homebrew extend self
+ # $n and $d are used by the ObserverPathnameExtension to keep track of
+ # certain filesystem actions.
+
+ def prune
+ $n = 0
+ $d = 0
+ dirs = []
+
+ %w[bin sbin etc lib include share].map{ |d| HOMEBREW_PREFIX/d }.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
+ print "Pruned #{$n} symbolic links "
+ print "and #{$d} directories " if $d > 0
+ puts "from #{HOMEBREW_PREFIX}"
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb
new file mode 100644
index 000000000..b6a0e971d
--- /dev/null
+++ b/Library/Homebrew/cmd/search.rb
@@ -0,0 +1,42 @@
+require "formula"
+
+module Homebrew extend self
+ def search
+ 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
+
+ require 'cmd/install' # for blacklisted? function
+ blacklisted? ARGV.named do |msg, _|
+ abort msg
+ end unless ARGV.force?
+
+ puts_columns search_brews(ARGV.first)
+ end
+
+ def search_brews text
+ if text.to_s.empty?
+ Formula.names
+ else
+ rx = if text =~ %r{^/(.*)/$}
+ Regexp.new($1)
+ else
+ /.*#{Regexp.escape text}.*/i
+ end
+
+ aliases = Formula.aliases
+ results = (Formula.names+aliases).grep rx
+
+ # Filter out aliases when the full name was also found
+ results.reject do |alias_name|
+ if aliases.include? alias_name
+ resolved_name = (HOMEBREW_REPOSITORY/"Library/Aliases"/alias_name).readlink.basename('.rb').to_s
+ results.include? resolved_name
+ end
+ end
+ end
+ end
+
+end
diff --git a/Library/Homebrew/cmd/uninstall.rb b/Library/Homebrew/cmd/uninstall.rb
new file mode 100644
index 000000000..34de88130
--- /dev/null
+++ b/Library/Homebrew/cmd/uninstall.rb
@@ -0,0 +1,31 @@
+require 'keg'
+
+module Homebrew extend self
+ def uninstall
+ unless ARGV.force?
+ ARGV.kegs.each do |keg|
+ puts "Uninstalling #{keg}..."
+ keg.unlink
+ keg.uninstall
+ end
+ else
+ ARGV.formulae.each do |f|
+ rack = f.prefix.parent
+ if rack.directory?
+ puts "Uninstalling #{f}..."
+ rack.children do |keg|
+ if keg.directory?
+ keg = Keg.new(keg)
+ keg.unlink
+ keg.rmtree
+ end
+ end
+ rack.rmdir
+ end
+ end
+ end
+ rescue MultipleVersionsInstalledError => e
+ onoe e
+ puts "Use `brew remove --force #{e.name}` to remove all versions."
+ end
+end
diff --git a/Library/Homebrew/cmd/unlink.rb b/Library/Homebrew/cmd/unlink.rb
new file mode 100644
index 000000000..d4749ab76
--- /dev/null
+++ b/Library/Homebrew/cmd/unlink.rb
@@ -0,0 +1,8 @@
+module Homebrew extend self
+ def unlink
+ ARGV.kegs.each do |keg|
+ print "Unlinking #{keg}... "
+ puts "#{keg.unlink} links removed"
+ end
+ end
+end
diff --git a/Library/Homebrew/cmd/update.rb b/Library/Homebrew/cmd/update.rb
new file mode 100644
index 000000000..32f144c8e
--- /dev/null
+++ b/Library/Homebrew/cmd/update.rb
@@ -0,0 +1,159 @@
+module Homebrew extend self
+ def update
+ abort "Please `brew install git' first." unless system "/usr/bin/which -s git"
+
+ updater = RefreshBrew.new
+ if updater.update_from_masterbrew!
+ updater.report
+ else
+ puts "Already up-to-date."
+ end
+ end
+end
+
+class RefreshBrew
+ REPOSITORY_URL = "http://github.com/mxcl/homebrew.git"
+ INIT_COMMAND = "git init"
+ CHECKOUT_COMMAND = "git checkout -q master"
+ UPDATE_COMMAND = "git pull #{REPOSITORY_URL} master"
+ REVISION_COMMAND = "git log -l -1 --pretty=format:%H 2> /dev/null"
+ GIT_UP_TO_DATE = "Already up-to-date."
+
+ formula_regexp = 'Library/Formula/(.+?)\.rb'
+ ADDED_FORMULA = %r{^\s+create mode \d+ #{formula_regexp}$}
+ UPDATED_FORMULA = %r{^\s+#{formula_regexp}\s}
+ DELETED_FORMULA = %r{^\s+delete mode \d+ #{formula_regexp}$}
+
+ example_regexp = 'Library/Contributions/examples/([^.\s]+).*'
+ ADDED_EXAMPLE = %r{^\s+create mode \d+ #{example_regexp}$}
+ UPDATED_EXAMPLE = %r{^\s+#{example_regexp}}
+ DELETED_EXAMPLE = %r{^\s+delete mode \d+ #{example_regexp}$}
+
+ attr_reader :added_formulae, :updated_formulae, :deleted_formulae, :initial_revision
+ attr_reader :added_examples, :updated_examples, :deleted_examples
+
+ def initialize
+ @added_formulae, @updated_formulae, @deleted_formulae = [], [], []
+ @added_examples, @updated_examples, @deleted_examples = [], [], []
+ @initial_revision = self.current_revision
+ end
+
+ # Performs an update of the homebrew source. Returns +true+ if a newer
+ # version was available, +false+ if already up-to-date.
+ def update_from_masterbrew!
+ output = ''
+ HOMEBREW_REPOSITORY.cd do
+ if File.directory? '.git'
+ safe_system CHECKOUT_COMMAND
+ else
+ safe_system INIT_COMMAND
+ end
+ output = execute(UPDATE_COMMAND)
+ end
+
+ output.split("\n").reverse.each do |line|
+ case line
+ when ADDED_FORMULA
+ @added_formulae << $1
+ when DELETED_FORMULA
+ @deleted_formulae << $1
+ when UPDATED_FORMULA
+ @updated_formulae << $1 unless @added_formulae.include?($1) or @deleted_formulae.include?($1)
+ when ADDED_EXAMPLE
+ @added_examples << $1
+ when DELETED_EXAMPLE
+ @deleted_examples << $1
+ when UPDATED_EXAMPLE
+ @updated_examples << $1 unless @added_examples.include?($1) or @deleted_examples.include?($1)
+ end
+ end
+ @added_formulae.sort!
+ @updated_formulae.sort!
+ @deleted_formulae.sort!
+ @added_examples.sort!
+ @updated_examples.sort!
+ @deleted_examples.sort!
+
+ output.strip != GIT_UP_TO_DATE
+ end
+
+ def pending_formulae_changes?
+ !@updated_formulae.empty?
+ end
+
+ def pending_new_formulae?
+ !@added_formulae.empty?
+ end
+
+ def deleted_formulae?
+ !@deleted_formulae.empty?
+ end
+
+ def pending_examples_changes?
+ !@updated_examples.empty?
+ end
+
+ def pending_new_examples?
+ !@added_examples.empty?
+ end
+
+ def deleted_examples?
+ !@deleted_examples.empty?
+ end
+
+ def current_revision
+ HOMEBREW_REPOSITORY.cd { execute(REVISION_COMMAND).strip }
+ rescue
+ 'TAIL'
+ end
+
+ def report
+ puts "Updated Homebrew from #{initial_revision[0,8]} to #{current_revision[0,8]}."
+ ## New Formulae
+ if pending_new_formulae?
+ ohai "The following formulae are new:"
+ puts_columns added_formulae
+ end
+ ## Deleted Formulae
+ if deleted_formulae?
+ ohai "The following formulae were removed:"
+ puts_columns deleted_formulae
+ end
+ ## Updated Formulae
+ if pending_formulae_changes?
+ ohai "The following formulae were updated:"
+ puts_columns updated_formulae
+ else
+ puts "No formulae were updated."
+ end
+ ## New examples
+ if pending_new_examples?
+ ohai "The following external commands are new:"
+ puts_columns added_examples
+ end
+ ## Deleted examples
+ if deleted_examples?
+ ohai "The following external commands were removed:"
+ puts_columns deleted_examples
+ end
+ ## Updated Formulae
+ if pending_examples_changes?
+ ohai "The following external commands were updated:"
+ puts_columns updated_examples
+ else
+ puts "No external commands were updated."
+ end
+ end
+
+ private
+
+ def execute(cmd)
+ out = `#{cmd}`
+ if $? && !$?.success?
+ puts out
+ raise "Failed while executing #{cmd}"
+ end
+ ohai(cmd, out) if ARGV.verbose?
+ out
+ end
+end
diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb
new file mode 100644
index 000000000..455b29b31
--- /dev/null
+++ b/Library/Homebrew/cmd/uses.rb
@@ -0,0 +1,25 @@
+require 'formula'
+
+# `brew uses foo bar` now returns formula that use both foo and bar
+# Rationale: If you want the union just run the command twice and
+# concatenate the results.
+# The intersection is harder to achieve with shell tools.
+
+module Homebrew extend self
+ def uses
+ uses = Formula.all.select do |f|
+ ARGV.formulae.all? do |ff|
+ # For each formula given, show which other formulas depend on it.
+ # We only go one level up, ie. direct dependencies.
+ f.deps.include? ff.name
+ end
+ end
+ if ARGV.include? "--installed"
+ uses = uses.select do |f|
+ keg = HOMEBREW_CELLAR/f
+ keg.directory? and not keg.subdirs.empty?
+ end
+ end
+ puts uses.sort
+ end
+end