Change permission failure from fatal to warning.

This commit is contained in:
JBYoshi 2023-05-26 11:13:23 -05:00
parent 40352cb2da
commit 97b9b61061
No known key found for this signature in database
GPG Key ID: AE4430116622D05D
3 changed files with 24 additions and 16 deletions

View File

@ -84,8 +84,7 @@ module Cask
Utils.gain_permissions_mkpath(target.dirname, command: command) unless target.dirname.exist?
if target.directory?
Quarantine.ensure_app_management_permissions_granted(app: target, command: command)
if target.directory? && Quarantine.app_management_permissions_granted?(app: target, command: command)
if target.writable?
source.children.each { |child| FileUtils.move(child, target/child.basename) }
else
@ -154,10 +153,11 @@ module Cask
return unless Utils.path_occupied?(target)
if target.directory? && matching_artifact?(successor)
if target.directory? && matching_artifact?(successor) && Quarantine.app_management_permissions_granted?(
app: target, command: command,
)
# If an app folder is deleted, macOS considers the app uninstalled and removes some data.
# Remove only the contents to handle this case.
Quarantine.ensure_app_management_permissions_granted(app: target, command: command)
target.children.each do |child|
if target.writable? && !force
child.rmtree

View File

@ -192,9 +192,9 @@ module Cask
# Ensures that Homebrew has permission to update apps on macOS Ventura.
# This may be granted either through the App Management toggle or the Full Disk Access toggle.
# The system will only show a prompt for App Management, so we ask the user to grant that.
sig { params(app: Pathname, command: T.class_of(SystemCommand)).void }
def self.ensure_app_management_permissions_granted(app:, command:)
return unless app.directory?
sig { params(app: Pathname, command: T.class_of(SystemCommand)).returns(T::Boolean) }
def self.app_management_permissions_granted?(app:, command:)
return true unless app.directory?
# To get macOS to prompt the user for permissions, we need to actually attempt to
# modify a file in the app.
@ -215,7 +215,7 @@ module Cask
begin
File.write(test_file, "")
test_file.delete
return
return true
rescue Errno::EACCES
# Using error handler below
end
@ -237,17 +237,19 @@ module Cask
print_stderr: false,
sudo: true,
)
return
return true
rescue ErrorDuringExecution => e
# We only want to handle "touch" errors here; propagate "sudo" errors up
raise e unless e.stderr.include?("touch: #{test_file}: Operation not permitted")
end
end
odie <<~EOF
Your terminal needs permission to update apps.
Go to Settings > Security and Privacy > App Management, or look for a notification saying your terminal was prevented from modifying apps.
opoo <<~EOF
Your terminal does not have App Management permissions, so Homebrew will delete and reinstall the app.
This may result in some configurations (like notification settings or location in the Dock/Launchpad) being lost.
To fix this, go to Settings > Security and Privacy > App Management and turn on the switch for your terminal.
EOF
false
end
end
end

View File

@ -329,13 +329,16 @@ describe Cask::Artifact::App, :cask do
end
describe "when the system blocks modifying apps" do
it "does not delete files" do
it "uninstalls and reinstalls the app" do
target_contents_path = target_path.join("Contents")
expect(File).to receive(:write).with(target_path / ".homebrew-write-test",
instance_of(String)).and_raise(Errno::EACCES)
expect { app.uninstall_phase(command: command, force: force, successor: cask) }.to raise_error(SystemExit)
app.uninstall_phase(command: command, force: force, successor: cask)
expect(target_path).not_to exist
app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask)
expect(target_contents_path).to exist
end
end
@ -368,7 +371,7 @@ describe Cask::Artifact::App, :cask do
end
describe "when the system blocks modifying apps" do
it "does not delete files" do
it "uninstalls and reinstalls the app" do
target_contents_path = target_path.join("Contents")
allow(command).to receive(:run!).with(any_args).and_call_original
@ -380,7 +383,10 @@ describe Cask::Artifact::App, :cask do
.and_raise(ErrorDuringExecution.new([], status: 1,
output: [[:stderr, "touch: #{target_path}/.homebrew-write-test: Operation not permitted\n"]], secrets: []))
expect { app.uninstall_phase(command: command, force: force, successor: cask) }.to raise_error(SystemExit)
app.uninstall_phase(command: command, force: force, successor: cask)
expect(target_path).not_to exist
app.install_phase(command: command, adopt: adopt, force: force, predecessor: cask)
expect(target_contents_path).to exist
end
end