mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00

This is the pattern we've been adopting for a while and it's a bit cleaner. Let's remove all of the existing usage of the existing pattern to avoid confusion when adopting the new one.
198 lines
6.8 KiB
Ruby
198 lines
6.8 KiB
Ruby
# typed: true # rubocop:disable Sorbet/StrictSigil
|
|
# frozen_string_literal: true
|
|
|
|
require "tempfile"
|
|
require "utils/shell"
|
|
require "hardware"
|
|
require "os/linux/glibc"
|
|
require "os/linux/kernel"
|
|
|
|
module OS
|
|
module Linux
|
|
module Diagnostic
|
|
module Checks
|
|
extend T::Helpers
|
|
|
|
requires_ancestor { Homebrew::Diagnostic::Checks }
|
|
|
|
def fatal_preinstall_checks
|
|
%w[
|
|
check_access_directories
|
|
check_linuxbrew_core
|
|
check_linuxbrew_bottle_domain
|
|
].freeze
|
|
end
|
|
|
|
def supported_configuration_checks
|
|
%w[
|
|
check_glibc_minimum_version
|
|
check_kernel_minimum_version
|
|
check_supported_architecture
|
|
].freeze
|
|
end
|
|
|
|
def check_tmpdir_sticky_bit
|
|
message = super
|
|
return if message.nil?
|
|
|
|
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
|
|
|
|
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 T.must(f.path)
|
|
|
|
<<~EOS
|
|
The directory #{HOMEBREW_TEMP} does not permit executing
|
|
programs. It is likely mounted as "noexec". Please set HOMEBREW_TEMP
|
|
in your #{Utils::Shell.profile} to a different directory, for example:
|
|
export HOMEBREW_TEMP=~/tmp
|
|
echo 'export HOMEBREW_TEMP=~/tmp' >> #{Utils::Shell.profile}
|
|
EOS
|
|
ensure
|
|
f&.unlink
|
|
end
|
|
|
|
def check_umask_not_zero
|
|
return unless File.umask.zero?
|
|
|
|
<<~EOS
|
|
umask is currently set to 000. Directories created by Homebrew cannot
|
|
be world-writable. This issue can be resolved by adding "umask 002" to
|
|
your #{Utils::Shell.profile}:
|
|
echo 'umask 002' >> #{Utils::Shell.profile}
|
|
EOS
|
|
end
|
|
|
|
def check_supported_architecture
|
|
return if ::Hardware::CPU.intel?
|
|
return if Homebrew::EnvConfig.developer? && ENV["HOMEBREW_ARM64_TESTING"].present? && ::Hardware::CPU.arm?
|
|
|
|
<<~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).
|
|
|
|
#{support_tier_message(tier: 2)}
|
|
EOS
|
|
end
|
|
|
|
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.
|
|
|
|
We recommend updating to a newer version via your distribution's
|
|
package manager, upgrading your distribution to the latest version,
|
|
or changing distributions.
|
|
|
|
#{support_tier_message(tier: :unsupported)}
|
|
EOS
|
|
end
|
|
|
|
def check_glibc_version
|
|
return unless OS::Linux::Glibc.below_ci_version?
|
|
|
|
# We want to bypass this check in some tests.
|
|
return if ENV["HOMEBREW_GLIBC_TESTING"]
|
|
|
|
<<~EOS
|
|
Your system glibc #{OS::Linux::Glibc.system_version} is too old.
|
|
We will need to automatically install a newer version.
|
|
|
|
We recommend updating to a newer version via your distribution's
|
|
package manager, upgrading your distribution to the latest version,
|
|
or changing distributions.
|
|
|
|
#{support_tier_message(tier: 2)}
|
|
EOS
|
|
end
|
|
|
|
def check_kernel_minimum_version
|
|
return unless OS::Linux::Kernel.below_minimum_version?
|
|
|
|
<<~EOS
|
|
Your Linux kernel #{OS.kernel_version} is too old.
|
|
We only support kernel #{OS::Linux::Kernel.minimum_version} or later.
|
|
You will be unable to use binary packages (bottles).
|
|
|
|
We recommend updating to a newer version via your distribution's
|
|
package manager, upgrading your distribution to the latest version,
|
|
or changing distributions.
|
|
|
|
#{support_tier_message(tier: 3)}
|
|
EOS
|
|
end
|
|
|
|
def check_linuxbrew_core
|
|
return unless Homebrew::EnvConfig.no_install_from_api?
|
|
return unless CoreTap.instance.linuxbrew_core?
|
|
|
|
<<~EOS
|
|
Your Linux core repository is still linuxbrew-core.
|
|
You must `brew update` to update to homebrew-core.
|
|
EOS
|
|
end
|
|
|
|
def check_linuxbrew_bottle_domain
|
|
return unless Homebrew::EnvConfig.bottle_domain.include?("linuxbrew")
|
|
|
|
<<~EOS
|
|
Your HOMEBREW_BOTTLE_DOMAIN still contains "linuxbrew".
|
|
You must unset it (or adjust it to not contain linuxbrew
|
|
e.g. by using homebrew instead).
|
|
EOS
|
|
end
|
|
|
|
def check_gcc_dependent_linkage
|
|
gcc_dependents = ::Formula.installed.select do |formula|
|
|
next false unless formula.tap&.core_tap?
|
|
|
|
# FIXME: This includes formulae that have no runtime dependency on GCC.
|
|
formula.recursive_dependencies.map(&:name).include? "gcc"
|
|
rescue TapFormulaUnavailableError
|
|
false
|
|
end
|
|
return if gcc_dependents.empty?
|
|
|
|
badly_linked = gcc_dependents.select do |dependent|
|
|
dependent_prefix = dependent.any_installed_prefix
|
|
# Keg.new() may raise an error if it is not a directory.
|
|
# As the result `brew doctor` may display `Error: <keg> is not a directory`
|
|
# instead of proper `doctor` information.
|
|
# There are other checks that test that, we can skip broken kegs.
|
|
next if dependent_prefix.nil? || !dependent_prefix.exist? || !dependent_prefix.directory?
|
|
|
|
keg = Keg.new(dependent_prefix)
|
|
keg.binary_executable_or_library_files.any? do |binary|
|
|
paths = binary.rpaths
|
|
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
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Homebrew::Diagnostic::Checks.prepend(OS::Linux::Diagnostic::Checks)
|