diff options
Diffstat (limited to 'Library/Homebrew/cmd')
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 |
