| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: false | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  | require "tempfile" | 
					
						
							|  |  |  | require "utils/shell" | 
					
						
							| 
									
										
										
										
											2020-03-13 11:39:27 +11:00
										 |  |  | require "hardware" | 
					
						
							| 
									
										
										
										
											2019-01-01 15:51:32 -08:00
										 |  |  | require "os/linux/glibc" | 
					
						
							|  |  |  | require "os/linux/kernel" | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   module Diagnostic | 
					
						
							|  |  |  |     class Checks | 
					
						
							| 
									
										
										
										
											2021-10-20 11:01:38 +01:00
										 |  |  |       undef fatal_preinstall_checks, supported_configuration_checks | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def fatal_preinstall_checks | 
					
						
							|  |  |  |         %w[
 | 
					
						
							|  |  |  |           check_access_directories | 
					
						
							|  |  |  |           check_linuxbrew_core | 
					
						
							| 
									
										
										
										
											2021-10-21 15:01:58 +01:00
										 |  |  |           check_linuxbrew_bottle_domain | 
					
						
							| 
									
										
										
										
											2021-10-20 11:01:38 +01:00
										 |  |  |         ].freeze | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-21 12:39:44 +00:00
										 |  |  |       def supported_configuration_checks | 
					
						
							|  |  |  |         %w[
 | 
					
						
							|  |  |  |           check_glibc_minimum_version | 
					
						
							|  |  |  |           check_kernel_minimum_version | 
					
						
							| 
									
										
										
										
											2020-03-13 11:39:27 +11:00
										 |  |  |           check_supported_architecture | 
					
						
							| 
									
										
										
										
											2019-01-21 12:39:44 +00:00
										 |  |  |         ].freeze | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |       def check_tmpdir_sticky_bit | 
					
						
							|  |  |  |         message = generic_check_tmpdir_sticky_bit | 
					
						
							|  |  |  |         return if message.nil? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |         message + <<~EOS | 
					
						
							|  |  |  |           If you don't have administrative privileges on this machine, | 
					
						
							|  |  |  |           create a directory and set the HOMEBREW_TEMP environment variable, | 
					
						
							|  |  |  |           for example: | 
					
						
							|  |  |  |             install -d -m 1755 ~/tmp
 | 
					
						
							|  |  |  |             #{Utils::Shell.set_variable_in_profile("HOMEBREW_TEMP", "~/tmp")} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-14 11:51:18 -07:00
										 |  |  |       def check_tmpdir_executable | 
					
						
							|  |  |  |         f = Tempfile.new(%w[homebrew_check_tmpdir_executable .sh], HOMEBREW_TEMP) | 
					
						
							|  |  |  |         f.write "#!/bin/sh\n" | 
					
						
							|  |  |  |         f.chmod 0700
 | 
					
						
							|  |  |  |         f.close | 
					
						
							|  |  |  |         return if system f.path | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 11:54:42 -07:00
										 |  |  |         <<~EOS | 
					
						
							| 
									
										
										
										
											2018-08-14 11:51:18 -07:00
										 |  |  |           The directory #{HOMEBREW_TEMP} does not permit executing | 
					
						
							|  |  |  |           programs. It is likely mounted as "noexec". Please set HOMEBREW_TEMP | 
					
						
							|  |  |  |           in your #{shell_profile} to a different directory, for example: | 
					
						
							|  |  |  |             export HOMEBREW_TEMP=~/tmp
 | 
					
						
							|  |  |  |             echo 'export HOMEBREW_TEMP=~/tmp' >> #{shell_profile} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       ensure | 
					
						
							|  |  |  |         f.unlink | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |       def check_xdg_data_dirs | 
					
						
							| 
									
										
										
										
											2018-09-14 17:02:19 +01:00
										 |  |  |         return if ENV["XDG_DATA_DIRS"].blank? | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |         return if ENV["XDG_DATA_DIRS"].split("/").include?(HOMEBREW_PREFIX/"share") | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |         <<~EOS | 
					
						
							|  |  |  |           Homebrew's share was not found in your XDG_DATA_DIRS but you have | 
					
						
							|  |  |  |           this variable set to include other locations. | 
					
						
							|  |  |  |           Some programs like `vapigen` may not work correctly. | 
					
						
							|  |  |  |           Consider adding Homebrew's share directory to XDG_DATA_DIRS like so: | 
					
						
							| 
									
										
										
										
											2019-02-21 08:39:11 -08:00
										 |  |  |             echo 'export XDG_DATA_DIRS="#{HOMEBREW_PREFIX}/share:$XDG_DATA_DIRS"' >> #{shell_profile} | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-11-02 15:03:54 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def check_umask_not_zero | 
					
						
							|  |  |  |         return unless File.umask.zero? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							|  |  |  |           umask is currently set to 000. Directories created by Homebrew cannot | 
					
						
							| 
									
										
										
										
											2019-04-08 12:47:15 -04:00
										 |  |  |           be world-writable. This issue can be resolved by adding "umask 002" to | 
					
						
							|  |  |  |           your #{shell_profile}: | 
					
						
							| 
									
										
										
										
											2018-11-02 15:03:54 -07:00
										 |  |  |             echo 'umask 002' >> #{shell_profile} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-01-01 15:51:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-13 11:39:27 +11:00
										 |  |  |       def check_supported_architecture | 
					
						
							|  |  |  |         return if Hardware::CPU.arch == :x86_64 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							|  |  |  |           Your CPU architecture (#{Hardware::CPU.arch}) is not supported. We only support | 
					
						
							|  |  |  |           x86_64 CPU architectures. You will be unable to use binary packages (bottles). | 
					
						
							|  |  |  |           #{please_create_pull_requests} | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-01 15:51:32 -08:00
										 |  |  |       def check_glibc_minimum_version | 
					
						
							|  |  |  |         return unless OS::Linux::Glibc.below_minimum_version? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							|  |  |  |           Your system glibc #{OS::Linux::Glibc.system_version} is too old. | 
					
						
							|  |  |  |           We only support glibc #{OS::Linux::Glibc.minimum_version} or later. | 
					
						
							|  |  |  |           #{please_create_pull_requests} | 
					
						
							|  |  |  |           We recommend updating to a newer version via your distribution's | 
					
						
							|  |  |  |           package manager, upgrading your distribution to the latest version, | 
					
						
							|  |  |  |           or changing distributions. | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def check_kernel_minimum_version | 
					
						
							|  |  |  |         return unless OS::Linux::Kernel.below_minimum_version? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							| 
									
										
										
										
											2020-08-17 12:24:53 -07:00
										 |  |  |           Your Linux kernel #{OS.kernel_version} is too old. | 
					
						
							| 
									
										
										
										
											2019-01-01 15:51:32 -08:00
										 |  |  |           We only support kernel #{OS::Linux::Kernel.minimum_version} or later. | 
					
						
							|  |  |  |           You will be unable to use binary packages (bottles). | 
					
						
							|  |  |  |           #{please_create_pull_requests} | 
					
						
							|  |  |  |           We recommend updating to a newer version via your distribution's | 
					
						
							|  |  |  |           package manager, upgrading your distribution to the latest version, | 
					
						
							|  |  |  |           or changing distributions. | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-10-20 11:01:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def check_linuxbrew_core | 
					
						
							| 
									
										
										
										
											2022-03-28 14:59:32 -04:00
										 |  |  |         return if Homebrew::EnvConfig.install_from_api? | 
					
						
							| 
									
										
										
										
											2021-10-20 11:01:38 +01:00
										 |  |  |         return unless CoreTap.instance.linuxbrew_core? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							|  |  |  |           Your Linux Homebrew/core repository is still linuxbrew-core. | 
					
						
							|  |  |  |           You must `brew update` to update to homebrew-core. | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2021-10-21 15:01:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def check_linuxbrew_bottle_domain | 
					
						
							| 
									
										
										
										
											2021-10-21 15:10:17 +01:00
										 |  |  |         return unless Homebrew::EnvConfig.bottle_domain.include?("linuxbrew") | 
					
						
							| 
									
										
										
										
											2021-10-21 15:01:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         <<~EOS | 
					
						
							| 
									
										
										
										
											2021-10-21 15:10:17 +01:00
										 |  |  |           Your HOMEBREW_BOTTLE_DOMAIN still contains "linuxbrew". | 
					
						
							|  |  |  |           You must unset it (or adjust it to not contain linuxbrew | 
					
						
							|  |  |  |           e.g. by using homebrew instead). | 
					
						
							| 
									
										
										
										
											2021-10-21 15:01:58 +01:00
										 |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2022-08-03 20:54:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def check_gcc_dependent_linkage | 
					
						
							|  |  |  |         gcc_dependents = Formula.installed.select do |formula| | 
					
						
							|  |  |  |           next false unless formula.tap&.core_tap? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-26 22:23:02 +08:00
										 |  |  |           # FIXME: This includes formulae that have no runtime dependency on GCC. | 
					
						
							| 
									
										
										
										
											2022-08-03 20:54:16 +08:00
										 |  |  |           formula.recursive_dependencies.map(&:name).include? "gcc" | 
					
						
							|  |  |  |         rescue TapFormulaUnavailableError | 
					
						
							|  |  |  |           false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         return if gcc_dependents.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         badly_linked = gcc_dependents.select do |dependent| | 
					
						
							|  |  |  |           keg = Keg.new(dependent.prefix) | 
					
						
							|  |  |  |           keg.binary_executable_or_library_files.any? do |binary| | 
					
						
							| 
									
										
										
										
											2022-08-26 22:23:02 +08:00
										 |  |  |             paths = binary.rpaths | 
					
						
							| 
									
										
										
										
											2022-08-03 20:54:16 +08:00
										 |  |  |             versioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/\d+$}) } | 
					
						
							|  |  |  |             unversioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/current$}) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             versioned_linkage && !unversioned_linkage | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         return if badly_linked.empty? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inject_file_list badly_linked, <<~EOS | 
					
						
							|  |  |  |           Formulae which link to GCC through a versioned path were found. These formulae | 
					
						
							|  |  |  |           are prone to breaking when GCC is updated. You should `brew reinstall` these formulae: | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |