Merge pull request #20415 from Homebrew/copilot/fix-18540
Improve `brew doctor` quarantine "unknown reason" message with specific CLT guidance
This commit is contained in:
commit
1d25414fee
@ -40,11 +40,12 @@ module Cask
|
|||||||
end
|
end
|
||||||
private_class_method :swift_target_args
|
private_class_method :swift_target_args
|
||||||
|
|
||||||
sig { returns(Symbol) }
|
sig { returns([Symbol, T.nilable(String)]) }
|
||||||
def self.check_quarantine_support
|
def self.check_quarantine_support
|
||||||
odebug "Checking quarantine support"
|
odebug "Checking quarantine support"
|
||||||
|
|
||||||
if xattr.nil? || !system_command(xattr, args: ["-h"], print_stderr: false).success?
|
check_output = nil
|
||||||
|
status = if xattr.nil? || !system_command(xattr, args: ["-h"], print_stderr: false).success?
|
||||||
odebug "There's no working version of `xattr` on this system."
|
odebug "There's no working version of `xattr` on this system."
|
||||||
:xattr_broken
|
:xattr_broken
|
||||||
elsif swift.nil?
|
elsif swift.nil?
|
||||||
@ -55,17 +56,37 @@ module Cask
|
|||||||
args: [*swift_target_args, QUARANTINE_SCRIPT],
|
args: [*swift_target_args, QUARANTINE_SCRIPT],
|
||||||
print_stderr: false)
|
print_stderr: false)
|
||||||
|
|
||||||
case api_check.exit_status
|
exit_status = api_check.exit_status
|
||||||
|
check_output = api_check.merged_output.to_s.strip
|
||||||
|
error_output = api_check.stderr.to_s.strip
|
||||||
|
|
||||||
|
case exit_status
|
||||||
when 2
|
when 2
|
||||||
odebug "Quarantine is available."
|
odebug "Quarantine is available."
|
||||||
:quarantine_available
|
:quarantine_available
|
||||||
|
when 1
|
||||||
|
# Swift script ran but failed (likely due to CLT issues)
|
||||||
|
odebug "Swift quarantine script failed: #{error_output}"
|
||||||
|
if error_output.include?("does not exist") || error_output.include?("No such file")
|
||||||
|
:swift_broken_clt
|
||||||
|
elsif error_output.include?("compiler") || error_output.include?("SDK")
|
||||||
|
:swift_compilation_failed
|
||||||
else
|
else
|
||||||
odebug "Unknown support status"
|
:swift_runtime_error
|
||||||
:unknown
|
end
|
||||||
|
when 127
|
||||||
|
# Command not found or execution failed
|
||||||
|
odebug "Swift execution failed with exit status 127"
|
||||||
|
:swift_not_executable
|
||||||
|
else
|
||||||
|
odebug "Swift returned unexpected exit status: #{exit_status}"
|
||||||
|
:swift_unexpected_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
[status, check_output]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
def self.available?
|
def self.available?
|
||||||
@status ||= check_quarantine_support
|
@status ||= check_quarantine_support
|
||||||
|
|
||||||
|
|||||||
@ -1040,21 +1040,6 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_cask_quarantine_support
|
|
||||||
case Cask::Quarantine.check_quarantine_support
|
|
||||||
when :quarantine_available
|
|
||||||
nil
|
|
||||||
when :xattr_broken
|
|
||||||
"No Cask quarantine support available: there's no working version of `xattr` on this system."
|
|
||||||
when :no_swift
|
|
||||||
"No Cask quarantine support available: there's no available version of `swift` on this system."
|
|
||||||
when :linux
|
|
||||||
"No Cask quarantine support available: not available on Linux."
|
|
||||||
else
|
|
||||||
"No Cask quarantine support available: unknown reason."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def non_core_taps
|
def non_core_taps
|
||||||
@non_core_taps ||= Tap.installed.reject(&:core_tap?).reject(&:core_cask_tap?)
|
@non_core_taps ||= Tap.installed.reject(&:core_tap?).reject(&:core_cask_tap?)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -10,9 +10,6 @@ module OS
|
|||||||
|
|
||||||
requires_ancestor { ::Cask::Quarantine }
|
requires_ancestor { ::Cask::Quarantine }
|
||||||
|
|
||||||
sig { returns(Symbol) }
|
|
||||||
def check_quarantine_support = :linux
|
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def available? = false
|
def available? = false
|
||||||
end
|
end
|
||||||
|
|||||||
@ -542,6 +542,52 @@ module OS
|
|||||||
We'd welcome a PR to automatically mitigate this instead of just warning about it.
|
We'd welcome a PR to automatically mitigate this instead of just warning about it.
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_cask_quarantine_support
|
||||||
|
status, check_output = ::Cask::Quarantine.check_quarantine_support
|
||||||
|
|
||||||
|
case status
|
||||||
|
when :quarantine_available
|
||||||
|
nil
|
||||||
|
when :xattr_broken
|
||||||
|
"No Cask quarantine support available: there's no working version of `xattr` on this system."
|
||||||
|
when :no_swift
|
||||||
|
"No Cask quarantine support available: there's no available version of `swift` on this system."
|
||||||
|
when :swift_broken_clt
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: Swift is not working due to missing Command Line Tools.
|
||||||
|
#{MacOS::CLT.installation_then_reinstall_instructions}
|
||||||
|
EOS
|
||||||
|
when :swift_compilation_failed
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: Swift compilation failed.
|
||||||
|
This is usually due to a broken or incompatible Command Line Tools installation.
|
||||||
|
#{MacOS::CLT.installation_then_reinstall_instructions}
|
||||||
|
EOS
|
||||||
|
when :swift_runtime_error
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: Swift runtime error.
|
||||||
|
Your Command Line Tools installation may be broken or incomplete.
|
||||||
|
#{MacOS::CLT.installation_then_reinstall_instructions}
|
||||||
|
EOS
|
||||||
|
when :swift_not_executable
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: Swift is not executable.
|
||||||
|
Your Command Line Tools installation may be incomplete.
|
||||||
|
#{MacOS::CLT.installation_then_reinstall_instructions}
|
||||||
|
EOS
|
||||||
|
when :swift_unexpected_error
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: Swift returned an unexpected error:
|
||||||
|
#{check_output}
|
||||||
|
EOS
|
||||||
|
else
|
||||||
|
<<~EOS
|
||||||
|
No Cask quarantine support available: unknown reason: #{status.inspect}:
|
||||||
|
#{check_output}
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -327,6 +327,19 @@ module OS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
sig { params(reason: String).returns(String) }
|
||||||
|
def self.reinstall_instructions(reason: "resolve your issues")
|
||||||
|
<<~EOS
|
||||||
|
If that doesn't #{reason}, run:
|
||||||
|
sudo rm -rf /Library/Developer/CommandLineTools
|
||||||
|
sudo xcode-select --install
|
||||||
|
|
||||||
|
Alternatively, manually download them from:
|
||||||
|
#{Formatter.url(MacOS::Xcode::APPLE_DEVELOPER_DOWNLOAD_URL)}.
|
||||||
|
You should download the Command Line Tools for Xcode #{MacOS::Xcode.latest_version}.
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { returns(String) }
|
||||||
def self.update_instructions
|
def self.update_instructions
|
||||||
return installation_instructions if OS::Mac.version.prerelease?
|
return installation_instructions if OS::Mac.version.prerelease?
|
||||||
@ -342,13 +355,15 @@ module OS
|
|||||||
<<~EOS
|
<<~EOS
|
||||||
Update them from Software Update in #{software_update_location}.
|
Update them from Software Update in #{software_update_location}.
|
||||||
|
|
||||||
If that doesn't show you any updates, run:
|
#{reinstall_instructions(reason: "show you any updates")}
|
||||||
sudo rm -rf /Library/Developer/CommandLineTools
|
EOS
|
||||||
sudo xcode-select --install
|
end
|
||||||
|
|
||||||
Alternatively, manually download them from:
|
sig { returns(String) }
|
||||||
#{Formatter.url(MacOS::Xcode::APPLE_DEVELOPER_DOWNLOAD_URL)}.
|
def self.installation_then_reinstall_instructions
|
||||||
You should download the Command Line Tools for Xcode #{MacOS::Xcode.latest_version}.
|
<<~EOS
|
||||||
|
#{installation_instructions}
|
||||||
|
#{reinstall_instructions}
|
||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -143,4 +143,53 @@ RSpec.describe Homebrew::Diagnostic::Checks do
|
|||||||
expect(checks.check_pkgconf_macos_sdk_mismatch).to include("brew reinstall pkgconf")
|
expect(checks.check_pkgconf_macos_sdk_mismatch).to include("brew reinstall pkgconf")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#check_cask_quarantine_support" do
|
||||||
|
it "returns nil when quarantine is available" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:quarantine_available, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when xattr is broken" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:xattr_broken, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("there's no working version of `xattr` on this system")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift is not available" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:no_swift, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("there's no available version of `swift` on this system")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift is broken due to missing CLT" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:swift_broken_clt, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("Swift is not working due to missing Command Line Tools")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift compilation failed" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:swift_compilation_failed, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("Swift compilation failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift runtime error occurs" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:swift_runtime_error, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("Swift runtime error")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift is not executable" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:swift_not_executable, nil])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("Swift is not executable")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns error when swift returns unexpected error" do
|
||||||
|
allow(Cask::Quarantine).to receive(:check_quarantine_support).and_return([:swift_unexpected_error, "whoopsie"])
|
||||||
|
expect(checks.check_cask_quarantine_support)
|
||||||
|
.to match("whoopsie")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user