From 62482504a9e584e9ec20ac6895e1485d9c68d94a Mon Sep 17 00:00:00 2001
From: Jack Nagel <jacknagel@gmail.com>
Date: Mon, 9 Jul 2012 14:58:34 -0500
Subject: [PATCH] Split Xcode and CLT methods into separate modules

Signed-off-by: Jack Nagel <jacknagel@gmail.com>
---
 Library/Homebrew/cmd/--config.rb         |  14 +-
 Library/Homebrew/cmd/doctor.rb           |  22 +-
 Library/Homebrew/compat/compatibility.rb |  30 ++-
 Library/Homebrew/extend/ENV.rb           |  18 +-
 Library/Homebrew/formula_installer.rb    |   2 +-
 Library/Homebrew/macos.rb                | 326 ++++++++++++-----------
 6 files changed, 222 insertions(+), 190 deletions(-)

diff --git a/Library/Homebrew/cmd/--config.rb b/Library/Homebrew/cmd/--config.rb
index 4ead67caf3..3b749c5abd 100644
--- a/Library/Homebrew/cmd/--config.rb
+++ b/Library/Homebrew/cmd/--config.rb
@@ -32,17 +32,17 @@ module Homebrew extend self
         else '/Applications/Xcode.app/Contents/Developer'
         end
 
-      guess = '(guessed)' unless MacOS.xcode_installed?
-      prefix = if MacOS.xcode_installed?
-        "=> #{MacOS.xcode_prefix}" unless MacOS.xcode_prefix.to_s == default_prefix
+      guess = '(guessed)' unless MacOS::Xcode.installed?
+      prefix = if MacOS::Xcode.installed?
+        "=> #{MacOS::Xcode.prefix}" unless MacOS::Xcode.prefix.to_s == default_prefix
       end
 
-      [MacOS.xcode_version, guess, prefix].compact.join(' ')
+      [MacOS::Xcode.version, guess, prefix].compact.join(' ')
     end
   end
 
   def describe_clt
-    @describe_clt ||= if MacOS.clt_installed? then MacOS.clt_version else 'N/A' end
+    @describe_clt ||= if MacOS::CLT.installed? then MacOS::CLT.version else 'N/A' end
   end
 
   def head
@@ -92,7 +92,7 @@ module Homebrew extend self
     puts hardware
     puts "OS X: #{MACOS_FULL_VERSION}-#{kernel}"
     puts "Xcode: #{describe_xcode}"
-    puts "CLT: #{describe_clt}" if MacOS.xcode_version.to_f >= 4.3
+    puts "CLT: #{describe_clt}" if MacOS::Xcode.version.to_f >= 4.3
     puts "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby:\n  #{RUBY_VERSION}-#{RUBY_PATCHLEVEL}" if RUBY_VERSION.to_f != 1.8
 
     unless MacOS.compilers_standard?
@@ -119,7 +119,7 @@ module Homebrew extend self
     Xcode: #{describe_xcode}
     EOS
 
-    config_s << "CLT: #{describe_clt}\n" if MacOS.xcode_version.to_f >= 4.3
+    config_s << "CLT: #{describe_clt}\n" if MacOS::Xcode.version.to_f >= 4.3
 
     config_s << <<-EOS.undent
     GCC-4.0: #{gcc_40 ? "build #{gcc_40}" : "N/A"}
diff --git a/Library/Homebrew/cmd/doctor.rb b/Library/Homebrew/cmd/doctor.rb
index 39079ceb79..8e63c09424 100644
--- a/Library/Homebrew/cmd/doctor.rb
+++ b/Library/Homebrew/cmd/doctor.rb
@@ -207,10 +207,10 @@ def check_for_broken_symlinks
 end
 
 def check_for_latest_xcode
-  if not MacOS.xcode_installed?
+  if not MacOS::Xcode.installed?
     # no Xcode, now it depends on the OS X version...
     if MacOS.version >= 10.7 then
-      if not MacOS.clt_installed?
+      if not MacOS::CLT.installed?
         return <<-EOS.undent
           No Xcode version found!
           No compiler found in /usr/bin!
