aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/extend/os/mac/diagnostic.rb
blob: f8d6c9e1f960b9ed2429bd0983408437b3f24dda (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
module Homebrew
  module Diagnostic
    class Checks
      def development_tools_checks
        %w[
          check_for_unsupported_osx
          check_for_prerelease_xcode
          check_for_bad_install_name_tool
          check_for_installed_developer_tools
          check_xcode_license_approved
          check_for_osx_gcc_installer
          check_xcode_8_without_clt_on_el_capitan
        ]
      end

      def fatal_development_tools_checks
        if MacOS.prerelease?
          %w[
            check_xcode_up_to_date
            check_clt_up_to_date
          ]
        else
          %w[
          ]
        end
      end

      def check_for_unsupported_osx
        return if ARGV.homebrew_developer?

        who = "We"
        if OS::Mac.prerelease?
          what = "pre-release version"
        elsif OS::Mac.outdated_release?
          who << " (and Apple)"
          what = "old version"
        else
          return
        end

        <<-EOS.undent
          You are using OS X #{MacOS.version}.
          #{who} do not provide support for this #{what}.
          You may encounter build failures or other breakages.
          Please create pull-requests instead of filing issues.
        EOS
      end

      def check_for_prerelease_xcode
        return if ARGV.homebrew_developer?
        # Running a pre-release Xcode on a pre-release OS is expected
        # and likely to cause less problems than a stable Xcode will.
        return if OS::Mac.prerelease?
        return unless MacOS::Xcode.installed?
        return unless MacOS::Xcode.prerelease?

        <<-EOS.undent
          You are using a pre-release version of Xcode.
          You may encounter build failures or other breakages.
          Please create pull-requests instead of filing issues.
        EOS
      end

      def check_xcode_up_to_date
        return unless MacOS::Xcode.installed? && MacOS::Xcode.outdated?

        message = <<-EOS.undent
          Your Xcode (#{MacOS::Xcode.version}) is outdated
          Please update to Xcode #{MacOS::Xcode.latest_version}.
          #{MacOS::Xcode.update_instructions}
        EOS

        if OS::Mac.prerelease?
          current_path = Utils.popen_read("/usr/bin/xcode-select", "-p")
          message += <<-EOS.undent
            If #{MacOS::Xcode.latest_version} is installed, you may need to:
              sudo xcode-select --switch /Applications/Xcode.app
            Current developer directory is:
              #{current_path}
          EOS
        end
        message
      end

      def check_clt_up_to_date
        return unless MacOS::CLT.installed? && MacOS::CLT.outdated?

        <<-EOS.undent
          A newer Command Line Tools release is available.
          #{MacOS::CLT.update_instructions}
        EOS
      end

      def check_xcode_8_without_clt_on_el_capitan
        return unless MacOS::Xcode.without_clt?
        # Scope this to Xcode 8 on El Cap for now
        return unless MacOS.version == :el_capitan && MacOS::Xcode.version >= "8"

        <<-EOS.undent
          You have Xcode 8 installed without the CLT;
          this causes certain builds to fail on OS X 10.11.
          Please install the CLT via:
            sudo xcode-select --install
        EOS
      end

      def check_for_osx_gcc_installer
        return unless MacOS.version < "10.7" || ((MacOS::Xcode.version || "0") > "4.1")
        return unless DevelopmentTools.clang_version == "2.1"

        fix_advice = if MacOS.version >= :mavericks
          "Please run `xcode-select --install` to install the CLT."
        elsif MacOS.version >= :lion
          "Please install the CLT or Xcode #{MacOS::Xcode.latest_version}."
        else
          "Please install Xcode #{MacOS::Xcode.latest_version}."
        end

        <<-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.
          #{fix_advice}
        EOS
      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")
        return unless ((MacOS::Xcode.version || "0") >= "4.3") && uninstaller.exist?

        <<-EOS.undent
          You have leftover files from an older version of Xcode.
          You should delete them using:
            #{uninstaller}
        EOS
      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?
        return if libs.include? "/usr/lib/libxcselect.dylib"

        <<-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

      def check_for_other_package_managers
        ponk = MacOS.macports_or_fink
        return if 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

      def check_ruby_version
        ruby_version = MacOS.version >= "10.9" ? "2.0" : "1.8"
        return if RUBY_VERSION[/\d\.\d/] == ruby_version

        <<-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

      def check_xcode_prefix
        prefix = MacOS::Xcode.prefix
        return if prefix.nil?
        return unless prefix.to_s.include?(" ")

        <<-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

      def check_xcode_prefix_exists
        prefix = MacOS::Xcode.prefix
        return if prefix.nil? || 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

      def check_xcode_select_path
        return if MacOS::CLT.installed?
        return if 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

      def check_for_bad_curl
        return unless MacOS.version <= "10.8"
        return if Formula["curl"].installed?

        <<-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

      def check_for_unsupported_curl_vars
        # Support for SSL_CERT_DIR seemed to be removed in the 10.10.5 update.
        return unless MacOS.version >= :yosemite
        return if ENV["SSL_CERT_DIR"].nil?

        <<-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 #{Utils::Shell.shell_profile} if present.
        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.
        return unless `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success?

        <<-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

      def check_for_latest_xquartz
        return unless MacOS::XQuartz.version
        return if MacOS::XQuartz.provided_by_apple?

        installed_version = Version.create(MacOS::XQuartz.version)
        latest_version = Version.create(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_beta_xquartz
        return unless MacOS::XQuartz.version
        return unless MacOS::XQuartz.version.include? "beta"

        <<-EOS.undent
          The following beta release of XQuartz is installed: #{MacOS::XQuartz.version}

          XQuartz beta releases include address sanitization, and do not work with
          all software; notably, wine will not work with beta releases of XQuartz.
          We recommend only installing stable releases of XQuartz.
        EOS
      end
    end
  end
end