Change permission failure from fatal to warning.
This commit is contained in:
parent
40352cb2da
commit
97b9b61061
@ -84,8 +84,7 @@ module Cask
|
|||||||
|
|
||||||
Utils.gain_permissions_mkpath(target.dirname, command: command) unless target.dirname.exist?
|
Utils.gain_permissions_mkpath(target.dirname, command: command) unless target.dirname.exist?
|
||||||
|
|
||||||
if target.directory?
|
if target.directory? && Quarantine.app_management_permissions_granted?(app: target, command: command)
|
||||||
Quarantine.ensure_app_management_permissions_granted(app: target, command: command)
|
|
||||||
if target.writable?
|
if target.writable?
|
||||||
source.children.each { |child| FileUtils.move(child, target/child.basename) }
|
source.children.each { |child| FileUtils.move(child, target/child.basename) }
|
||||||
else
|
else
|
||||||
@ -154,10 +153,11 @@ module Cask
|
|||||||
|
|
||||||
return unless Utils.path_occupied?(target)
|
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.
|
# If an app folder is deleted, macOS considers the app uninstalled and removes some data.
|
||||||
# Remove only the contents to handle this case.
|
# Remove only the contents to handle this case.
|
||||||
Quarantine.ensure_app_management_permissions_granted(app: target, command: command)
|
|
||||||
target.children.each do |child|
|
target.children.each do |child|
|
||||||
if target.writable? && !force
|
if target.writable? && !force
|
||||||
child.rmtree
|
child.rmtree
|
||||||
|
|||||||
@ -192,9 +192,9 @@ module Cask
|
|||||||
# Ensures that Homebrew has permission to update apps on macOS Ventura.
|
# 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.
|
# 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.
|
# 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 }
|
sig { params(app: Pathname, command: T.class_of(SystemCommand)).returns(T::Boolean) }
|
||||||
def self.ensure_app_management_permissions_granted(app:, command:)
|
def self.app_management_permissions_granted?(app:, command:)
|
||||||
return unless app.directory?
|
return true unless app.directory?
|
||||||
|
|
||||||
# To get macOS to prompt the user for permissions, we need to actually attempt to
|
# To get macOS to prompt the user for permissions, we need to actually attempt to
|
||||||
# modify a file in the app.
|
# modify a file in the app.
|
||||||
@ -215,7 +215,7 @@ module Cask
|
|||||||
begin
|
begin
|
||||||
File.write(test_file, "")
|
File.write(test_file, "")
|
||||||
test_file.delete
|
test_file.delete
|
||||||
return
|
return true
|
||||||
rescue Errno::EACCES
|
rescue Errno::EACCES
|
||||||
# Using error handler below
|
# Using error handler below
|
||||||
end
|
end
|
||||||
@ -237,17 +237,19 @@ module Cask
|
|||||||
print_stderr: false,
|
print_stderr: false,
|
||||||
sudo: true,
|
sudo: true,
|
||||||
)
|
)
|
||||||
return
|
return true
|
||||||
rescue ErrorDuringExecution => e
|
rescue ErrorDuringExecution => e
|
||||||
# We only want to handle "touch" errors here; propagate "sudo" errors up
|
# We only want to handle "touch" errors here; propagate "sudo" errors up
|
||||||
raise e unless e.stderr.include?("touch: #{test_file}: Operation not permitted")
|
raise e unless e.stderr.include?("touch: #{test_file}: Operation not permitted")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
odie <<~EOF
|
opoo <<~EOF
|
||||||
Your terminal needs permission to update apps.
|
Your terminal does not have App Management permissions, so Homebrew will delete and reinstall the app.
|
||||||
Go to Settings > Security and Privacy > App Management, or look for a notification saying your terminal was prevented from modifying apps.
|
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
|
EOF
|
||||||
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -329,13 +329,16 @@ describe Cask::Artifact::App, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "when the system blocks modifying apps" do
|
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")
|
target_contents_path = target_path.join("Contents")
|
||||||
|
|
||||||
expect(File).to receive(:write).with(target_path / ".homebrew-write-test",
|
expect(File).to receive(:write).with(target_path / ".homebrew-write-test",
|
||||||
instance_of(String)).and_raise(Errno::EACCES)
|
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
|
expect(target_contents_path).to exist
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -368,7 +371,7 @@ describe Cask::Artifact::App, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "when the system blocks modifying apps" do
|
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")
|
target_contents_path = target_path.join("Contents")
|
||||||
|
|
||||||
allow(command).to receive(:run!).with(any_args).and_call_original
|
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,
|
.and_raise(ErrorDuringExecution.new([], status: 1,
|
||||||
output: [[:stderr, "touch: #{target_path}/.homebrew-write-test: Operation not permitted\n"]], secrets: []))
|
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
|
expect(target_contents_path).to exist
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user