@@ -248,16 +248,16 @@ def check_for_latest_xcode
     Not sure what version of Xcode is the latest for OS X #{MacOS.version}.
     EOS
   end
-  if MacOS.xcode_installed? and MacOS.xcode_version < latest_xcode then <<-EOS.undent
-    You have Xcode-#{MacOS.xcode_version}, which is outdated.
+  if MacOS::Xcode.installed? and MacOS::Xcode.version < latest_xcode then <<-EOS.undent
+    You have Xcode-#{MacOS::Xcode.version}, which is outdated.
     Please install Xcode #{latest_xcode}.
     EOS
   end
 end
 
 def check_cc
-  unless MacOS.clt_installed?
-    if MacOS.xcode_version >= "4.3"
+  unless MacOS::CLT.installed?
+    if MacOS::Xcode.version >= "4.3"
       return <<-EOS.undent
         Experimental support for using Xcode without the "Command Line Tools".
       EOS
@@ -389,7 +389,7 @@ def check_homebrew_prefix
 end
 
 def check_xcode_prefix
-  prefix = MacOS.xcode_prefix
+  prefix = MacOS::Xcode.prefix
   return if prefix.nil?
   if prefix.to_s.match(' ')
     <<-EOS.undent
@@ -401,9 +401,9 @@ end
 
 def check_xcode_select_path
   # with the advent of CLT-only support, we don't need xcode-select
-  return if MacOS.clt_installed?
-  unless File.file? "#{MacOS.xcode_folder}/usr/bin/xcodebuild" and not MacOS.xctools_fucked?
-    path = MacOS.app_with_bundle_id(MacOS::XCODE_4_BUNDLE_ID) || MacOS.app_with_bundle_id(MacOS::XCODE_3_BUNDLE_ID)
+  return if MacOS::CLT.installed?
+  unless File.file? "#{MacOS::Xcode.folder}/usr/bin/xcodebuild" and not MacOS::Xcode.xctools_fucked?
+    path = MacOS.app_with_bundle_id(MacOS::Xcode::V4_BUNDLE_ID) || MacOS.app_with_bundle_id(MacOS::Xcode::V3_BUNDLE_ID)
     path = '/Developer' if path.nil? or not path.directory?
     <<-EOS.undent
       Your Xcode is configured with an invalid path.
@@ -677,7 +677,7 @@ def check_git_newline_settings
 end
 
 def check_for_autoconf
-  return if MacOS.xcode_version >= "4.3"
+  return if MacOS::Xcode.version >= "4.3"
 
   autoconf = which('autoconf')
   safe_autoconfs = %w[/usr/bin/autoconf /Developer/usr/bin/autoconf]
diff --git a/Library/Homebrew/compat/compatibility.rb b/Library/Homebrew/compat/compatibility.rb
index 879042fd41..e14909496c 100644
--- a/Library/Homebrew/compat/compatibility.rb
+++ b/Library/Homebrew/compat/compatibility.rb
@@ -137,7 +137,7 @@ class FailsWithLLVM
     # latest version we have tested against so we will switch to GCC and
     # bump this integer when Xcode 4.3 is released. TODO do that!
     if build.to_i >= 2336
-      if MacOS.xcode_version < "4.2"
+      if MacOS::Xcode.version < "4.2"
         opoo "Formula will not build with LLVM, using GCC"
         ENV.gcc
       else
@@ -156,7 +156,7 @@ class FailsWithLLVM
       that we can update the formula accordingly. Thanks!
       EOS
     puts
-    if MacOS.xcode_version < "4.2"
+    if MacOS::Xcode.version < "4.2"
       puts "If it doesn't work you can: brew install --use-gcc"
     else
       puts "If it doesn't work you can try: brew install --use-clang"
@@ -164,3 +164,29 @@ class FailsWithLLVM
     puts
   end
 end
+
+module MacOS extend self
+  def xcode_folder
+    Xcode.folder
+  end
+
+  def xcode_prefix
+    Xcode.prefix
+  end
+
+  def xcode_installed?
+    Xcode.installed?
+  end
+
+  def xcode_version
+    Xcode.version
+  end
+
+  def clt_installed?
+    CLT.installed?
+  end
+
+  def clt_version?
+    CLT.version
+  end
+end
diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb
index 41ac3e5d69..13900685cf 100644
--- a/Library/Homebrew/extend/ENV.rb
+++ b/Library/Homebrew/extend/ENV.rb
@@ -10,7 +10,7 @@ module HomebrewEnvExtension
     remove_cc_etc
 
     # make any aclocal stuff installed in Homebrew available
