From d8afed206fc782a1411f1d9dfb5813caa9167670 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 15 Sep 2019 01:08:04 +0200 Subject: [PATCH] Use AppleScript to check if GUI apps are running. --- .../cask/artifact/abstract_uninstall.rb | 35 +++++++++++++++---- .../artifact/shared_examples/uninstall_zap.rb | 10 +++--- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index 6c5f45982f96a..789306bb99ae5 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -127,7 +127,7 @@ def running_processes(bundle_id) # :quit/:signal must come before :kext so the kext will not be in use by a running process def uninstall_quit(*bundle_ids, command: nil, **_) bundle_ids.each do |bundle_id| - next if running_processes(bundle_id).empty? + next unless running?(bundle_id) unless User.current.gui? opoo "Not logged into a GUI; skipping quitting application ID '#{bundle_id}'." @@ -146,10 +146,10 @@ def uninstall_quit(*bundle_ids, command: nil, **_) Kernel.loop do next unless quit(bundle_id).success? - if running_processes(bundle_id).empty? - puts "Application '#{bundle_id}' quit successfully." - break - end + next if running?(bundle_id) + + puts "Application '#{bundle_id}' quit successfully." + break end end rescue Timeout::Error @@ -159,6 +159,28 @@ def uninstall_quit(*bundle_ids, command: nil, **_) end end + def running?(bundle_id) + script = <<~JAVASCRIPT + 'use strict'; + + ObjC.import('stdlib') + + function run(argv) { + try { + var app = Application(argv[0]) + if (app.running()) { + $.exit(0) + } + } catch (err) { } + + $.exit(1) + } + JAVASCRIPT + + system_command("osascript", args: ["-l", "JavaScript", "-e", script, bundle_id], + print_stderr: true).status.success? + end + def quit(bundle_id) script = <<~JAVASCRIPT 'use strict'; @@ -181,8 +203,7 @@ def quit(bundle_id) JAVASCRIPT system_command "osascript", args: ["-l", "JavaScript", "-e", script, bundle_id], - print_stderr: false, - sudo: true + print_stderr: false end private :quit diff --git a/Library/Homebrew/test/cask/artifact/shared_examples/uninstall_zap.rb b/Library/Homebrew/test/cask/artifact/shared_examples/uninstall_zap.rb index f0e7c56fe18c4..7e57322ffaa48 100644 --- a/Library/Homebrew/test/cask/artifact/shared_examples/uninstall_zap.rb +++ b/Library/Homebrew/test/cask/artifact/shared_examples/uninstall_zap.rb @@ -119,7 +119,7 @@ it "is skipped when the user does not have automation access" do allow(User).to receive(:automation_access?).and_return false allow(User.current).to receive(:gui?).and_return true - allow(subject).to receive(:running_processes).with(bundle_id).and_return([[0, "", bundle_id]]) + allow(subject).to receive(:running?).with(bundle_id).and_return(true) expect { subject.public_send(:"#{artifact_dsl_key}_phase", command: fake_system_command) @@ -128,7 +128,7 @@ it "is skipped when the user is not a GUI user" do allow(User.current).to receive(:gui?).and_return false - allow(subject).to receive(:running_processes).with(bundle_id).and_return([[0, "", bundle_id]]) + allow(subject).to receive(:running?).with(bundle_id).and_return(true) expect { subject.public_send(:"#{artifact_dsl_key}_phase", command: fake_system_command) @@ -139,10 +139,10 @@ allow(User).to receive(:automation_access?).and_return true allow(User.current).to receive(:gui?).and_return true - expect(subject).to receive(:running_processes).with(bundle_id).ordered.and_return([[0, "", bundle_id]]) + expect(subject).to receive(:running?).with(bundle_id).ordered.and_return(true) expect(subject).to receive(:quit).with(bundle_id) .and_return(instance_double("SystemCommand::Result", success?: true)) - expect(subject).to receive(:running_processes).with(bundle_id).ordered.and_return([]) + expect(subject).to receive(:running?).with(bundle_id).ordered.and_return(false) expect { subject.public_send(:"#{artifact_dsl_key}_phase", command: fake_system_command) @@ -153,7 +153,7 @@ allow(User).to receive(:automation_access?).and_return true allow(User.current).to receive(:gui?).and_return true - allow(subject).to receive(:running_processes).with(bundle_id).and_return([[0, "", bundle_id]]) + allow(subject).to receive(:running?).with(bundle_id).and_return(true) allow(subject).to receive(:quit).with(bundle_id) .and_return(instance_double("SystemCommand::Result", success?: false))