aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Library/Homebrew/cmd/doctor.rb1324
-rw-r--r--Library/Homebrew/cmd/install.rb4
-rw-r--r--Library/Homebrew/cmd/missing.rb26
-rw-r--r--Library/Homebrew/cmd/update.rb4
-rw-r--r--Library/Homebrew/diagnostic.rb1344
-rw-r--r--Library/Homebrew/exceptions.rb4
-rw-r--r--Library/Homebrew/test/test_integration_cmds.rb57
7 files changed, 1411 insertions, 1352 deletions
diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb
index 142c7fe0e..fe230c8bc 100644
--- a/Library/Homebrew/cmd/doctor.rb
+++ b/Library/Homebrew/cmd/doctor.rb
@@ -1,1318 +1,15 @@
-require "cmd/missing"
-require "formula"
-require "keg"
-require "language/python"
-require "version"
-
-class Volumes
- def initialize
- @volumes = get_mounts
- end
-
- def which(path)
- vols = get_mounts path
-
- # no volume found
- if vols.empty?
- return -1
- end
-
- vol_index = @volumes.index(vols[0])
- # volume not found in volume list
- if vol_index.nil?
- return -1
- end
- vol_index
- end
-
- def get_mounts(path = nil)
- vols = []
- # get the volume of path, if path is nil returns all volumes
-
- args = %w[/bin/df -P]
- args << path if path
-
- Utils.popen_read(*args) do |io|
- io.each_line do |line|
- case line.chomp
- # regex matches: /dev/disk0s2 489562928 440803616 48247312 91% /
- when /^.+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]{1,3}%\s+(.+)/
- vols << $1
- end
- end
- end
- vols
- end
-end
-
-class Checks
- ############# HELPERS
- # Finds files in HOMEBREW_PREFIX *and* /usr/local.
- # Specify paths relative to a prefix eg. "include/foo.h".
- # Sets @found for your convenience.
- def find_relative_paths(*relative_paths)
- @found = %W[#{HOMEBREW_PREFIX} /usr/local].uniq.inject([]) do |found, prefix|
- found + relative_paths.map { |f| File.join(prefix, f) }.select { |f| File.exist? f }
- end
- end
-
- def inject_file_list(list, str)
- list.inject(str) { |s, f| s << " #{f}\n" }
- end
- ############# END HELPERS
-
- # Sorry for the lack of an indent here, the diff would have been unreadable.
- # See https://github.com/Homebrew/homebrew/pull/9986
- def check_path_for_trailing_slashes
- bad_paths = ENV["PATH"].split(File::PATH_SEPARATOR).select { |p| p[-1..-1] == "/" }
- return if bad_paths.empty?
- inject_file_list bad_paths, <<-EOS.undent
- Some directories in your path end in a slash.
- Directories in your path should not end in a slash. This can break other
- doctor checks. The following directories should be edited:
- EOS
- end
-
- # Installing MacGPG2 interferes with Homebrew in a big way
- # https://github.com/GPGTools/MacGPG2
- def check_for_macgpg2
- return if File.exist? "/usr/local/MacGPG2/share/gnupg/VERSION"
-
- suspects = %w[
- /Applications/start-gpg-agent.app
- /Library/Receipts/libiconv1.pkg
- /usr/local/MacGPG2
- ]
-
- if suspects.any? { |f| File.exist? f } then <<-EOS.undent
- You may 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
-
- # Anaconda installs multiple system & brew dupes, including OpenSSL, Python,
- # sqlite, libpng, Qt, etc. Regularly breaks compile on Vim, MacVim and others.
- # Is flagged as part of the *-config script checks below, but people seem
- # to ignore those as warnings rather than extremely likely breakage.
- def check_for_anaconda
- return unless which("anaconda")
- return unless which("python")
-
- anaconda = which("anaconda").realpath.dirname
- python_binary = Utils.popen_read which("python"), "-c", "import sys; sys.stdout.write(sys.executable)"
- python = Pathname.new(python_binary).realpath.dirname
-
- # Only warn if Python lives with Anaconda, since is most problematic case.
- if python == anaconda then <<-EOS.undent
- Anaconda is known to frequently break Homebrew builds, including Vim and
- MacVim, due to bundling many duplicates of system and Homebrew-available
- tools.
-
- If you encounter a build failure please temporarily remove Anaconda
- from your $PATH and attempt the build again prior to reporting the
- failure to us. Thanks!
- EOS
- end
- end
-
- def __check_stray_files(dir, pattern, white_list, message)
- return unless File.directory?(dir)
-
- files = Dir.chdir(dir) do
- Dir[pattern].select { |f| File.file?(f) && !File.symlink?(f) } - Dir.glob(white_list)
- end.map { |file| File.join(dir, file) }
-
- inject_file_list(files, message) unless files.empty?
- end
-
- def check_for_stray_dylibs
- # 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
- "libmacfuse_i32.2.dylib", # OSXFuse MacFuse compatibility layer
- "libmacfuse_i64.2.dylib", # OSXFuse MacFuse compatibility layer
- "libosxfuse_i32.2.dylib", # OSXFuse
- "libosxfuse_i64.2.dylib", # OSXFuse
- "libTrAPI.dylib", # TrAPI / Endpoint Security VPN
- "libntfs-3g.*.dylib", # NTFS-3G
- "libntfs.*.dylib", # NTFS-3G
- "libublio.*.dylib", # NTFS-3G
- "libUFSDNTFS.dylib", # Paragon NTFS
- "libUFSDExtFS.dylib", # Paragon ExtFS
- ]
-
- __check_stray_files "/usr/local/lib", "*.dylib", white_list, <<-EOS.undent
- Unbrewed dylibs were found in /usr/local/lib.
- If you didn't put them there on purpose they could cause problems when
- building Homebrew formulae, and may need to be deleted.
-
- Unexpected dylibs:
- EOS
- end
-
- def check_for_stray_static_libs
- # Static libs which are generally OK should be added to this list,
- # with a short description of the software they come with.
- white_list = [
- "libsecurity_agent_client.a", # OS X 10.8.2 Supplemental Update
- "libsecurity_agent_server.a", # OS X 10.8.2 Supplemental Update
- "libntfs-3g.a", # NTFS-3G
- "libntfs.a", # NTFS-3G
- "libublio.a", # NTFS-3G
- ]
-
- __check_stray_files "/usr/local/lib", "*.a", white_list, <<-EOS.undent
- Unbrewed static libraries were found in /usr/local/lib.
- If you didn't put them there on purpose they could cause problems when
- building Homebrew formulae, and may need to be deleted.
-
- Unexpected static libraries:
- EOS
- end
-
- def check_for_stray_pcs
- # Package-config files which are generally OK should be added to this list,
- # with a short description of the software they come with.
- white_list = [
- "fuse.pc", # OSXFuse/MacFuse
- "macfuse.pc", # OSXFuse MacFuse compatibility layer
- "osxfuse.pc", # OSXFuse
- "libntfs-3g.pc", # NTFS-3G
- "libublio.pc", # NTFS-3G
- ]
-
- __check_stray_files "/usr/local/lib/pkgconfig", "*.pc", white_list, <<-EOS.undent
- Unbrewed .pc files were found in /usr/local/lib/pkgconfig.
- If you didn't put them there on purpose they could cause problems when
- building Homebrew formulae, and may need to be deleted.
-
- Unexpected .pc files:
- EOS
- end
-
- def check_for_stray_las
- white_list = [
- "libfuse.la", # MacFuse
- "libfuse_ino64.la", # MacFuse
- "libosxfuse_i32.la", # OSXFuse
- "libosxfuse_i64.la", # OSXFuse
- "libntfs-3g.la", # NTFS-3G
- "libntfs.la", # NTFS-3G
- "libublio.la", # NTFS-3G
- ]
-
- __check_stray_files "/usr/local/lib", "*.la", white_list, <<-EOS.undent
- Unbrewed .la files were found in /usr/local/lib.
- If you didn't put them there on purpose they could cause problems when
- building Homebrew formulae, and may need to be deleted.
-
- Unexpected .la files:
- EOS
- end
-
- def check_for_stray_headers
- white_list = [
- "fuse.h", # MacFuse
- "fuse/**/*.h", # MacFuse
- "macfuse/**/*.h", # OSXFuse MacFuse compatibility layer
- "osxfuse/**/*.h", # OSXFuse
- "ntfs/**/*.h", # NTFS-3G
- "ntfs-3g/**/*.h", # NTFS-3G
- ]
-
- __check_stray_files "/usr/local/include", "**/*.h", white_list, <<-EOS.undent
- Unbrewed header files were found in /usr/local/include.
- If you didn't put them there on purpose they could cause problems when
- building Homebrew formulae, and may need to be deleted.
-
- Unexpected header files:
- EOS
- end
-
- def check_for_other_package_managers
- ponk = MacOS.macports_or_fink
- unless ponk.empty?
- <<-EOS.undent
- You have MacPorts or Fink installed:
- #{ponk.join(", ")}
-
- This can cause trouble. You don't have to uninstall them, but you may want to
- temporarily move them out of the way, e.g.
-
- sudo mv /opt/local ~/macports
- EOS
- end
- end
-
- def check_for_broken_symlinks
- broken_symlinks = []
-
- Keg::PRUNEABLE_DIRECTORIES.each do |d|
- next unless d.directory?
- d.find do |path|
- if path.symlink? && !path.resolved_path_exists?
- broken_symlinks << path
- end
- end
- end
- return if broken_symlinks.empty?
- inject_file_list broken_symlinks, <<-EOS.undent
- Broken symlinks were found. Remove them with `brew prune`:
- EOS
- end
-
- def check_for_unsupported_osx
- if !ARGV.homebrew_developer? && OS::Mac.prerelease? then <<-EOS.undent
- You are using OS X #{MacOS.version}.
- We do not provide support for this pre-release version.
- You may encounter build failures or other breakages.
- EOS
- end
- end
-
- # TODO: distill down into single method definition a la BuildToolsError
- if MacOS.version >= "10.9"
- def check_for_installed_developer_tools
- unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
- No developer tools installed.
- Install the Command Line Tools:
- xcode-select --install
- EOS
- end
- end
-
- if OS::Mac.prerelease?
- def check_xcode_up_to_date
- if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
- <<-EOS.undent
- Your Xcode (#{MacOS::Xcode.version}) is outdated
- Please update to Xcode #{MacOS::Xcode.latest_version}.
- Xcode can be updated from
- https://developer.apple.com/xcode/downloads/
- EOS
- end
- end
- else
- def check_xcode_up_to_date
- if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
- <<-EOS.undent
- Your Xcode (#{MacOS::Xcode.version}) is outdated
- Please update to Xcode #{MacOS::Xcode.latest_version}.
- Xcode can be updated from the App Store.
- EOS
- end
- end
- end
-
- def check_clt_up_to_date
- if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
- A newer Command Line Tools release is available.
- Update them from Software Update in the App Store.
- EOS
- end
- end
- elsif MacOS.version == "10.8" || MacOS.version == "10.7"
- def check_for_installed_developer_tools
- unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
- No developer tools installed.
- You should install the Command Line Tools.
- The standalone package can be obtained from
- https://developer.apple.com/downloads
- or it can be installed via Xcode's preferences.
- EOS
- end
- end
-
- def check_xcode_up_to_date
- if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
- Your Xcode (#{MacOS::Xcode.version}) is outdated
- Please update to Xcode #{MacOS::Xcode.latest_version}.
- Xcode can be updated from
- https://developer.apple.com/xcode/downloads/
- EOS
- end
- end
-
- def check_clt_up_to_date
- if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
- A newer Command Line Tools release is available.
- The standalone package can be obtained from
- https://developer.apple.com/downloads
- or it can be installed via Xcode's preferences.
- EOS
- end
- end
- else
- def check_for_installed_developer_tools
- unless MacOS::Xcode.installed? then <<-EOS.undent
- Xcode is not installed. Most formulae need Xcode to build.
- It can be installed from
- https://developer.apple.com/xcode/downloads/
- EOS
- end
- end
-
- def check_xcode_up_to_date
- if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
- Your Xcode (#{MacOS::Xcode.version}) is outdated
- Please update to Xcode #{MacOS::Xcode.latest_version}.
- Xcode can be updated from
- https://developer.apple.com/xcode/downloads/
- EOS
- end
- end
- end
-
- def check_for_osx_gcc_installer
- if (MacOS.version < "10.7" || MacOS::Xcode.version > "4.1") && \
- MacOS.clang_version == "2.1"
- message = <<-EOS.undent
- You seem to have osx-gcc-installer installed.
- Homebrew doesn't support osx-gcc-installer. It causes many builds to fail and
- is an unlicensed distribution of really old Xcode files.
- EOS
- if MacOS.version >= :mavericks
- message += <<-EOS.undent
- Please run `xcode-select --install` to install the CLT.
- EOS
- elsif MacOS.version >= :lion
- message += <<-EOS.undent
- Please install the CLT or Xcode #{MacOS::Xcode.latest_version}.
- EOS
- else
- message += <<-EOS.undent
- Please install Xcode #{MacOS::Xcode.latest_version}.
- EOS
- end
- end
- end
-
- def check_for_stray_developer_directory
- # if the uninstaller script isn't there, it's a good guess neither are
- # any troublesome leftover Xcode files
- uninstaller = Pathname.new("/Developer/Library/uninstall-developer-folder")
- if MacOS::Xcode.version >= "4.3" && uninstaller.exist? then <<-EOS.undent
- You have leftover files from an older version of Xcode.
- You should delete them using:
- #{uninstaller}
- EOS
- end
- end
-
- def check_for_bad_install_name_tool
- return if MacOS.version < "10.9"
-
- libs = Pathname.new("/usr/bin/install_name_tool").dynamically_linked_libraries
-
- # otool may not work, for example if the Xcode license hasn't been accepted yet
- return if libs.empty?
-
- unless libs.include? "/usr/lib/libxcselect.dylib" then <<-EOS.undent
- You have an outdated version of /usr/bin/install_name_tool installed.
- This will cause binary package installations to fail.
- This can happen if you install osx-gcc-installer or RailsInstaller.
- To restore it, you must reinstall OS X or restore the binary from
- the OS packages.
- 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_real?
- end
-
- return if cant_read.empty?
- inject_file_list cant_read.sort, <<-EOS.undent
- Some directories 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
- directories, then the install will fail during the link step.
-
- You should probably `sudo chown -R $(whoami)` them:
- EOS
- 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_homebrew_repository
- unless HOMEBREW_REPOSITORY.writable_real? then <<-EOS.undent
- The #{HOMEBREW_REPOSITORY} is not writable.
-
- You should probably change the ownership and permissions of #{HOMEBREW_REPOSITORY}
- back to your user account.
- sudo chown -R $(whoami) #{HOMEBREW_REPOSITORY}
- EOS
- end
- end
-
- def check_access_usr_local
- return unless HOMEBREW_PREFIX.to_s == "/usr/local"
-
- unless HOMEBREW_PREFIX.writable_real? then <<-EOS.undent
- The /usr/local directory is not writable.
- Even if this directory was writable when you installed Homebrew, other
- software may change permissions on this directory. Some versions of the
- "InstantOn" component of Airfoil or running Cocktail cleanup/optimizations
- are known to do this.
-
- You should probably change the ownership and permissions of /usr/local
- back to your user account.
- sudo chown -R $(whoami):admin /usr/local
- EOS
- end
- end
-
- def check_tmpdir_sticky_bit
- # Repair Disk Permissions was removed(?) in El Capitan.
- # https://support.apple.com/en-us/HT201560
- if MacOS.version < "10.11"
- fix_message = "Please run \"Repair Disk Permissions\" in Disk Utility."
- else
- fix_message = "Please execute `sudo chmod +t #{HOMEBREW_TEMP}` in your Terminal"
- end
-
- world_writable = HOMEBREW_TEMP.stat.mode & 0777 == 0777
- if world_writable && !HOMEBREW_TEMP.sticky? then <<-EOS.undent
- #{HOMEBREW_TEMP} is world-writable but does not have the sticky bit set.
- #{fix_message}
- EOS
- end
- end
-
- (Keg::TOP_LEVEL_DIRECTORIES + ["lib/pkgconfig"]).each do |d|
- define_method("check_access_#{d.sub("/", "_")}") do
- dir = HOMEBREW_PREFIX.join(d)
- if dir.exist? && !dir.writable_real? then <<-EOS.undent
- #{dir} isn't writable.
-
- This can happen if you "sudo make install" software that isn't managed
- by Homebrew. If a formula tries to write a file to this directory, the
- install will fail during the link step.
-
- You should probably change the ownership and permissions of #{dir}
- back to your user account.
- sudo chown -R $(whoami) #{dir}
- EOS
- end
- end
- end
-
- def check_access_site_packages
- if Language::Python.homebrew_site_packages.exist? && !Language::Python.homebrew_site_packages.writable_real?
- <<-EOS.undent
- #{Language::Python.homebrew_site_packages} isn't writable.
- This can happen if you "sudo pip install" software that isn't managed
- by Homebrew. If you install a formula with Python modules, the install
- will fail during the link step.
-
- You should probably change the ownership and permissions of #{Language::Python.homebrew_site_packages}
- back to your user account.
- sudo chown -R $(whoami) #{Language::Python.homebrew_site_packages}
- EOS
- end
- end
-
- def check_access_logs
- if HOMEBREW_LOGS.exist? && !HOMEBREW_LOGS.writable_real?
- <<-EOS.undent
- #{HOMEBREW_LOGS} isn't writable.
- Homebrew writes debugging logs to this location.
-
- You should probably change the ownership and permissions of #{HOMEBREW_LOGS}
- back to your user account.
- sudo chown -R $(whoami) #{HOMEBREW_LOGS}
- EOS
- end
- end
-
- def check_access_cache
- if HOMEBREW_CACHE.exist? && !HOMEBREW_CACHE.writable_real?
- <<-EOS.undent
- #{HOMEBREW_CACHE} isn't writable.
- This can happen if you run `brew install` or `brew fetch` as another user.
- Homebrew caches downloaded files to this location.
-
- You should probably change the ownership and permissions of #{HOMEBREW_CACHE}
- back to your user account.
- sudo chown -R $(whoami) #{HOMEBREW_CACHE}
- EOS
- end
- end
-
- def check_access_cellar
- if HOMEBREW_CELLAR.exist? && !HOMEBREW_CELLAR.writable_real?
- <<-EOS.undent
- #{HOMEBREW_CELLAR} isn't writable.
-
- You should probably change the ownership and permissions of #{HOMEBREW_CELLAR}
- back to your user account.
- sudo chown -R $(whoami) #{HOMEBREW_CELLAR}
- EOS
- end
- end
-
- def check_access_prefix_opt
- opt = HOMEBREW_PREFIX.join("opt")
- if opt.exist? && !opt.writable_real?
- <<-EOS.undent
- #{opt} isn't writable.
- You should probably change the ownership and permissions of #{opt}
- back to your user account.
- sudo chown -R $(whoami) #{opt}
- EOS
- end
- end
-
- def check_ruby_version
- ruby_version = MacOS.version >= "10.9" ? "2.0" : "1.8"
- if RUBY_VERSION[/\d\.\d/] != ruby_version then <<-EOS.undent
- Ruby version #{RUBY_VERSION} is unsupported on #{MacOS.version}. Homebrew
- is developed and tested on Ruby #{ruby_version}, and may not work correctly
- on other Rubies. Patches are accepted as long as they don't cause breakage
- on supported Rubies.
- EOS
- end
- end
-
- def check_homebrew_prefix
- unless HOMEBREW_PREFIX.to_s == "/usr/local"
- <<-EOS.undent
- Your Homebrew is not installed to /usr/local
- You can install Homebrew anywhere you want, but some brews may only build
- correctly if you install in /usr/local. Sorry!
- EOS
- end
- end
-
- def check_xcode_prefix
- prefix = MacOS::Xcode.prefix
- return if prefix.nil?
- if prefix.to_s.match(" ")
- <<-EOS.undent
- Xcode is installed to a directory with a space in the name.
- This will cause some formulae to fail to build.
- EOS
- end
- end
-
- def check_xcode_prefix_exists
- prefix = MacOS::Xcode.prefix
- return if prefix.nil?
- unless prefix.exist?
- <<-EOS.undent
- The directory Xcode is reportedly installed to doesn't exist:
- #{prefix}
- You may need to `xcode-select` the proper path if you have moved Xcode.
- EOS
- end
- end
-
- def check_xcode_select_path
- if !MacOS::CLT.installed? && !File.file?("#{MacOS.active_developer_dir}/usr/bin/xcodebuild")
- path = MacOS::Xcode.bundle_path
- path = "/Developer" if path.nil? || !path.directory?
- <<-EOS.undent
- Your Xcode is configured with an invalid path.
- You should change it to the correct path:
- sudo xcode-select -switch #{path}
- EOS
- end
- end
-
- def check_user_path_1
- $seen_prefix_bin = false
- $seen_prefix_sbin = false
-
- out = nil
-
- paths.each do |p|
- case p
- when "/usr/bin"
- unless $seen_prefix_bin
- # only show the doctor message if there are any conflicts
- # rationale: a default install should not trigger any brew doctor messages
- conflicts = Dir["#{HOMEBREW_PREFIX}/bin/*"].
- map { |fn| File.basename fn }.
- select { |bn| File.exist? "/usr/bin/#{bn}" }
-
- if conflicts.size > 0
- out = inject_file_list conflicts, <<-EOS.undent
- /usr/bin occurs before #{HOMEBREW_PREFIX}/bin
- This means that system-provided programs will be used instead of those
- provided by Homebrew. The following tools exist at both paths:
- EOS
-
- out += <<-EOS.undent
-
- Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin
- occurs before /usr/bin. Here is a one-liner:
- echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
- EOS
- end
- end
- when "#{HOMEBREW_PREFIX}/bin"
- $seen_prefix_bin = true
- when "#{HOMEBREW_PREFIX}/sbin"
- $seen_prefix_sbin = true
- end
- end
- out
- end
-
- def check_user_path_2
- unless $seen_prefix_bin
- <<-EOS.undent
- Homebrew's bin was not found in your PATH.
- Consider setting the PATH for example like so
- echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
- EOS
- end
- end
-
- def check_user_path_3
- # Don't complain about sbin not being in the path if it doesn't exist
- sbin = (HOMEBREW_PREFIX+"sbin")
- if sbin.directory? && sbin.children.length > 0
- unless $seen_prefix_sbin
- <<-EOS.undent
- Homebrew's sbin was not found in your PATH but you have installed
- formulae that put executables in #{HOMEBREW_PREFIX}/sbin.
- Consider setting the PATH for example like so
- echo 'export PATH="#{HOMEBREW_PREFIX}/sbin:$PATH"' >> #{shell_profile}
- EOS
- end
- end
- end
-
- def check_for_bad_curl
- if MacOS.version <= "10.8" && !Formula["curl"].installed? then <<-EOS.undent
- The system curl on 10.8 and below is often incapable of supporting
- modern secure connections & will fail on fetching formulae.
-
- We recommend you:
- brew install curl
- EOS
- end
- end
-
- def check_user_curlrc
- if %w[CURL_HOME HOME].any? { |key| ENV[key] && File.exist?("#{ENV[key]}/.curlrc") } then <<-EOS.undent
- You have a curlrc file
- If you have trouble downloading packages with Homebrew, then maybe this
- is the problem? If the following command doesn't work, then try removing
- your curlrc:
- curl https://github.com
- EOS
- end
- end
-
- def check_for_unsupported_curl_vars
- # Support for SSL_CERT_DIR seemed to be removed in the 10.10.5 update.
- if MacOS.version >= :yosemite && !ENV["SSL_CERT_DIR"].nil? then <<-EOS.undent
- SSL_CERT_DIR support was removed from Apple's curl.
- If fetching formulae fails you should:
- unset SSL_CERT_DIR
- and remove it from #{shell_profile} if present.
- EOS
- end
- end
-
- def check_which_pkg_config
- binary = which "pkg-config"
- return if binary.nil?
-
- mono_config = Pathname.new("/usr/bin/pkg-config")
- if mono_config.exist? && mono_config.realpath.to_s.include?("Mono.framework") then <<-EOS.undent
- You have a non-Homebrew 'pkg-config' in your PATH:
- /usr/bin/pkg-config => #{mono_config.realpath}
-
- This was most likely created by the Mono installer. `./configure` may
- have problems finding brew-installed packages using this other pkg-config.
-
- Mono no longer installs this file as of 3.0.4. You should
- `sudo rm /usr/bin/pkg-config` and upgrade to the latest version of Mono.
- EOS
- elsif binary.to_s != "#{HOMEBREW_PREFIX}/bin/pkg-config" then <<-EOS.undent
- You have a non-Homebrew 'pkg-config' in your PATH:
- #{binary}
-
- `./configure` may have problems finding brew-installed packages using
- this other pkg-config.
- EOS
- end
- end
-
- def check_for_gettext
- find_relative_paths("lib/libgettextlib.dylib",
- "lib/libintl.dylib",
- "include/libintl.h")
-
- return if @found.empty?
-
- # Our gettext formula will be caught by check_linked_keg_only_brews
- f = Formulary.factory("gettext") rescue nil
- return if f && f.linked_keg.directory? && @found.all? do |path|
- Pathname.new(path).realpath.to_s.start_with? "#{HOMEBREW_CELLAR}/gettext"
- end
-
- s = <<-EOS.undent_________________________________________________________72
- gettext files detected at a system prefix
- These files can cause compilation and link failures, especially if they
- are compiled with improper architectures. Consider removing these files:
- EOS
- inject_file_list(@found, s)
- end
-
- def check_for_iconv
- unless find_relative_paths("lib/libiconv.dylib", "include/iconv.h").empty?
- if (f = Formulary.factory("libiconv") rescue nil) && f.linked_keg.directory?
- unless f.keg_only? then <<-EOS.undent
- A libiconv formula is installed and linked
- This will break stuff. For serious. Unlink it.
- EOS
- end
- else
- s = <<-EOS.undent_________________________________________________________72
- libiconv files detected at a system prefix other than /usr
- Homebrew doesn't provide a libiconv formula, and expects to link against
- the system version in /usr. libiconv in other prefixes can cause
- compile or link failure, especially if compiled with improper
- architectures. OS X itself never installs anything to /usr/local so
- it was either installed by a user or some other third party software.
-
- tl;dr: delete these files:
- EOS
- inject_file_list(@found, s)
- end
- end
- end
-
- def check_for_config_scripts
- return unless HOMEBREW_CELLAR.exist?
- real_cellar = HOMEBREW_CELLAR.realpath
-
- scripts = []
-
- whitelist = %W[
- /usr/bin /usr/sbin
- /usr/X11/bin /usr/X11R6/bin /opt/X11/bin
- #{HOMEBREW_PREFIX}/bin #{HOMEBREW_PREFIX}/sbin
- /Applications/Server.app/Contents/ServerRoot/usr/bin
- /Applications/Server.app/Contents/ServerRoot/usr/sbin
- ].map(&:downcase)
-
- paths.each do |p|
- next if whitelist.include?(p.downcase) || !File.directory?(p)
-
- realpath = Pathname.new(p).realpath.to_s
- next if realpath.start_with?(real_cellar.to_s, HOMEBREW_CELLAR.to_s)
-
- scripts += Dir.chdir(p) { Dir["*-config"] }.map { |c| File.join(p, c) }
- end
-
- return if scripts.empty?
- inject_file_list scripts, <<-EOS.undent
- "config" scripts exist outside your system or Homebrew directories.
- `./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. We found the following "config" scripts:
- EOS
- end
-
- def check_DYLD_vars
- found = ENV.keys.grep(/^DYLD_/)
- return if found.empty?
- s = inject_file_list found.map { |e| "#{e}: #{ENV.fetch(e)}" }, <<-EOS.undent
- Setting DYLD_* vars can break dynamic linking.
- Set variables:
- EOS
- if found.include? "DYLD_INSERT_LIBRARIES"
- s += <<-EOS.undent
-
- Setting DYLD_INSERT_LIBRARIES can cause Go builds to fail.
- Having this set is common if you use this software:
- http://asepsis.binaryage.com/
- EOS
- end
- s
- end
-
- def check_for_symlinked_cellar
- return unless HOMEBREW_CELLAR.exist?
- if HOMEBREW_CELLAR.symlink?
- <<-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 directory 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
- return unless HOMEBREW_CELLAR.exist?
- volumes = Volumes.new
-
- # Find the volumes for the TMP folder & HOMEBREW_CELLAR
- real_cellar = HOMEBREW_CELLAR.realpath
-
- tmp = Pathname.new(Dir.mktmpdir("doctor", HOMEBREW_TEMP))
- real_temp = tmp.realpath.parent
-
- where_cellar = volumes.which real_cellar
- where_temp = volumes.which real_temp
-
- Dir.delete tmp
-
- unless where_cellar == where_temp then <<-EOS.undent
- Your Cellar and TEMP directories 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
- directory on the same volume as your Cellar.
- EOS
- end
- end
-
- def check_filesystem_case_sensitive
- volumes = Volumes.new
- case_sensitive_vols = [HOMEBREW_PREFIX, HOMEBREW_REPOSITORY, HOMEBREW_CELLAR, HOMEBREW_TEMP].select do |dir|
- # We select the dir as being case-sensitive if either the UPCASED or the
- # downcased variant is missing.
- # Of course, on a case-insensitive fs, both exist because the os reports so.
- # In the rare situation when the user has indeed a downcased and an upcased
- # dir (e.g. /TMP and /tmp) this check falsely thinks it is case-insensitive
- # but we don't care beacuse: 1. there is more than one dir checked, 2. the
- # check is not vital and 3. we would have to touch files otherwise.
- upcased = Pathname.new(dir.to_s.upcase)
- downcased = Pathname.new(dir.to_s.downcase)
- dir.exist? && !(upcased.exist? && downcased.exist?)
- end.map { |case_sensitive_dir| volumes.get_mounts(case_sensitive_dir) }.uniq
- return if case_sensitive_vols.empty?
- <<-EOS.undent
- The filesystem on #{case_sensitive_vols.join(",")} appears to be case-sensitive.
- The default OS X filesystem is case-insensitive. Please report any apparent problems.
- EOS
- end
-
- def __check_git_version
- # https://help.github.com/articles/https-cloning-errors
- `git --version`.chomp =~ /git version ((?:\d+\.?)+)/
-
- if $1 && Version.new($1) < Version.new("1.7.10")
- git_upgrade_cmd = Formula["git"].any_version_installed? ? "upgrade" : "install"
-
- <<-EOS.undent
- An outdated version of Git was detected in your PATH.
- Git 1.7.10 or newer is required to perform checkouts over HTTPS from GitHub.
- Please upgrade: brew #{git_upgrade_cmd} git
- EOS
- end
- end
-
- def check_for_git
- if Utils.git_available?
- __check_git_version
- else <<-EOS.undent
- Git could not be 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 install Git:
- brew install git
- EOS
- end
- end
-
- def check_git_newline_settings
- return unless Utils.git_available?
-
- autocrlf = `git config --get core.autocrlf`.chomp
-
- if autocrlf == "true" then <<-EOS.undent
- Suspicious Git newline settings found.
-
- The detected Git newline settings will cause checkout problems:
- core.autocrlf = #{autocrlf}
-
- If you are not routinely dealing with Windows-based projects,
- consider removing these by running:
- `git config --global core.autocrlf input`
- EOS
- end
- end
-
- def check_git_origin
- return if !Utils.git_available? || !(HOMEBREW_REPOSITORY/".git").exist?
-
- origin = Homebrew.git_origin
-
- if origin.nil? then <<-EOS.undent
- Missing git origin remote.
-
- Without a correctly configured origin, Homebrew won't update
- properly. You can solve this by adding the Homebrew remote:
- cd #{HOMEBREW_REPOSITORY}
- git remote add origin https://github.com/Homebrew/homebrew.git
- EOS
- elsif origin !~ /(mxcl|Homebrew)\/homebrew(\.git)?$/ then <<-EOS.undent
- Suspicious git origin remote found.
-
- With a non-standard origin, Homebrew won't pull updates from
- the main repository. The current git origin is:
- #{origin}
-
- Unless you have compelling reasons, consider setting the
- origin remote to point at the main repository, located at:
- https://github.com/Homebrew/homebrew.git
- EOS
- end
- end
-
- def check_for_autoconf
- return unless MacOS::Xcode.provides_autotools?
-
- autoconf = which("autoconf")
- safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf]
- unless autoconf.nil? || safe_autoconfs.include?(autoconf.to_s) then <<-EOS.undent
- An "autoconf" in your path blocks the Xcode-provided version at:
- #{autoconf}
-
- This custom autoconf may cause some Homebrew formulae to fail to compile.
- EOS
- end
- end
-
- def __check_linked_brew(f)
- f.installed_prefixes.each do |prefix|
- prefix.find do |src|
- next if src == prefix
- dst = HOMEBREW_PREFIX + src.relative_path_from(prefix)
- return true if dst.symlink? && src == dst.resolved_path
- end
- end
-
- false
- end
-
- def check_for_linked_keg_only_brews
- return unless HOMEBREW_CELLAR.exist?
-
- linked = Formula.installed.select do |f|
- f.keg_only? && __check_linked_brew(f)
- end
-
- return if linked.empty?
- inject_file_list linked.map(&:full_name), <<-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 <formula>` 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
- end
-
- def check_for_other_frameworks
- # Other frameworks that are known to cause problems when present
- %w[expat.framework libexpat.framework libcurl.framework].
- map { |frmwrk| "/Library/Frameworks/#{frmwrk}" }.
- select { |frmwrk| File.exist? frmwrk }.
- map do |frmwrk|
- <<-EOS.undent
- #{frmwrk} detected
- This can be picked up by CMake's build system and likely cause the build to
- fail. You may need to move this file out of the way to compile CMake.
- EOS
- end.join
- end
-
- def check_tmpdir
- tmpdir = ENV["TMPDIR"]
- "TMPDIR #{tmpdir.inspect} doesn't exist." unless tmpdir.nil? || File.directory?(tmpdir)
- end
-
- def check_missing_deps
- return unless HOMEBREW_CELLAR.exist?
- missing = Set.new
- Homebrew.missing_deps(Formula.installed).each_value do |deps|
- missing.merge(deps)
- end
-
- if missing.any? then <<-EOS.undent
- Some installed formula are missing dependencies.
- You should `brew install` the missing dependencies:
-
- brew install #{missing.sort_by(&:full_name) * " "}
-
- Run `brew missing` for more details.
- EOS
- end
- end
-
- def check_git_status
- return unless Utils.git_available?
- HOMEBREW_REPOSITORY.cd do
- unless `git status --untracked-files=all --porcelain -- Library/Homebrew/ 2>/dev/null`.chomp.empty?
- <<-EOS.undent_________________________________________________________72
- You have uncommitted modifications to Homebrew
- If this is a surprise to you, then you should stash these modifications.
- Stashing returns Homebrew to a pristine state but can be undone
- should you later need to do so for some reason.
- cd #{HOMEBREW_LIBRARY} && git stash && git clean -d -f
- EOS
- end
- end
- end
-
- def check_for_enthought_python
- if which "enpkg" then <<-EOS.undent
- Enthought Python was found in your PATH.
- This can cause build problems, as this software installs its own
- copies of iconv and libxml2 into directories that are picked up by
- other build systems.
- EOS
- end
- end
-
- def check_for_library_python
- if File.exist?("/Library/Frameworks/Python.framework") then <<-EOS.undent
- Python is installed at /Library/Frameworks/Python.framework
-
- Homebrew only supports building against the System-provided Python or a
- brewed Python. In particular, Pythons installed to /Library can interfere
- with other software installs.
- EOS
- end
- end
-
- def check_for_old_homebrew_share_python_in_path
- s = ""
- ["", "3"].map do |suffix|
- if paths.include?((HOMEBREW_PREFIX/"share/python#{suffix}").to_s)
- s += "#{HOMEBREW_PREFIX}/share/python#{suffix} is not needed in PATH.\n"
- end
- end
- unless s.empty?
- s += <<-EOS.undent
- Formerly homebrew put Python scripts you installed via `pip` or `pip3`
- (or `easy_install`) into that directory above but now it can be removed
- from your PATH variable.
- Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
- You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
- (and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages
- anew with `pip install --upgrade`.
- EOS
- end
- end
-
- def check_for_bad_python_symlink
- return unless which "python"
- `python -V 2>&1` =~ /Python (\d+)\./
- # This won't be the right warning if we matched nothing at all
- return if $1.nil?
- unless $1 == "2" then <<-EOS.undent
- python is symlinked to python#{$1}
- This will confuse build scripts and in general lead to subtle breakage.
- EOS
- end
- end
-
- def check_for_non_prefixed_coreutils
- gnubin = "#{Formulary.factory("coreutils").prefix}/libexec/gnubin"
- if paths.include? gnubin then <<-EOS.undent
- Putting non-prefixed coreutils in your path can cause gmp builds to fail.
- EOS
- end
- end
-
- def check_for_non_prefixed_findutils
- default_names = Tab.for_name("findutils").with? "default-names"
- if default_names then <<-EOS.undent
- Putting non-prefixed findutils in your path can cause python builds to fail.
- EOS
- end
- end
-
- def check_for_pydistutils_cfg_in_home
- if File.exist? "#{ENV["HOME"]}/.pydistutils.cfg" then <<-EOS.undent
- A .pydistutils.cfg file was found in $HOME, which may cause Python
- builds to fail. See:
- https://bugs.python.org/issue6138
- https://bugs.python.org/issue4655
- EOS
- end
- end
-
- def check_for_outdated_homebrew
- return unless Utils.git_available?
- HOMEBREW_REPOSITORY.cd do
- if File.directory? ".git"
- local = `git rev-parse -q --verify refs/remotes/origin/master`.chomp
- remote = /^([a-f0-9]{40})/.match(`git ls-remote origin refs/heads/master 2>/dev/null`)
- if remote.nil? || local == remote[0]
- return
- end
- end
-
- timestamp = if File.directory? ".git"
- `git log -1 --format="%ct" HEAD`.to_i
- else
- HOMEBREW_LIBRARY.mtime.to_i
- end
-
- if Time.now.to_i - timestamp > 60 * 60 * 24 then <<-EOS.undent
- Your Homebrew is outdated.
- You haven't updated for at least 24 hours. This is a long time in brewland!
- To update Homebrew, run `brew update`.
- EOS
- end
- end
- end
-
- def check_for_unlinked_but_not_keg_only
- unlinked = Formula.racks.reject do |rack|
- if !(HOMEBREW_REPOSITORY/"Library/LinkedKegs"/rack.basename).directory?
- begin
- Formulary.from_rack(rack).keg_only?
- rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
- false
- end
- else
- true
- end
- end.map(&:basename)
-
- return if unlinked.empty?
- inject_file_list unlinked, <<-EOS.undent
- You have unlinked kegs in your Cellar
- Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
- those kegs to fail to run properly once built. Run `brew link` on these:
- EOS
- end
-
- def check_xcode_license_approved
- # If the user installs Xcode-only, they have to approve the
- # license or no "xc*" tool will work.
- if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success? then <<-EOS.undent
- You have not agreed to the Xcode license.
- Builds will fail! Agree to the license by opening Xcode.app or running:
- sudo xcodebuild -license
- EOS
- end
- end
-
- def check_for_latest_xquartz
- return unless MacOS::XQuartz.version
- return if MacOS::XQuartz.provided_by_apple?
-
- installed_version = Version.new(MacOS::XQuartz.version)
- latest_version = Version.new(MacOS::XQuartz.latest_version)
-
- return if installed_version >= latest_version
-
- <<-EOS.undent
- Your XQuartz (#{installed_version}) is outdated
- Please install XQuartz #{latest_version}:
- https://xquartz.macosforge.org
- EOS
- end
-
- def check_for_old_env_vars
- if ENV["HOMEBREW_KEEP_INFO"]
- <<-EOS.undent
- `HOMEBREW_KEEP_INFO` is no longer used
- info files are no longer deleted by default; you may
- remove this environment variable.
- EOS
- end
- end
-
- def check_for_pth_support
- homebrew_site_packages = Language::Python.homebrew_site_packages
- return unless homebrew_site_packages.directory?
- return if Language::Python.reads_brewed_pth_files?("python") != false
- return unless Language::Python.in_sys_path?("python", homebrew_site_packages)
- user_site_packages = Language::Python.user_site_packages "python"
- <<-EOS.undent
- Your default Python does not recognize the Homebrew site-packages
- directory as a special site-packages directory, which means that .pth
- files will not be followed. This means you will not be able to import
- some modules after installing them with Homebrew, like wxpython. To fix
- this for the current user, you can run:
-
- mkdir -p #{user_site_packages}
- echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{user_site_packages}/homebrew.pth
- EOS
- end
-
- def check_for_external_cmd_name_conflict
- cmds = paths.flat_map { |p| Dir["#{p}/brew-*"] }.uniq
- cmds = cmds.select { |cmd| File.file?(cmd) && File.executable?(cmd) }
- cmd_map = {}
- cmds.each do |cmd|
- cmd_name = File.basename(cmd, ".rb")
- cmd_map[cmd_name] ||= []
- cmd_map[cmd_name] << cmd
- end
- cmd_map.reject! { |_cmd_name, cmd_paths| cmd_paths.size == 1 }
- return if cmd_map.empty?
- s = "You have external commands with conflicting names.\n"
- cmd_map.each do |cmd_name, cmd_paths|
- s += inject_file_list cmd_paths, <<-EOS.undent
-
- Found command `#{cmd_name}` in following places:
- EOS
- end
- s
- end
-
- def all
- methods.map(&:to_s).grep(/^check_/)
- end
-end # end class Checks
+require "diagnostic"
module Homebrew
def doctor
- checks = Checks.new
+ checks = Diagnostic::Checks.new
if ARGV.include? "--list-checks"
puts checks.all.sort
exit
end
- inject_dump_stats(checks) if ARGV.switch? "D"
+ checks.inject_dump_stats! if ARGV.switch? "D"
if ARGV.named.empty?
methods = checks.all.sort
@@ -1349,19 +46,4 @@ module Homebrew
puts "Your system is ready to brew." unless Homebrew.failed?
end
-
- def inject_dump_stats(checks)
- checks.extend Module.new {
- def send(method, *)
- time = Time.now
- super
- ensure
- $times[method] = Time.now - time
- end
- }
- $times = {}
- at_exit do
- puts $times.sort_by { |_k, v| v }.map { |k, v| "#{k}: #{v}" }
- end
- end
end
diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb
index dbd8f5c04..c2ef9a334 100644
--- a/Library/Homebrew/cmd/install.rb
+++ b/Library/Homebrew/cmd/install.rb
@@ -1,5 +1,5 @@
require "blacklist"
-require "cmd/doctor"
+require "diagnostic"
require "cmd/search"
require "formula_installer"
require "tap"
@@ -159,7 +159,7 @@ module Homebrew
end
def check_xcode
- checks = Checks.new
+ checks = Diagnostic::Checks.new
%w[
check_for_unsupported_osx
check_for_bad_install_name_tool
diff --git a/Library/Homebrew/cmd/missing.rb b/Library/Homebrew/cmd/missing.rb
index 6805548a8..3d70e5f35 100644
--- a/Library/Homebrew/cmd/missing.rb
+++ b/Library/Homebrew/cmd/missing.rb
@@ -1,30 +1,8 @@
require "formula"
require "tab"
+require "diagnostic"
module Homebrew
- def missing_deps(ff)
- missing = {}
- ff.each do |f|
- missing_deps = f.recursive_dependencies do |dependent, dep|
- if dep.optional? || dep.recommended?
- tab = Tab.for_formula(dependent)
- Dependency.prune unless tab.with?(dep)
- elsif dep.build?
- Dependency.prune
- end
- end
-
- missing_deps.map!(&:to_formula)
- missing_deps.reject! { |d| d.installed_prefixes.any? }
-
- unless missing_deps.empty?
- yield f.full_name, missing_deps if block_given?
- missing[f.full_name] = missing_deps
- end
- end
- missing
- end
-
def missing
return unless HOMEBREW_CELLAR.exist?
@@ -34,7 +12,7 @@ module Homebrew
ARGV.resolved_formulae
end
- missing_deps(ff) do |name, missing|
+ Diagnostic.missing_deps(ff) do |name, missing|
print "#{name}: " if ff.size > 1
puts "#{missing * " "}"
end
diff --git a/Library/Homebrew/cmd/update.rb b/Library/Homebrew/cmd/update.rb
index 9e2541434..436175b25 100644
--- a/Library/Homebrew/cmd/update.rb
+++ b/Library/Homebrew/cmd/update.rb
@@ -1,5 +1,5 @@
require "cmd/tap"
-require "cmd/doctor"
+require "diagnostic"
require "formula_versions"
require "migrator"
require "formulary"
@@ -15,7 +15,7 @@ module Homebrew
end
# check permissions
- checks = Checks.new
+ checks = Diagnostic::Checks.new
%w[
check_access_usr_local
check_access_homebrew_repository
diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb
new file mode 100644
index 000000000..3dd7f566f
--- /dev/null
+++ b/Library/Homebrew/diagnostic.rb
@@ -0,0 +1,1344 @@
+require "keg"
+require "language/python"
+require "formula"
+require "version"
+
+module Homebrew
+ module Diagnostic
+ def self.missing_deps(ff)
+ missing = {}
+ ff.each do |f|
+ missing_deps = f.recursive_dependencies do |dependent, dep|
+ if dep.optional? || dep.recommended?
+ tab = Tab.for_formula(dependent)
+ Dependency.prune unless tab.with?(dep)
+ elsif dep.build?
+ Dependency.prune
+ end
+ end
+
+ missing_deps.map!(&:to_formula)
+ missing_deps.reject! { |d| d.installed_prefixes.any? }
+
+ unless missing_deps.empty?
+ yield f.full_name, missing_deps if block_given?
+ missing[f.full_name] = missing_deps
+ end
+ end
+ missing
+ end
+
+ class Volumes
+ def initialize
+ @volumes = get_mounts
+ end
+
+ def which(path)
+ vols = get_mounts path
+
+ # no volume found
+ if vols.empty?
+ return -1
+ end
+
+ vol_index = @volumes.index(vols[0])
+ # volume not found in volume list
+ if vol_index.nil?
+ return -1
+ end
+ vol_index
+ end
+
+ def get_mounts(path = nil)
+ vols = []
+ # get the volume of path, if path is nil returns all volumes
+
+ args = %w[/bin/df -P]
+ args << path if path
+
+ Utils.popen_read(*args) do |io|
+ io.each_line do |line|
+ case line.chomp
+ # regex matches: /dev/disk0s2 489562928 440803616 48247312 91% /
+ when /^.+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9]{1,3}%\s+(.+)/
+ vols << $1
+ end
+ end
+ end
+ vols
+ end
+ end
+
+ class Checks
+ ############# HELPERS
+ # Finds files in HOMEBREW_PREFIX *and* /usr/local.
+ # Specify paths relative to a prefix eg. "include/foo.h".
+ # Sets @found for your convenience.
+ def find_relative_paths(*relative_paths)
+ @found = [HOMEBREW_PREFIX, "/usr/local"].uniq.inject([]) do |found, prefix|
+ found + relative_paths.map { |f| File.join(prefix, f) }.select { |f| File.exist? f }
+ end
+ end
+
+ def inject_file_list(list, str)
+ list.inject(str) { |s, f| s << " #{f}\n" }
+ end
+ ############# END HELPERS
+
+ def inject_dump_stats!
+ self.extend Module.new {
+ def send(method, *)
+ time = Time.now
+ super
+ ensure
+ $times[method] = Time.now - time
+ end
+ }
+ $times = {}
+ at_exit do
+ puts $times.sort_by { |_k, v| v }.map { |k, v| "#{k}: #{v}" }
+ end
+ end
+
+ # See https://github.com/Homebrew/homebrew/pull/9986
+ def check_path_for_trailing_slashes
+ bad_paths = ENV["PATH"].split(File::PATH_SEPARATOR).select { |p| p[-1..-1] == "/" }
+ return if bad_paths.empty?
+ inject_file_list bad_paths, <<-EOS.undent
+ Some directories in your path end in a slash.
+ Directories in your path should not end in a slash. This can break other
+ doctor checks. The following directories should be edited:
+ EOS
+ end
+
+ # Installing MacGPG2 interferes with Homebrew in a big way
+ # https://github.com/GPGTools/MacGPG2
+ def check_for_macgpg2
+ return if File.exist? "/usr/local/MacGPG2/share/gnupg/VERSION"
+
+ suspects = %w[
+ /Applications/start-gpg-agent.app
+ /Library/Receipts/libiconv1.pkg
+ /usr/local/MacGPG2
+ ]
+
+ if suspects.any? { |f| File.exist? f } then <<-EOS.undent
+ You may 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
+
+ # Anaconda installs multiple system & brew dupes, including OpenSSL, Python,
+ # sqlite, libpng, Qt, etc. Regularly breaks compile on Vim, MacVim and others.
+ # Is flagged as part of the *-config script checks below, but people seem
+ # to ignore those as warnings rather than extremely likely breakage.
+ def check_for_anaconda
+ return unless which("anaconda")
+ return unless which("python")
+
+ anaconda = which("anaconda").realpath.dirname
+ python_binary = Utils.popen_read which("python"), "-c", "import sys; sys.stdout.write(sys.executable)"
+ python = Pathname.new(python_binary).realpath.dirname
+
+ # Only warn if Python lives with Anaconda, since is most problematic case.
+ if python == anaconda then <<-EOS.undent
+ Anaconda is known to frequently break Homebrew builds, including Vim and
+ MacVim, due to bundling many duplicates of system and Homebrew-available
+ tools.
+
+ If you encounter a build failure please temporarily remove Anaconda
+ from your $PATH and attempt the build again prior to reporting the
+ failure to us. Thanks!
+ EOS
+ end
+ end
+
+ def __check_stray_files(dir, pattern, white_list, message)
+ return unless File.directory?(dir)
+
+ files = Dir.chdir(dir) do
+ Dir[pattern].select { |f| File.file?(f) && !File.symlink?(f) } - Dir.glob(white_list)
+ end.map { |file| File.join(dir, file) }
+
+ inject_file_list(files, message) unless files.empty?
+ end
+
+ def check_for_stray_dylibs
+ # 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
+ "libmacfuse_i32.2.dylib", # OSXFuse MacFuse compatibility layer
+ "libmacfuse_i64.2.dylib", # OSXFuse MacFuse compatibility layer
+ "libosxfuse_i32.2.dylib", # OSXFuse
+ "libosxfuse_i64.2.dylib", # OSXFuse
+ "libTrAPI.dylib", # TrAPI / Endpoint Security VPN
+ "libntfs-3g.*.dylib", # NTFS-3G
+ "libntfs.*.dylib", # NTFS-3G
+ "libublio.*.dylib", # NTFS-3G
+ "libUFSDNTFS.dylib", # Paragon NTFS
+ "libUFSDExtFS.dylib", # Paragon ExtFS
+ ]
+
+ __check_stray_files "/usr/local/lib", "*.dylib", white_list, <<-EOS.undent
+ Unbrewed dylibs were found in /usr/local/lib.
+ If you didn't put them there on purpose they could cause problems when
+ building Homebrew formulae, and may need to be deleted.
+
+ Unexpected dylibs:
+ EOS
+ end
+
+ def check_for_stray_static_libs
+ # Static libs which are generally OK should be added to this list,
+ # with a short description of the software they come with.
+ white_list = [
+ "libsecurity_agent_client.a", # OS X 10.8.2 Supplemental Update
+ "libsecurity_agent_server.a", # OS X 10.8.2 Supplemental Update
+ "libntfs-3g.a", # NTFS-3G
+ "libntfs.a", # NTFS-3G
+ "libublio.a", # NTFS-3G
+ ]
+
+ __check_stray_files "/usr/local/lib", "*.a", white_list, <<-EOS.undent
+ Unbrewed static libraries were found in /usr/local/lib.
+ If you didn't put them there on purpose they could cause problems when
+ building Homebrew formulae, and may need to be deleted.
+
+ Unexpected static libraries:
+ EOS
+ end
+
+ def check_for_stray_pcs
+ # Package-config files which are generally OK should be added to this list,
+ # with a short description of the software they come with.
+ white_list = [
+ "fuse.pc", # OSXFuse/MacFuse
+ "macfuse.pc", # OSXFuse MacFuse compatibility layer
+ "osxfuse.pc", # OSXFuse
+ "libntfs-3g.pc", # NTFS-3G
+ "libublio.pc", # NTFS-3G
+ ]
+
+ __check_stray_files "/usr/local/lib/pkgconfig", "*.pc", white_list, <<-EOS.undent
+ Unbrewed .pc files were found in /usr/local/lib/pkgconfig.
+ If you didn't put them there on purpose they could cause problems when
+ building Homebrew formulae, and may need to be deleted.
+
+ Unexpected .pc files:
+ EOS
+ end
+
+ def check_for_stray_las
+ white_list = [
+ "libfuse.la", # MacFuse
+ "libfuse_ino64.la", # MacFuse
+ "libosxfuse_i32.la", # OSXFuse
+ "libosxfuse_i64.la", # OSXFuse
+ "libntfs-3g.la", # NTFS-3G
+ "libntfs.la", # NTFS-3G
+ "libublio.la", # NTFS-3G
+ ]
+
+ __check_stray_files "/usr/local/lib", "*.la", white_list, <<-EOS.undent
+ Unbrewed .la files were found in /usr/local/lib.
+ If you didn't put them there on purpose they could cause problems when
+ building Homebrew formulae, and may need to be deleted.
+
+ Unexpected .la files:
+ EOS
+ end
+
+ def check_for_stray_headers
+ white_list = [
+ "fuse.h", # MacFuse
+ "fuse/**/*.h", # MacFuse
+ "macfuse/**/*.h", # OSXFuse MacFuse compatibility layer
+ "osxfuse/**/*.h", # OSXFuse
+ "ntfs/**/*.h", # NTFS-3G
+ "ntfs-3g/**/*.h", # NTFS-3G
+ ]
+
+ __check_stray_files "/usr/local/include", "**/*.h", white_list, <<-EOS.undent
+ Unbrewed header files were found in /usr/local/include.
+ If you didn't put them there on purpose they could cause problems when
+ building Homebrew formulae, and may need to be deleted.
+
+ Unexpected header files:
+ EOS
+ end
+
+ def check_for_other_package_managers
+ ponk = MacOS.macports_or_fink
+ unless ponk.empty?
+ <<-EOS.undent
+ You have MacPorts or Fink installed:
+ #{ponk.join(", ")}
+
+ This can cause trouble. You don't have to uninstall them, but you may want to
+ temporarily move them out of the way, e.g.
+
+ sudo mv /opt/local ~/macports
+ EOS
+ end
+ end
+
+ def check_for_broken_symlinks
+ broken_symlinks = []
+
+ Keg::PRUNEABLE_DIRECTORIES.each do |d|
+ next unless d.directory?
+ d.find do |path|
+ if path.symlink? && !path.resolved_path_exists?
+ broken_symlinks << path
+ end
+ end
+ end
+ return if broken_symlinks.empty?
+ inject_file_list broken_symlinks, <<-EOS.undent
+ Broken symlinks were found. Remove them with `brew prune`:
+ EOS
+ end
+
+ def check_for_unsupported_osx
+ if !ARGV.homebrew_developer? && OS::Mac.prerelease? then <<-EOS.undent
+ You are using OS X #{MacOS.version}.
+ We do not provide support for this pre-release version.
+ You may encounter build failures or other breakages.
+ EOS
+ end
+ end
+
+ # TODO: distill down into single method definition a la BuildToolsError
+ if MacOS.version >= "10.9"
+ def check_for_installed_developer_tools
+ unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
+ No developer tools installed.
+ Install the Command Line Tools:
+ xcode-select --install
+ EOS
+ end
+ end
+
+ if OS::Mac.prerelease?
+ def check_xcode_up_to_date
+ if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
+ <<-EOS.undent
+ Your Xcode (#{MacOS::Xcode.version}) is outdated
+ Please update to Xcode #{MacOS::Xcode.latest_version}.
+ Xcode can be updated from
+ https://developer.apple.com/xcode/downloads/
+ EOS
+ end
+ end
+ else
+ def check_xcode_up_to_date
+ if MacOS::Xcode.installed? && MacOS::Xcode.outdated?
+ <<-EOS.undent
+ Your Xcode (#{MacOS::Xcode.version}) is outdated
+ Please update to Xcode #{MacOS::Xcode.latest_version}.
+ Xcode can be updated from the App Store.
+ EOS
+ end
+ end
+ end
+
+ def check_clt_up_to_date
+ if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
+ A newer Command Line Tools release is available.
+ Update them from Software Update in the App Store.
+ EOS
+ end
+ end
+ elsif MacOS.version == "10.8" || MacOS.version == "10.7"
+ def check_for_installed_developer_tools
+ unless MacOS::Xcode.installed? || MacOS::CLT.installed? then <<-EOS.undent
+ No developer tools installed.
+ You should install the Command Line Tools.
+ The standalone package can be obtained from
+ https://developer.apple.com/downloads
+ or it can be installed via Xcode's preferences.
+ EOS
+ end
+ end
+
+ def check_xcode_up_to_date
+ if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
+ Your Xcode (#{MacOS::Xcode.version}) is outdated
+ Please update to Xcode #{MacOS::Xcode.latest_version}.
+ Xcode can be updated from
+ https://developer.apple.com/xcode/downloads/
+ EOS
+ end
+ end
+
+ def check_clt_up_to_date
+ if MacOS::CLT.installed? && MacOS::CLT.outdated? then <<-EOS.undent
+ A newer Command Line Tools release is available.
+ The standalone package can be obtained from
+ https://developer.apple.com/downloads
+ or it can be installed via Xcode's preferences.
+ EOS
+ end
+ end
+ else
+ def check_for_installed_developer_tools
+ unless MacOS::Xcode.installed? then <<-EOS.undent
+ Xcode is not installed. Most formulae need Xcode to build.
+ It can be installed from
+ https://developer.apple.com/xcode/downloads/
+ EOS
+ end
+ end
+
+ def check_xcode_up_to_date
+ if MacOS::Xcode.installed? && MacOS::Xcode.outdated? then <<-EOS.undent
+ Your Xcode (#{MacOS::Xcode.version}) is outdated
+ Please update to Xcode #{MacOS::Xcode.latest_version}.
+ Xcode can be updated from
+ https://developer.apple.com/xcode/downloads/
+ EOS
+ end
+ end
+ end
+
+ def check_for_osx_gcc_installer
+ if (MacOS.version < "10.7" || MacOS::Xcode.version > "4.1") && \
+ MacOS.clang_version == "2.1"
+ message = <<-EOS.undent
+ You seem to have osx-gcc-installer installed.
+ Homebrew doesn't support osx-gcc-installer. It causes many builds to fail and
+ is an unlicensed distribution of really old Xcode files.
+ EOS
+ if MacOS.version >= :mavericks
+ message += <<-EOS.undent
+ Please run `xcode-select --install` to install the CLT.
+ EOS
+ elsif MacOS.version >= :lion
+ message += <<-EOS.undent
+ Please install the CLT or Xcode #{MacOS::Xcode.latest_version}.
+ EOS
+ else
+ message += <<-EOS.undent
+ Please install Xcode #{MacOS::Xcode.latest_version}.
+ EOS
+ end
+ end
+ end
+
+ def check_for_stray_developer_directory
+ # if the uninstaller script isn't there, it's a good guess neither are
+ # any troublesome leftover Xcode files
+ uninstaller = Pathname.new("/Developer/Library/uninstall-developer-folder")
+ if MacOS::Xcode.version >= "4.3" && uninstaller.exist? then <<-EOS.undent
+ You have leftover files from an older version of Xcode.
+ You should delete them using:
+ #{uninstaller}
+ EOS
+ end
+ end
+
+ def check_for_bad_install_name_tool
+ return if MacOS.version < "10.9"
+
+ libs = Pathname.new("/usr/bin/install_name_tool").dynamically_linked_libraries
+
+ # otool may not work, for example if the Xcode license hasn't been accepted yet
+ return if libs.empty?
+
+ unless libs.include? "/usr/lib/libxcselect.dylib" then <<-EOS.undent
+ You have an outdated version of /usr/bin/install_name_tool installed.
+ This will cause binary package installations to fail.
+ This can happen if you install osx-gcc-installer or RailsInstaller.
+ To restore it, you must reinstall OS X or restore the binary from
+ the OS packages.
+ 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_real?
+ end
+
+ return if cant_read.empty?
+ inject_file_list cant_read.sort, <<-EOS.undent
+ Some directories 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
+ directories, then the install will fail during the link step.
+
+ You should probably `sudo chown -R $(whoami)` them:
+ EOS
+ 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_homebrew_repository
+ unless HOMEBREW_REPOSITORY.writable_real? then <<-EOS.undent
+ The #{HOMEBREW_REPOSITORY} is not writable.
+
+ You should probably change the ownership and permissions of #{HOMEBREW_REPOSITORY}
+ back to your user account.
+ sudo chown -R $(whoami) #{HOMEBREW_REPOSITORY}
+ EOS
+ end
+ end
+
+ def check_access_usr_local
+ return unless HOMEBREW_PREFIX.to_s == "/usr/local"
+
+ unless HOMEBREW_PREFIX.writable_real? then <<-EOS.undent
+ The /usr/local directory is not writable.
+ Even if this directory was writable when you installed Homebrew, other
+ software may change permissions on this directory. Some versions of the
+ "InstantOn" component of Airfoil or running Cocktail cleanup/optimizations
+ are known to do this.
+
+ You should probably change the ownership and permissions of /usr/local
+ back to your user account.
+ sudo chown -R $(whoami):admin /usr/local
+ EOS
+ end
+ end
+
+ def check_tmpdir_sticky_bit
+ # Repair Disk Permissions was removed(?) in El Capitan.
+ # https://support.apple.com/en-us/HT201560
+ if MacOS.version < "10.11"
+ fix_message = "Please run \"Repair Disk Permissions\" in Disk Utility."
+ else
+ fix_message = "Please execute `sudo chmod +t #{HOMEBREW_TEMP}` in your Terminal"
+ end
+
+ world_writable = HOMEBREW_TEMP.stat.mode & 0777 == 0777
+ if world_writable && !HOMEBREW_TEMP.sticky? then <<-EOS.undent
+ #{HOMEBREW_TEMP} is world-writable but does not have the sticky bit set.
+ #{fix_message}
+ EOS
+ end
+ end
+
+ (Keg::TOP_LEVEL_DIRECTORIES + ["lib/pkgconfig"]).each do |d|
+ define_method("check_access_#{d.sub("/", "_")}") do
+ dir = HOMEBREW_PREFIX.join(d)
+ if dir.exist? && !dir.writable_real? then <<-EOS.undent
+ #{dir} isn't writable.
+
+ This can happen if you "sudo make install" software that isn't managed
+ by Homebrew. If a formula tries to write a file to this directory, the
+ install will fail during the link step.
+
+ You should probably change the ownership and permissions of #{dir}
+ back to your user account.
+ sudo chown -R $(whoami) #{dir}
+ EOS
+ end
+ end
+ end
+
+ def check_access_site_packages
+ if Language::Python.homebrew_site_packages.exist? && !Language::Python.homebrew_site_packages.writable_real?
+ <<-EOS.undent
+ #{Language::Python.homebrew_site_packages} isn't writable.
+ This can happen if you "sudo pip install" software that isn't managed
+ by Homebrew. If you install a formula with Python modules, the install
+ will fail during the link step.
+
+ You should probably change the ownership and permissions of #{Language::Python.homebrew_site_packages}
+ back to your user account.
+ sudo chown -R $(whoami) #{Language::Python.homebrew_site_packages}
+ EOS
+ end
+ end
+
+ def check_access_logs
+ if HOMEBREW_LOGS.exist? && !HOMEBREW_LOGS.writable_real?
+ <<-EOS.undent
+ #{HOMEBREW_LOGS} isn't writable.
+ Homebrew writes debugging logs to this location.
+
+ You should probably change the ownership and permissions of #{HOMEBREW_LOGS}
+ back to your user account.
+ sudo chown -R $(whoami) #{HOMEBREW_LOGS}
+ EOS
+ end
+ end
+
+ def check_access_cache
+ if HOMEBREW_CACHE.exist? && !HOMEBREW_CACHE.writable_real?
+ <<-EOS.undent
+ #{HOMEBREW_CACHE} isn't writable.
+ This can happen if you run `brew install` or `brew fetch` as another user.
+ Homebrew caches downloaded files to this location.
+
+ You should probably change the ownership and permissions of #{HOMEBREW_CACHE}
+ back to your user account.
+ sudo chown -R $(whoami) #{HOMEBREW_CACHE}
+ EOS
+ end
+ end
+
+ def check_access_cellar
+ if HOMEBREW_CELLAR.exist? && !HOMEBREW_CELLAR.writable_real?
+ <<-EOS.undent
+ #{HOMEBREW_CELLAR} isn't writable.
+
+ You should probably change the ownership and permissions of #{HOMEBREW_CELLAR}
+ back to your user account.
+ sudo chown -R $(whoami) #{HOMEBREW_CELLAR}
+ EOS
+ end
+ end
+
+ def check_access_prefix_opt
+ opt = HOMEBREW_PREFIX.join("opt")
+ if opt.exist? && !opt.writable_real?
+ <<-EOS.undent
+ #{opt} isn't writable.
+ You should probably change the ownership and permissions of #{opt}
+ back to your user account.
+ sudo chown -R $(whoami) #{opt}
+ EOS
+ end
+ end
+
+ def check_ruby_version
+ ruby_version = MacOS.version >= "10.9" ? "2.0" : "1.8"
+ if RUBY_VERSION[/\d\.\d/] != ruby_version then <<-EOS.undent
+ Ruby version #{RUBY_VERSION} is unsupported on #{MacOS.version}. Homebrew
+ is developed and tested on Ruby #{ruby_version}, and may not work correctly
+ on other Rubies. Patches are accepted as long as they don't cause breakage
+ on supported Rubies.
+ EOS
+ end
+ end
+
+ def check_homebrew_prefix
+ unless HOMEBREW_PREFIX.to_s == "/usr/local"
+ <<-EOS.undent
+ Your Homebrew is not installed to /usr/local
+ You can install Homebrew anywhere you want, but some brews may only build
+ correctly if you install in /usr/local. Sorry!
+ EOS
+ end
+ end
+
+ def check_xcode_prefix
+ prefix = MacOS::Xcode.prefix
+ return if prefix.nil?
+ if prefix.to_s.match(" ")
+ <<-EOS.undent
+ Xcode is installed to a directory with a space in the name.
+ This will cause some formulae to fail to build.
+ EOS
+ end
+ end
+
+ def check_xcode_prefix_exists
+ prefix = MacOS::Xcode.prefix
+ return if prefix.nil?
+ unless prefix.exist?
+ <<-EOS.undent
+ The directory Xcode is reportedly installed to doesn't exist:
+ #{prefix}
+ You may need to `xcode-select` the proper path if you have moved Xcode.
+ EOS
+ end
+ end
+
+ def check_xcode_select_path
+ if !MacOS::CLT.installed? && !File.file?("#{MacOS.active_developer_dir}/usr/bin/xcodebuild")
+ path = MacOS::Xcode.bundle_path
+ path = "/Developer" if path.nil? || !path.directory?
+ <<-EOS.undent
+ Your Xcode is configured with an invalid path.
+ You should change it to the correct path:
+ sudo xcode-select -switch #{path}
+ EOS
+ end
+ end
+
+ def check_user_path_1
+ $seen_prefix_bin = false
+ $seen_prefix_sbin = false
+
+ out = nil
+
+ paths.each do |p|
+ case p
+ when "/usr/bin"
+ unless $seen_prefix_bin
+ # only show the doctor message if there are any conflicts
+ # rationale: a default install should not trigger any brew doctor messages
+ conflicts = Dir["#{HOMEBREW_PREFIX}/bin/*"].
+ map { |fn| File.basename fn }.
+ select { |bn| File.exist? "/usr/bin/#{bn}" }
+
+ if conflicts.size > 0
+ out = inject_file_list conflicts, <<-EOS.undent
+ /usr/bin occurs before #{HOMEBREW_PREFIX}/bin
+ This means that system-provided programs will be used instead of those
+ provided by Homebrew. The following tools exist at both paths:
+ EOS
+
+ out += <<-EOS.undent
+
+ Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin
+ occurs before /usr/bin. Here is a one-liner:
+ echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
+ EOS
+ end
+ end
+ when "#{HOMEBREW_PREFIX}/bin"
+ $seen_prefix_bin = true
+ when "#{HOMEBREW_PREFIX}/sbin"
+ $seen_prefix_sbin = true
+ end
+ end
+ out
+ end
+
+ def check_user_path_2
+ unless $seen_prefix_bin
+ <<-EOS.undent
+ Homebrew's bin was not found in your PATH.
+ Consider setting the PATH for example like so
+ echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile}
+ EOS
+ end
+ end
+
+ def check_user_path_3
+ # Don't complain about sbin not being in the path if it doesn't exist
+ sbin = (HOMEBREW_PREFIX+"sbin")
+ if sbin.directory? && sbin.children.length > 0
+ unless $seen_prefix_sbin
+ <<-EOS.undent
+ Homebrew's sbin was not found in your PATH but you have installed
+ formulae that put executables in #{HOMEBREW_PREFIX}/sbin.
+ Consider setting the PATH for example like so
+ echo 'export PATH="#{HOMEBREW_PREFIX}/sbin:$PATH"' >> #{shell_profile}
+ EOS
+ end
+ end
+ end
+
+ def check_for_bad_curl
+ if MacOS.version <= "10.8" && !Formula["curl"].installed? then <<-EOS.undent
+ The system curl on 10.8 and below is often incapable of supporting
+ modern secure connections & will fail on fetching formulae.
+
+ We recommend you:
+ brew install curl
+ EOS
+ end
+ end
+
+ def check_user_curlrc
+ if %w[CURL_HOME HOME].any? { |key| ENV[key] && File.exist?("#{ENV[key]}/.curlrc") } then <<-EOS.undent
+ You have a curlrc file
+ If you have trouble downloading packages with Homebrew, then maybe this
+ is the problem? If the following command doesn't work, then try removing
+ your curlrc:
+ curl https://github.com
+ EOS
+ end
+ end
+
+ def check_for_unsupported_curl_vars
+ # Support for SSL_CERT_DIR seemed to be removed in the 10.10.5 update.
+ if MacOS.version >= :yosemite && !ENV["SSL_CERT_DIR"].nil? then <<-EOS.undent
+ SSL_CERT_DIR support was removed from Apple's curl.
+ If fetching formulae fails you should:
+ unset SSL_CERT_DIR
+ and remove it from #{shell_profile} if present.
+ EOS
+ end
+ end
+
+ def check_which_pkg_config
+ binary = which "pkg-config"
+ return if binary.nil?
+
+ mono_config = Pathname.new("/usr/bin/pkg-config")
+ if mono_config.exist? && mono_config.realpath.to_s.include?("Mono.framework") then <<-EOS.undent
+ You have a non-Homebrew 'pkg-config' in your PATH:
+ /usr/bin/pkg-config => #{mono_config.realpath}
+
+ This was most likely created by the Mono installer. `./configure` may
+ have problems finding brew-installed packages using this other pkg-config.
+
+ Mono no longer installs this file as of 3.0.4. You should
+ `sudo rm /usr/bin/pkg-config` and upgrade to the latest version of Mono.
+ EOS
+ elsif binary.to_s != "#{HOMEBREW_PREFIX}/bin/pkg-config" then <<-EOS.undent
+ You have a non-Homebrew 'pkg-config' in your PATH:
+ #{binary}
+
+ `./configure` may have problems finding brew-installed packages using
+ this other pkg-config.
+ EOS
+ end
+ end
+
+ def check_for_gettext
+ find_relative_paths("lib/libgettextlib.dylib",
+ "lib/libintl.dylib",
+ "include/libintl.h")
+
+ return if @found.empty?
+
+ # Our gettext formula will be caught by check_linked_keg_only_brews
+ f = Formulary.factory("gettext") rescue nil
+ return if f && f.linked_keg.directory? && @found.all? do |path|
+ Pathname.new(path).realpath.to_s.start_with? "#{HOMEBREW_CELLAR}/gettext"
+ end
+
+ s = <<-EOS.undent_________________________________________________________72
+ gettext files detected at a system prefix
+ These files can cause compilation and link failures, especially if they
+ are compiled with improper architectures. Consider removing these files:
+ EOS
+ inject_file_list(@found, s)
+ end
+
+ def check_for_iconv
+ unless find_relative_paths("lib/libiconv.dylib", "include/iconv.h").empty?
+ if (f = Formulary.factory("libiconv") rescue nil) && f.linked_keg.directory?
+ unless f.keg_only? then <<-EOS.undent
+ A libiconv formula is installed and linked
+ This will break stuff. For serious. Unlink it.
+ EOS
+ end
+ else
+ s = <<-EOS.undent_________________________________________________________72
+ libiconv files detected at a system prefix other than /usr
+ Homebrew doesn't provide a libiconv formula, and expects to link against
+ the system version in /usr. libiconv in other prefixes can cause
+ compile or link failure, especially if compiled with improper
+ architectures. OS X itself never installs anything to /usr/local so
+ it was either installed by a user or some other third party software.
+
+ tl;dr: delete these files:
+ EOS
+ inject_file_list(@found, s)
+ end
+ end
+ end
+
+ def check_for_config_scripts
+ return unless HOMEBREW_CELLAR.exist?
+ real_cellar = HOMEBREW_CELLAR.realpath
+
+ scripts = []
+
+ whitelist = %W[
+ /usr/bin /usr/sbin
+ /usr/X11/bin /usr/X11R6/bin /opt/X11/bin
+ #{HOMEBREW_PREFIX}/bin #{HOMEBREW_PREFIX}/sbin
+ /Applications/Server.app/Contents/ServerRoot/usr/bin
+ /Applications/Server.app/Contents/ServerRoot/usr/sbin
+ ].map(&:downcase)
+
+ paths.each do |p|
+ next if whitelist.include?(p.downcase) || !File.directory?(p)
+
+ realpath = Pathname.new(p).realpath.to_s
+ next if realpath.start_with?(real_cellar.to_s, HOMEBREW_CELLAR.to_s)
+
+ scripts += Dir.chdir(p) { Dir["*-config"] }.map { |c| File.join(p, c) }
+ end
+
+ return if scripts.empty?
+ inject_file_list scripts, <<-EOS.undent
+ "config" scripts exist outside your system or Homebrew directories.
+ `./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. We found the following "config" scripts:
+ EOS
+ end
+
+ def check_DYLD_vars
+ found = ENV.keys.grep(/^DYLD_/)
+ return if found.empty?
+ s = inject_file_list found.map { |e| "#{e}: #{ENV.fetch(e)}" }, <<-EOS.undent
+ Setting DYLD_* vars can break dynamic linking.
+ Set variables:
+ EOS
+ if found.include? "DYLD_INSERT_LIBRARIES"
+ s += <<-EOS.undent
+
+ Setting DYLD_INSERT_LIBRARIES can cause Go builds to fail.
+ Having this set is common if you use this software:
+ http://asepsis.binaryage.com/
+ EOS
+ end
+ s
+ end
+
+ def check_for_symlinked_cellar
+ return unless HOMEBREW_CELLAR.exist?
+ if HOMEBREW_CELLAR.symlink?
+ <<-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 directory 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
+ return unless HOMEBREW_CELLAR.exist?
+ volumes = Volumes.new
+
+ # Find the volumes for the TMP folder & HOMEBREW_CELLAR
+ real_cellar = HOMEBREW_CELLAR.realpath
+
+ tmp = Pathname.new(Dir.mktmpdir("doctor", HOMEBREW_TEMP))
+ real_temp = tmp.realpath.parent
+
+ where_cellar = volumes.which real_cellar
+ where_temp = volumes.which real_temp
+
+ Dir.delete tmp
+
+ unless where_cellar == where_temp then <<-EOS.undent
+ Your Cellar and TEMP directories 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
+ directory on the same volume as your Cellar.
+ EOS
+ end
+ end
+
+ def check_filesystem_case_sensitive
+ volumes = Volumes.new
+ case_sensitive_vols = [HOMEBREW_PREFIX, HOMEBREW_REPOSITORY, HOMEBREW_CELLAR, HOMEBREW_TEMP].select do |dir|
+ # We select the dir as being case-sensitive if either the UPCASED or the
+ # downcased variant is missing.
+ # Of course, on a case-insensitive fs, both exist because the os reports so.
+ # In the rare situation when the user has indeed a downcased and an upcased
+ # dir (e.g. /TMP and /tmp) this check falsely thinks it is case-insensitive
+ # but we don't care beacuse: 1. there is more than one dir checked, 2. the
+ # check is not vital and 3. we would have to touch files otherwise.
+ upcased = Pathname.new(dir.to_s.upcase)
+ downcased = Pathname.new(dir.to_s.downcase)
+ dir.exist? && !(upcased.exist? && downcased.exist?)
+ end.map { |case_sensitive_dir| volumes.get_mounts(case_sensitive_dir) }.uniq
+ return if case_sensitive_vols.empty?
+ <<-EOS.undent
+ The filesystem on #{case_sensitive_vols.join(",")} appears to be case-sensitive.
+ The default OS X filesystem is case-insensitive. Please report any apparent problems.
+ EOS
+ end
+
+ def __check_git_version
+ # https://help.github.com/articles/https-cloning-errors
+ `git --version`.chomp =~ /git version ((?:\d+\.?)+)/
+
+ if $1 && Version.new($1) < Version.new("1.7.10")
+ git_upgrade_cmd = Formula["git"].any_version_installed? ? "upgrade" : "install"
+
+ <<-EOS.undent
+ An outdated version of Git was detected in your PATH.
+ Git 1.7.10 or newer is required to perform checkouts over HTTPS from GitHub.
+ Please upgrade: brew #{git_upgrade_cmd} git
+ EOS
+ end
+ end
+
+ def check_for_git
+ if Utils.git_available?
+ __check_git_version
+ else <<-EOS.undent
+ Git could not be 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 install Git:
+ brew install git
+ EOS
+ end
+ end
+
+ def check_git_newline_settings
+ return unless Utils.git_available?
+
+ autocrlf = `git config --get core.autocrlf`.chomp
+
+ if autocrlf == "true" then <<-EOS.undent
+ Suspicious Git newline settings found.
+
+ The detected Git newline settings will cause checkout problems:
+ core.autocrlf = #{autocrlf}
+
+ If you are not routinely dealing with Windows-based projects,
+ consider removing these by running:
+ `git config --global core.autocrlf input`
+ EOS
+ end
+ end
+
+ def check_git_origin
+ return if !Utils.git_available? || !(HOMEBREW_REPOSITORY/".git").exist?
+
+ origin = Homebrew.git_origin
+
+ if origin.nil? then <<-EOS.undent
+ Missing git origin remote.
+
+ Without a correctly configured origin, Homebrew won't update
+ properly. You can solve this by adding the Homebrew remote:
+ cd #{HOMEBREW_REPOSITORY}
+ git remote add origin https://github.com/Homebrew/homebrew.git
+ EOS
+ elsif origin !~ /(mxcl|Homebrew)\/homebrew(\.git)?$/ then <<-EOS.undent
+ Suspicious git origin remote found.
+
+ With a non-standard origin, Homebrew won't pull updates from
+ the main repository. The current git origin is:
+ #{origin}
+
+ Unless you have compelling reasons, consider setting the
+ origin remote to point at the main repository, located at:
+ https://github.com/Homebrew/homebrew.git
+ EOS
+ end
+ end
+
+ def check_for_autoconf
+ return unless MacOS::Xcode.provides_autotools?
+
+ autoconf = which("autoconf")
+ safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf]
+ unless autoconf.nil? || safe_autoconfs.include?(autoconf.to_s) then <<-EOS.undent
+ An "autoconf" in your path blocks the Xcode-provided version at:
+ #{autoconf}
+
+ This custom autoconf may cause some Homebrew formulae to fail to compile.
+ EOS
+ end
+ end
+
+ def __check_linked_brew(f)
+ f.installed_prefixes.each do |prefix|
+ prefix.find do |src|
+ next if src == prefix
+ dst = HOMEBREW_PREFIX + src.relative_path_from(prefix)
+ return true if dst.symlink? && src == dst.resolved_path
+ end
+ end
+
+ false
+ end
+
+ def check_for_linked_keg_only_brews
+ return unless HOMEBREW_CELLAR.exist?
+
+ linked = Formula.installed.select do |f|
+ f.keg_only? && __check_linked_brew(f)
+ end
+
+ return if linked.empty?
+ inject_file_list linked.map(&:full_name), <<-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 <formula>` 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
+ end
+
+ def check_for_other_frameworks
+ # Other frameworks that are known to cause problems when present
+ %w[expat.framework libexpat.framework libcurl.framework].
+ map { |frmwrk| "/Library/Frameworks/#{frmwrk}" }.
+ select { |frmwrk| File.exist? frmwrk }.
+ map do |frmwrk|
+ <<-EOS.undent
+ #{frmwrk} detected
+ This can be picked up by CMake's build system and likely cause the build to
+ fail. You may need to move this file out of the way to compile CMake.
+ EOS
+ end.join
+ end
+
+ def check_tmpdir
+ tmpdir = ENV["TMPDIR"]
+ "TMPDIR #{tmpdir.inspect} doesn't exist." unless tmpdir.nil? || File.directory?(tmpdir)
+ end
+
+ def check_missing_deps
+ return unless HOMEBREW_CELLAR.exist?
+ missing = Set.new
+ Homebrew::Diagnostic.missing_deps(Formula.installed).each_value do |deps|
+ missing.merge(deps)
+ end
+
+ if missing.any? then <<-EOS.undent
+ Some installed formula are missing dependencies.
+ You should `brew install` the missing dependencies:
+
+ brew install #{missing.sort_by(&:full_name) * " "}
+
+ Run `brew missing` for more details.
+ EOS
+ end
+ end
+
+ def check_git_status
+ return unless Utils.git_available?
+ HOMEBREW_REPOSITORY.cd do
+ unless `git status --untracked-files=all --porcelain -- Library/Homebrew/ 2>/dev/null`.chomp.empty?
+ <<-EOS.undent_________________________________________________________72
+ You have uncommitted modifications to Homebrew
+ If this is a surprise to you, then you should stash these modifications.
+ Stashing returns Homebrew to a pristine state but can be undone
+ should you later need to do so for some reason.
+ cd #{HOMEBREW_LIBRARY} && git stash && git clean -d -f
+ EOS
+ end
+ end
+ end
+
+ def check_for_enthought_python
+ if which "enpkg" then <<-EOS.undent
+ Enthought Python was found in your PATH.
+ This can cause build problems, as this software installs its own
+ copies of iconv and libxml2 into directories that are picked up by
+ other build systems.
+ EOS
+ end
+ end
+
+ def check_for_library_python
+ if File.exist?("/Library/Frameworks/Python.framework") then <<-EOS.undent
+ Python is installed at /Library/Frameworks/Python.framework
+
+ Homebrew only supports building against the System-provided Python or a
+ brewed Python. In particular, Pythons installed to /Library can interfere
+ with other software installs.
+ EOS
+ end
+ end
+
+ def check_for_old_homebrew_share_python_in_path
+ s = ""
+ ["", "3"].map do |suffix|
+ if paths.include?((HOMEBREW_PREFIX/"share/python#{suffix}").to_s)
+ s += "#{HOMEBREW_PREFIX}/share/python#{suffix} is not needed in PATH.\n"
+ end
+ end
+ unless s.empty?
+ s += <<-EOS.undent
+ Formerly homebrew put Python scripts you installed via `pip` or `pip3`
+ (or `easy_install`) into that directory above but now it can be removed
+ from your PATH variable.
+ Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
+ You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
+ (and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages
+ anew with `pip install --upgrade`.
+ EOS
+ end
+ end
+
+ def check_for_bad_python_symlink
+ return unless which "python"
+ `python -V 2>&1` =~ /Python (\d+)\./
+ # This won't be the right warning if we matched nothing at all
+ return if $1.nil?
+ unless $1 == "2" then <<-EOS.undent
+ python is symlinked to python#{$1}
+ This will confuse build scripts and in general lead to subtle breakage.
+ EOS
+ end
+ end
+
+ def check_for_non_prefixed_coreutils
+ gnubin = "#{Formulary.factory("coreutils").prefix}/libexec/gnubin"
+ if paths.include? gnubin then <<-EOS.undent
+ Putting non-prefixed coreutils in your path can cause gmp builds to fail.
+ EOS
+ end
+ end
+
+ def check_for_non_prefixed_findutils
+ default_names = Tab.for_name("findutils").with? "default-names"
+ if default_names then <<-EOS.undent
+ Putting non-prefixed findutils in your path can cause python builds to fail.
+ EOS
+ end
+ end
+
+ def check_for_pydistutils_cfg_in_home
+ if File.exist? "#{ENV["HOME"]}/.pydistutils.cfg" then <<-EOS.undent
+ A .pydistutils.cfg file was found in $HOME, which may cause Python
+ builds to fail. See:
+ https://bugs.python.org/issue6138
+ https://bugs.python.org/issue4655
+ EOS
+ end
+ end
+
+ def check_for_outdated_homebrew
+ return unless Utils.git_available?
+ HOMEBREW_REPOSITORY.cd do
+ if File.directory? ".git"
+ local = `git rev-parse -q --verify refs/remotes/origin/master`.chomp
+ remote = /^([a-f0-9]{40})/.match(`git ls-remote origin refs/heads/master 2>/dev/null`)
+ if remote.nil? || local == remote[0]
+ return
+ end
+ end
+
+ timestamp = if File.directory? ".git"
+ `git log -1 --format="%ct" HEAD`.to_i
+ else
+ HOMEBREW_LIBRARY.mtime.to_i
+ end
+
+ if Time.now.to_i - timestamp > 60 * 60 * 24 then <<-EOS.undent
+ Your Homebrew is outdated.
+ You haven't updated for at least 24 hours. This is a long time in brewland!
+ To update Homebrew, run `brew update`.
+ EOS
+ end
+ end
+ end
+
+ def check_for_unlinked_but_not_keg_only
+ unlinked = Formula.racks.reject do |rack|
+ if !(HOMEBREW_REPOSITORY/"Library/LinkedKegs"/rack.basename).directory?
+ begin
+ Formulary.from_rack(rack).keg_only?
+ rescue FormulaUnavailableError, TapFormulaAmbiguityError, TapFormulaWithOldnameAmbiguityError
+ false
+ end
+ else
+ true
+ end
+ end.map(&:basename)
+
+ return if unlinked.empty?
+ inject_file_list unlinked, <<-EOS.undent
+ You have unlinked kegs in your Cellar
+ Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
+ those kegs to fail to run properly once built. Run `brew link` on these:
+ EOS
+ end
+
+ def check_xcode_license_approved
+ # If the user installs Xcode-only, they have to approve the
+ # license or no "xc*" tool will work.
+ if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success? then <<-EOS.undent
+ You have not agreed to the Xcode license.
+ Builds will fail! Agree to the license by opening Xcode.app or running:
+ sudo xcodebuild -license
+ EOS
+ end
+ end
+
+ def check_for_latest_xquartz
+ return unless MacOS::XQuartz.version
+ return if MacOS::XQuartz.provided_by_apple?
+
+ installed_version = Version.new(MacOS::XQuartz.version)
+ latest_version = Version.new(MacOS::XQuartz.latest_version)
+
+ return if installed_version >= latest_version
+
+ <<-EOS.undent
+ Your XQuartz (#{installed_version}) is outdated
+ Please install XQuartz #{latest_version}:
+ https://xquartz.macosforge.org
+ EOS
+ end
+
+ def check_for_old_env_vars
+ if ENV["HOMEBREW_KEEP_INFO"]
+ <<-EOS.undent
+ `HOMEBREW_KEEP_INFO` is no longer used
+ info files are no longer deleted by default; you may
+ remove this environment variable.
+ EOS
+ end
+ end
+
+ def check_for_pth_support
+ homebrew_site_packages = Language::Python.homebrew_site_packages
+ return unless homebrew_site_packages.directory?
+ return if Language::Python.reads_brewed_pth_files?("python") != false
+ return unless Language::Python.in_sys_path?("python", homebrew_site_packages)
+ user_site_packages = Language::Python.user_site_packages "python"
+ <<-EOS.undent
+ Your default Python does not recognize the Homebrew site-packages
+ directory as a special site-packages directory, which means that .pth
+ files will not be followed. This means you will not be able to import
+ some modules after installing them with Homebrew, like wxpython. To fix
+ this for the current user, you can run:
+
+ mkdir -p #{user_site_packages}
+ echo 'import site; site.addsitedir("#{homebrew_site_packages}")' >> #{user_site_packages}/homebrew.pth
+ EOS
+ end
+
+ def check_for_external_cmd_name_conflict
+ cmds = paths.flat_map { |p| Dir["#{p}/brew-*"] }.uniq
+ cmds = cmds.select { |cmd| File.file?(cmd) && File.executable?(cmd) }
+ cmd_map = {}
+ cmds.each do |cmd|
+ cmd_name = File.basename(cmd, ".rb")
+ cmd_map[cmd_name] ||= []
+ cmd_map[cmd_name] << cmd
+ end
+ cmd_map.reject! { |_cmd_name, cmd_paths| cmd_paths.size == 1 }
+ return if cmd_map.empty?
+ s = "You have external commands with conflicting names.\n"
+ cmd_map.each do |cmd_name, cmd_paths|
+ s += inject_file_list cmd_paths, <<-EOS.undent
+
+ Found command `#{cmd_name}` in following places:
+ EOS
+ end
+ s
+ end
+
+ def all
+ methods.map(&:to_s).grep(/^check_/)
+ end
+ end # end class Checks
+ end
+end
diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb
index ad4e600f6..7e6103a39 100644
--- a/Library/Homebrew/exceptions.rb
+++ b/Library/Homebrew/exceptions.rb
@@ -265,8 +265,8 @@ class BuildError < RuntimeError
puts issues.map { |i| "#{i["title"]} #{i["html_url"]}" }.join("\n")
end
- require "cmd/doctor"
- unsupported_osx = Checks.new.check_for_unsupported_osx
+ require "diagnostic"
+ unsupported_osx = Diagnostic::Checks.new.check_for_unsupported_osx
opoo unsupported_osx if unsupported_osx
end
end
diff --git a/Library/Homebrew/test/test_integration_cmds.rb b/Library/Homebrew/test/test_integration_cmds.rb
index 41cc9ac05..64ce9f76a 100644
--- a/Library/Homebrew/test/test_integration_cmds.rb
+++ b/Library/Homebrew/test/test_integration_cmds.rb
@@ -1,6 +1,7 @@
require "bundler"
require "testing_env"
require "core_formula_repository"
+require "fileutils"
class IntegrationCommandTests < Homebrew::TestCase
def cmd_output(*args)
@@ -152,7 +153,7 @@ class IntegrationCommandTests < Homebrew::TestCase
cmd("readall", "--aliases", "--syntax")
cmd("readall", "Homebrew/homebrew")
ensure
- formula_file.unlink
+ formula_file.unlink unless formula_file.nil?
repo.alias_dir.rmtree
end
@@ -181,4 +182,58 @@ class IntegrationCommandTests < Homebrew::TestCase
ensure
Tap::TAP_DIRECTORY.rmtree
end
+
+ def test_missing
+ url = "file://#{File.expand_path("..", __FILE__)}/tarballs/testball-0.1.tbz"
+ sha256 = "1dfb13ce0f6143fe675b525fc9e168adb2215c5d5965c9f57306bb993170914f"
+ repo = CoreFormulaRepository.new
+ foo_file = repo.formula_dir/"foo.rb"
+ foo_file.write <<-EOS.undent
+ class Foo < Formula
+ url "#{url}"
+ sha256 "#{sha256}"
+ end
+ EOS
+
+ bar_file = repo.formula_dir/"bar.rb"
+ bar_file.write <<-EOS.undent
+ class Bar < Formula
+ url "#{url}"
+ sha256 "#{sha256}"
+ depends_on "foo"
+ end
+ EOS
+
+ cmd("install", "bar")
+ cmd("uninstall", "foo")
+ assert_match "foo", cmd("missing")
+ ensure
+ cmd("uninstall", "--force", "foo", "bar")
+ cmd("cleanup", "--force", "--prune=all")
+ foo_file.unlink unless foo_file.nil?
+ bar_file.unlink unless bar_file.nil?
+ end
+
+ def test_doctor_check_path_for_trailing_slashes
+ assert_match "Some directories in your path end in a slash",
+ cmd_fail("doctor", "check_path_for_trailing_slashes",
+ {"PATH" => ENV["PATH"] + File::PATH_SEPARATOR + "/foo/bar/"})
+ end
+
+ def test_doctor_check_for_anaconda
+ mktmpdir do |path|
+ anaconda = "#{path}/anaconda"
+ python = "#{path}/python"
+ FileUtils.touch anaconda
+ File.open(python, "w") do |file|
+ file.write("#! #{`which bash`}\necho -n '#{python}'\n")
+ end
+ FileUtils.chmod 0777, anaconda
+ FileUtils.chmod 0777, python
+
+ assert_match "Anaconda",
+ cmd_fail("doctor", "check_for_anaconda",
+ {"PATH" => path + File::PATH_SEPARATOR + ENV["PATH"]})
+ end
+ end
end