-    self['ACLOCAL_PATH'] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS.xcode_version < "4.3"
+    self['ACLOCAL_PATH'] = "#{HOMEBREW_PREFIX}/share/aclocal" if MacOS::Xcode.version < "4.3"
 
     self['MAKEFLAGS'] = "-j#{self.make_jobs}"
 
@@ -47,7 +47,7 @@ module HomebrewEnvExtension
     macosxsdk MacOS.version
 
     # For Xcode 4.3 (*without* the "Command Line Tools for Xcode") compiler and tools inside of Xcode:
-    if not MacOS.clt_installed? and MacOS.xcode_installed? and MacOS.xcode_version >= "4.3"
+    if not MacOS::CLT.installed? and MacOS::Xcode.installed? and MacOS::Xcode.version >= "4.3"
       # Some tools (clang, etc.) are in the xctoolchain dir of Xcode
       append 'PATH', "#{MacOS.xctoolchain_path}/usr/bin", ":" if MacOS.xctoolchain_path
       # Others are now at /Applications/Xcode.app/Contents/Developer/usr/bin
@@ -231,7 +231,7 @@ Please take one of the following actions:
     remove 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
     remove 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
     sdk = MacOS.sdk_path(v)
-    unless sdk.nil? or MacOS.clt_installed?
+    unless sdk.nil? or MacOS::CLT.installed?
       self['SDKROOT'] = nil
       remove 'CPPFLAGS', "-isysroot #{sdk}"
       remove 'CPPFLAGS', "-isystem #{sdk}/usr/include"
@@ -261,7 +261,7 @@ Please take one of the following actions:
     append 'CPPFLAGS', "-isystem #{HOMEBREW_PREFIX}/include"
     prepend 'LDFLAGS', "-L#{HOMEBREW_PREFIX}/lib"
     sdk = MacOS.sdk_path(v)
-    unless sdk.nil? or MacOS.clt_installed?
+    unless sdk.nil? or MacOS::CLT.installed?
       # Extra setup to support Xcode 4.3+ without CLT.
       self['SDKROOT'] = sdk
       # Teach the preprocessor and compiler (some don't respect CPPFLAGS)
@@ -286,16 +286,16 @@ Please take one of the following actions:
 
   def minimal_optimization
     self['CFLAGS'] = self['CXXFLAGS'] = "-Os #{SAFE_CFLAGS_FLAGS}"
-    macosxsdk unless MacOS.clt_installed?
+    macosxsdk unless MacOS::CLT.installed?
   end
   def no_optimization
     self['CFLAGS'] = self['CXXFLAGS'] = SAFE_CFLAGS_FLAGS
-    macosxsdk unless MacOS.clt_installed?
+    macosxsdk unless MacOS::CLT.installed?
   end
 
   # Some configure scripts won't find libxml2 without help
   def libxml2
-    if MacOS.clt_installed?
+    if MacOS::CLT.installed?
       append 'CPPFLAGS', '-I/usr/include/libxml2'
     else
       # Use the includes form the sdk
@@ -319,7 +319,7 @@ Please take one of the following actions:
 
     # We prefer XQuartz if it is installed. Otherwise, we look for Apple's
     # X11. For Xcode-only systems, the headers are found in the SDK.
-    prefix = if MacOS.x11_prefix.to_s == '/opt/X11' or MacOS.clt_installed?
+    prefix = if MacOS.x11_prefix.to_s == '/opt/X11' or MacOS::CLT.installed?
       MacOS.x11_prefix
     else
       MacOS.sdk_path/'usr/X11'
@@ -330,7 +330,7 @@ Please take one of the following actions:
     append 'CMAKE_PREFIX_PATH', prefix, ':'
     append 'CMAKE_INCLUDE_PATH', prefix/'include', ':'
 
