Improve quarantine support error messages with specific CLT guidance

Co-authored-by: MikeMcQuaid <125011+MikeMcQuaid@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-08-13 14:29:43 +01:00 committed by Mike McQuaid
parent 023bbfdf5c
commit 4ee43fbde1
No known key found for this signature in database
6 changed files with 142 additions and 29 deletions

View File

@ -40,11 +40,12 @@ module Cask
end
private_class_method :swift_target_args
sig { returns(Symbol) }
sig { returns([Symbol, T.nilable(String)]) }
def self.check_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."
:xattr_broken
elsif swift.nil?
@ -55,17 +56,37 @@ module Cask
args: [*swift_target_args, QUARANTINE_SCRIPT],
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
odebug "Quarantine is 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
:swift_runtime_error
end
when 127
# Command not found or execution failed
odebug "Swift execution failed with exit status 127"
:swift_not_executable
else
odebug "Unknown support status"
:unknown
odebug "Swift returned unexpected exit status: #{exit_status}"
:swift_unexpected_error
end
end
[status, check_output]
end
sig { returns(T::Boolean) }
def self.available?
@status ||= check_quarantine_support

View File

@ -1040,21 +1040,6 @@ module Homebrew
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
@non_core_taps ||= Tap.installed.reject(&:core_tap?).reject(&:core_cask_tap?)
end

View File

@ -10,9 +10,6 @@ module OS
requires_ancestor { ::Cask::Quarantine }
sig { returns(Symbol) }
def check_quarantine_support = :linux
sig { returns(T::Boolean) }
def available? = false
end

View File

@ -542,6 +542,52 @@ module OS
We'd welcome a PR to automatically mitigate this instead of just warning about it.
EOS
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

View File

@ -327,6 +327,19 @@ module OS
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) }
def self.update_instructions
return installation_instructions if OS::Mac.version.prerelease?
@ -342,13 +355,15 @@ module OS
<<~EOS
Update them from Software Update in #{software_update_location}.
If that doesn't show you any updates, run:
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
#{reinstall_instructions(reason: "show you any updates")}
EOS
end
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}.
sig { returns(String) }
def self.installation_then_reinstall_instructions
<<~EOS
#{installation_instructions}
#{reinstall_instructions}
EOS
end

View File

@ -143,4 +143,53 @@ RSpec.describe Homebrew::Diagnostic::Checks do
expect(checks.check_pkgconf_macos_sdk_mismatch).to include("brew reinstall pkgconf")
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