-    unless MacOS.clt_installed?
+    unless MacOS::CLT.installed?
       append 'CPPFLAGS', "-I#{prefix}/include/freetype2"
       append 'CFLAGS', "-I#{prefix}/include"
     end
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index 5356f166ec..419a8855cc 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -377,7 +377,7 @@ class FormulaInstaller
 
   def check_m4
     # Newer versions of Xcode don't come with autotools
-    return if MacOS.xcode_version.to_f >= 4.3
+    return if MacOS::Xcode.version.to_f >= 4.3
 
     # If the user has added our path to dirlist, don't complain
     return if File.open("/usr/share/aclocal/dirlist") do |dirlist|
diff --git a/Library/Homebrew/macos.rb b/Library/Homebrew/macos.rb
index d2b6548a14..ea8c33a761 100644
--- a/Library/Homebrew/macos.rb
+++ b/Library/Homebrew/macos.rb
@@ -1,12 +1,6 @@
 module MacOS extend self
 
   MDITEM_BUNDLE_ID_KEY = "kMDItemCFBundleIdentifier"
-  XCODE_4_BUNDLE_ID = "com.apple.dt.Xcode"
-  XCODE_3_BUNDLE_ID = "com.apple.Xcode"
-  XCODE_4_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app")
-  XCODE_3_BUNDLE_PATH = Pathname.new("/Developer/Applications/Xcode.app")
-  CLT_STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
-  CLT_FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
   APPLE_X11_BUNDLE_ID = "org.x.X11"
   XQUARTZ_BUNDLE_ID = "org.macosforge.xquartz.X11"
 
@@ -28,44 +22,6 @@ module MacOS extend self
     end
   end
 
-  # This is true ift he standard UNIX tools are present under /usr. For
-  # Xcode < 4.3, this is the standard location. Otherwise, it means that
-  # the user has installed the "Command Line Tools for Xcode" package.
-  def clt_installed?
-    dev_tools_path == Pathname.new("/usr/bin")
-  end
-
-  def clt_version
-    # Version string (a pretty damn long one) of the CLT package.
-    # Note, that different ways to install the CLTs lead to different
-    # version numbers.
-    @clt_version ||= begin
-      standalone = pkgutil_info(CLT_STANDALONE_PKG_ID)
-      from_xcode = pkgutil_info(CLT_FROM_XCODE_PKG_ID)
-
-      if not standalone.empty?
-        standalone =~ /version: (.*)$/
-        $1
-      elsif not from_xcode.empty?
-        from_xcode =~ /version: (.*)$/
-        $1
-      else
-        nil
-      end
-    end
-  end
-
-  # Locate the "current Xcode folder" via xcode-select. See:
-  # man xcode-select
-  def xcode_folder
-    @xcode_folder ||= `xcode-select -print-path 2>/dev/null`.strip
-  end
-
-  # Xcode 4.3 tools hang if "/" is set
-  def xctools_fucked?
-    xcode_folder == "/"
-  end
-
   def locate tool
     # Don't call tools (cc, make, strip, etc.) directly!
     # Give the name of the binary you look for as a string to this method
@@ -80,7 +36,7 @@ module MacOS extend self
     else
       # Xcrun was provided first with Xcode 4.3 and allows us to proxy
       # tool usage thus avoiding various bugs.
-      p = `/usr/bin/xcrun -find #{tool} 2>/dev/null`.chomp unless xctools_fucked?
+      p = `/usr/bin/xcrun -find #{tool} 2>/dev/null`.chomp unless Xcode.xctools_fucked?
       if !p.nil? and !p.empty? and File.executable? p
         path = Pathname.new p
       else
@@ -111,12 +67,12 @@ module MacOS extend self
     @dev_tools_path ||= if File.exist? "/usr/bin/cc" and File.exist? "/usr/bin/make"
       # probably a safe enough assumption (the unix way)
       Pathname.new "/usr/bin"
-    elsif not xctools_fucked? and system "/usr/bin/xcrun -find make 1>/dev/null 2>&1"
+    elsif not Xcode.xctools_fucked? and system "/usr/bin/xcrun -find make 1>/dev/null 2>&1"
       # Wherever "make" is there are the dev tools.
       Pathname.new(`/usr/bin/xcrun -find make`.chomp).dirname
-    elsif File.exist? "#{xcode_prefix}/usr/bin/make"
+    elsif File.exist? "#{Xcode.prefix}/usr/bin/make"
       # cc stopped existing with Xcode 4.3, there are c89 and c99 options though
-      Pathname.new "#{xcode_prefix}/usr/bin"
+      Pathname.new "#{Xcode.prefix}/usr/bin"
     else
       # Since we are pretty unrelenting in finding Xcode no matter where
       # it hides, we can now throw in the towel.
@@ -128,7 +84,7 @@ module MacOS extend self
   def xctoolchain_path
     # As of Xcode 4.3, some tools are located in the "xctoolchain" directory
     @xctoolchain_path ||= begin
-      path = Pathname.new("#{xcode_prefix}/Toolchains/XcodeDefault.xctoolchain")
+      path = Pathname.new("#{Xcode.prefix}/Toolchains/XcodeDefault.xctoolchain")
       # If only the CLT are installed, all tools will be under dev_tools_path,
       # this path won't exist, and xctoolchain_path will be nil.
       path if path.exist?
@@ -137,14 +93,14 @@ module MacOS extend self
 
   def sdk_path v=version
     @sdk_path ||= begin
-      path = if not xctools_fucked? and File.executable? "#{xcode_folder}/usr/bin/make"
+      path = if not Xcode.xctools_fucked? and File.executable? "#{Xcode.folder}/usr/bin/make"
         `#{locate('xcodebuild')} -version -sdk macosx#{v} Path 2>/dev/null`.strip
       elsif File.directory? '/Developer/SDKs/MacOS#{v}.sdk'
         # the old default (or wild wild west style)
         "/Developer/SDKs/MacOS#{v}.sdk"
-      elsif File.directory? "#{xcode_prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
-        # xcode_prefix is pretty smart, so lets look inside to find the sdk
-        "#{xcode_prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
+      elsif File.directory? "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
+        # Xcode.prefix is pretty smart, so lets look inside to find the sdk
+        "#{Xcode.prefix}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX#{v}.sdk"
       end
 
       Pathname.new(path) unless path.nil? or path.empty? or not File.directory? path
@@ -163,9 +119,9 @@ module MacOS extend self
       when "clang" then :clang
       else
         # guess :(
-        if xcode_version >= "4.3"
+        if Xcode.version >= "4.3"
           :clang
-        elsif xcode_version >= "4.2"
+        elsif Xcode.version >= "4.2"
           :llvm
         else
           :gcc
@@ -173,108 +129,6 @@ module MacOS extend self
     end
   end
 
-  def xcode_prefix
-    @xcode_prefix ||= begin
-      path = Pathname.new xcode_folder
-      if path.absolute? and (path/'usr/bin/make').executable?
-        path
-      elsif File.executable? '/Developer/usr/bin/make'
-        # we do this to support cowboys who insist on installing
-        # only a subset of Xcode
-        Pathname.new '/Developer'
-      elsif (XCODE_4_BUNDLE_PATH/'Contents/Developer/usr/bin/make').executable?
-        # fallback for broken Xcode 4.3 installs
-        XCODE_4_BUNDLE_PATH/'Contents/Developer'
-      else
-        # Ask Spotlight where Xcode is. If the user didn't install the
-        # helper tools and installed Xcode in a non-conventional place, this
-        # is our only option. See: http://superuser.com/questions/390757
-        path = app_with_bundle_id(XCODE_4_BUNDLE_ID) || app_with_bundle_id(XCODE_3_BUNDLE_ID)
-
-        unless path.nil?
-          path += "Contents/Developer"
-          path if (path/'usr/bin/make').executable?
-        end
-      end
-    end
-  end
-
-  def xcode_installed?
-    # Telling us whether the Xcode.app is installed or not.
-    @xcode_installed ||= XCODE_4_BUNDLE_PATH.exist? ||
-      XCODE_3_BUNDLE_PATH.exist? ||
-      app_with_bundle_id(XCODE_4_BUNDLE_ID) ||
-      app_with_bundle_id(XCODE_3_BUNDLE_ID) ||
-      false
-  end
-
-  def xcode_version
-    # may return a version string
-    # that is guessed based on the compiler, so do not
-    # use it in order to check if Xcode is installed.
-    @xcode_version ||= begin
-      return "0" unless MACOS
-
-      # this shortcut makes xcode_version work for people who don't realise you
-      # need to install the CLI tools
-      xcode43build = "#{XCODE_4_BUNDLE_PATH}/Contents/Developer/usr/bin/xcodebuild"
-      if File.file? xcode43build
-        `#{xcode43build} -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
-        return $1 if $1
-      end
-
-      # Xcode 4.3 xc* tools hang indefinately if xcode-select path is set thus
-      raise if xctools_fucked?
-
-      raise unless which "xcodebuild"
-      `xcodebuild -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
-      raise if $1.nil? or not $?.success?
-      $1
-    rescue
-      # For people who's xcode-select is unset, or who have installed
-      # xcode-gcc-installer or whatever other combinations we can try and
-      # supprt. See https://github.com/mxcl/homebrew/wiki/Xcode
-      case llvm_build_version.to_i
-      when 1..2063 then "3.1.0"
-      when 2064..2065 then "3.1.4"
-      when 2366..2325
-        # we have no data for this range so we are guessing
-        "3.2.0"
-      when 2326
-        # also applies to "3.2.3"
-        "3.2.4"
-      when 2327..2333 then "3.2.5"
-      when 2335
-        # this build number applies to 3.2.6, 4.0 and 4.1
-        # https://github.com/mxcl/homebrew/wiki/Xcode
-        "4.0"
-      else
-        case (clang_version.to_f * 10).to_i
-        when 0
-          "dunno"
-        when 1..14
-          "3.2.2"
-        when 15
-          "3.2.4"
-        when 16
-          "3.2.5"
-        when 17..20
-          "4.0"
-        when 21
-          "4.1"
-        when 22..30
-          "4.2"
-        when 31
-          "4.3"
-        when 40
-          "4.4"
-        else
-          "4.4"
-        end
-      end
-    end
-  end
-
   def gcc_40_build_version
     @gcc_40_build_version ||= if locate("gcc-4.0")
       `#{locate("gcc-4.0")} --version` =~ /build (\d{4,})/
@@ -402,7 +256,7 @@ module MacOS extend self
   }
 
   def compilers_standard?
-    xcode = xcode_version
+    xcode = Xcode.version
     # Assume compilers are okay if Xcode version not in hash
     return true unless StandardCompilers.keys.include? xcode
 
@@ -413,8 +267,6 @@ module MacOS extend self
     mdfind(MDITEM_BUNDLE_ID_KEY, id)
   end
 
-  private
-
   def mdfind attribute, id
     path = `mdfind "#{attribute} == '#{id}'"`.strip
     Pathname.new(path) unless path.empty?
@@ -424,3 +276,157 @@ module MacOS extend self
     `pkgutil --pkg-info #{id} 2>/dev/null`.strip
   end
 end
+
+module MacOS::Xcode extend self
+
+  V4_BUNDLE_ID = "com.apple.dt.Xcode"
+  V3_BUNDLE_ID = "com.apple.Xcode"
+  V4_BUNDLE_PATH = Pathname.new("/Applications/Xcode.app")
+  V3_BUNDLE_PATH = Pathname.new("/Developer/Applications/Xcode.app")
+
+  # Locate the "current Xcode folder" via xcode-select. See:
+  # man xcode-select
+  def folder
+    @folder ||= `xcode-select -print-path 2>/dev/null`.strip
+  end
+
+  # Xcode 4.3 tools hang if "/" is set
+  def xctools_fucked?
+    folder == "/"
+  end
+
+  def prefix
+    @prefix ||= begin
+      path = Pathname.new folder
+      if path.absolute? and (path/'usr/bin/make').executable?
+        path
+      elsif File.executable? '/Developer/usr/bin/make'
+        # we do this to support cowboys who insist on installing
+        # only a subset of Xcode
+        Pathname.new '/Developer'
+      elsif (V4_BUNDLE_PATH/'Contents/Developer/usr/bin/make').executable?
+        # fallback for broken Xcode 4.3 installs
+        V4_BUNDLE_PATH/'Contents/Developer'
+      else
+        # Ask Spotlight where Xcode is. If the user didn't install the
+        # helper tools and installed Xcode in a non-conventional place, this
+        # is our only option. See: http://superuser.com/questions/390757
+        path = MacOS.app_with_bundle_id(V4_BUNDLE_ID) ||
+          MacOS.app_with_bundle_id(V3_BUNDLE_ID)
+
+        unless path.nil?
+          path += "Contents/Developer"
+          path if (path/'usr/bin/make').executable?
+        end
+      end
+    end
+  end
+
+  def installed?
+    # Telling us whether the Xcode.app is installed or not.
+    @installed ||= V4_BUNDLE_PATH.exist? ||
+      V3_BUNDLE_PATH.exist? ||
+      MacOS.app_with_bundle_id(V4_BUNDLE_ID) ||
+      MacOS.app_with_bundle_id(V3_BUNDLE_ID) ||
+      false
+  end
+
+  def version
+    # may return a version string
+    # that is guessed based on the compiler, so do not
+    # use it in order to check if Xcode is installed.
+    @version ||= begin
+      return "0" unless MACOS
+
+      # this shortcut makes version work for people who don't realise you
+      # need to install the CLI tools
+      xcode43build = "#{V4_BUNDLE_PATH}/Contents/Developer/usr/bin/xcodebuild"
+      if File.file? xcode43build
+        `#{xcode43build} -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
+        return $1 if $1
+      end
+
+      # Xcode 4.3 xc* tools hang indefinately if xcode-select path is set thus
+      raise if xctools_fucked?
+
+      raise unless which "xcodebuild"
+      `xcodebuild -version 2>/dev/null` =~ /Xcode (\d(\.\d)*)/
+      raise if $1.nil? or not $?.success?
+      $1
+    rescue
+      # For people who's xcode-select is unset, or who have installed
+      # xcode-gcc-installer or whatever other combinations we can try and
+      # supprt. See https://github.com/mxcl/homebrew/wiki/Xcode
+      case llvm_build_version.to_i
+      when 1..2063 then "3.1.0"
+      when 2064..2065 then "3.1.4"
+      when 2366..2325
+        # we have no data for this range so we are guessing
+        "3.2.0"
+      when 2326
+        # also applies to "3.2.3"
+        "3.2.4"
+      when 2327..2333 then "3.2.5"
+      when 2335
+        # this build number applies to 3.2.6, 4.0 and 4.1
+        # https://github.com/mxcl/homebrew/wiki/Xcode
+        "4.0"
+      else
+        case (clang_version.to_f * 10).to_i
+        when 0
+          "dunno"
+        when 1..14
+          "3.2.2"
+        when 15
+          "3.2.4"
+        when 16
+          "3.2.5"
+        when 17..20
+          "4.0"
+        when 21
+          "4.1"
+        when 22..30
+          "4.2"
+        when 31
+          "4.3"
+        when 40
+          "4.4"
+        else
+          "4.4"
+        end
+      end
+    end
+  end
+end
+
+module MacOS::CLT extend self
+  STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo"
+  FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI"
+
+  # This is true ift he standard UNIX tools are present under /usr. For
+  # Xcode < 4.3, this is the standard location. Otherwise, it means that
+  # the user has installed the "Command Line Tools for Xcode" package.
+  def installed?
+    MacOS.dev_tools_path == Pathname.new("/usr/bin")
+  end
+
+  def version
+    # Version string (a pretty damn long one) of the CLT package.
+    # Note, that different ways to install the CLTs lead to different
+    # version numbers.
+    @version ||= begin
+      standalone = MacOS.pkgutil_info(CLT_STANDALONE_PKG_ID)
+      from_xcode = MacOS.pkgutil_info(CLT_FROM_XCODE_PKG_ID)
+
+      if not standalone.empty?
+        standalone =~ /version: (.*)$/
+        $1
+      elsif not from_xcode.empty?
+        from_xcode =~ /version: (.*)$/
+        $1
+      else
+        nil
+      end
+    end
+  end
+end
-- 
GitLab