Files
Allen Houchins 0fda179e92 Fix osascript is-running checks across 15 FMA custom scripts (#49033)
**Related issue:** Resolves #48638, resolves #48225

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops

## Testing

- [x] QA'd all new/changed functionality manually

## Details

Follow-up to #49030 (GitHub Desktop, #48639), which fixed one instance
of this bug. An audit for the raw pattern found **15 more custom FMA
scripts** carrying the same broken check that #42951 fixed in the
generated helpers: gating on the **exit status** of `osascript -e
'application id "..." is running'`. osascript exits 0 whether it prints
`true` or `false`, so a fully-quit app is misclassified as running
whenever the bundle id resolves.

Impact by script:

- **Relaunch after every patch (user-visible — the filed bugs):**
`zoom_install.sh` (#48638) and `google_chrome_install.sh` (#48225) set
`*_WAS_RUNNING=true` unconditionally and reopen the app after
`installer`, even when the user had nothing open.
- **Broken check, no relaunch step (needless quit attempts, misleading
logs):** install scripts for 1Password, Adobe CC, ExpressVPN, Grammarly,
LogiTune, Microsoft Edge, P4V, Slack; uninstall scripts for Adobe CC,
CleanMyMac, GPG Suite, Microsoft Word, P4V. Note `tell application id X
to quit` against a not-running app can briefly launch it to deliver the
quit event, so these aren't purely cosmetic either.

The fix is the same one-line pattern everywhere, style-matched to each
script (`local`/POSIX `[ ]`/top-level variants preserved): capture
osascript output and compare it to `"true"`. No other behavior changed —
this PR deliberately does not touch relaunch methods or console-user
guards.

Regenerated the 13 affected darwin manifests with `go run
./cmd/maintained-apps -slug <slug>`. All diffs are script-ref-only
except `google-chrome/darwin.json`, which also picked up the legitimate
upstream 150.0.7871.115 version bump during regeneration (the daily
ingest cron would publish it tonight regardless). An unrelated
`google-chrome/windows.json` winget bump was excluded.

## Manual QA

Reproduced the bug live on macOS with the shipped Zoom script logic (ref
`05e6a85c`) against a **fully-quit** Zoom (verified `is running` =
`false`, zero processes): the exit-status check set
`ZOOM_WAS_RUNNING=true` and the relaunch step launched Zoom — exactly
the customer report, no background helpers needed. The corrected
output-compare check on the same state correctly reported not running.
Equivalent verification for the shared-helper variant was done against
GitHub Desktop in #49030 (both the fully-quit and running→quit→relaunch
paths).

Verified for all 16 scripts: `bash -n` passes, no `if [!] osascript -e
"application id ...` pattern remains anywhere under
`inputs/homebrew/scripts/`, and every regenerated manifest ref carries
the output-compare check.

Remaining by-design behavior (unchanged): an app running with a dock
icon but no visible window is genuinely running and will still be quit
and relaunched; window-aware relaunching would be a separate
enhancement.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved app detection before install/uninstall steps, reducing
unnecessary quit attempts and making setup flows more reliable.
* Updated several app install/uninstall workflows to better handle
running apps, cleanup, and restart behavior.
* Refined a few app package definitions to point to newer supported
versions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 11:21:28 -05:00

63 lines
2.2 KiB
Bash

#!/bin/bash
quit_application() {
bundle_id="$1"
timeout_duration=10
app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
if [ "$app_running" != "true" ]; then return; fi
console_user="$(stat -f "%Su" /dev/console 2>/dev/null || true)"
if [ "$(id -u)" -eq 0 ] && [ "$console_user" = "root" ]; then
echo "Skipping quit for '$bundle_id'."
return
fi
echo "Quitting '$bundle_id'..."
i=0
while [ "$i" -lt "$timeout_duration" ]; do
osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1 || true
if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
echo "'$bundle_id' quit successfully."
return
fi
i=$((i+1))
sleep 1
done
echo "'$bundle_id' did not quit."
}
[ -n "$INSTALLER_PATH" ] && [ -f "$INSTALLER_PATH" ] || { echo "missing installer"; exit 1; }
quit_application "com.adobe.acc.AdobeCreativeCloud"
# Mount to a known path to avoid space-in-volume issues
MOUNT_POINT="$(mktemp -d "/tmp/adobe_cc.XXXXXX")"
if ! hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" >/dev/null 2>&1; then
rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true
echo "failed to mount dmg"
exit 1
fi
# Find the installer app (handles Install.app or variants like *Install*.app)
INSTALL_APP="$(/usr/bin/find "$MOUNT_POINT" -maxdepth 5 -type d \( -name "Install.app" -o -iname "*Install*.app" \) -print -quit)"
if [ -z "$INSTALL_APP" ] || [ ! -d "$INSTALL_APP" ]; then
hdiutil detach "$MOUNT_POINT" >/dev/null 2>&1 || true
rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true
echo "Install.app not found"
exit 1
fi
# Prefer Contents/MacOS/Install, fall back to first executable in MacOS
BIN="$INSTALL_APP/Contents/MacOS/Install"
if [ ! -x "$BIN" ]; then
BIN="$(/usr/bin/find "$INSTALL_APP/Contents/MacOS" -type f -perm +111 -print -quit 2>/dev/null)"
fi
[ -n "$BIN" ] && [ -x "$BIN" ] || { hdiutil detach "$MOUNT_POINT" >/dev/null 2>&1 || true; rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true; echo "installer binary not found"; exit 1; }
# Try silent, fall back to normal if needed
"$BIN" --mode=silent >/dev/null 2>&1 || "$BIN" >/dev/null 2>&1
hdiutil detach "$MOUNT_POINT" >/dev/null 2>&1 || true
rmdir "$MOUNT_POINT" >/dev/null 2>&1 || true
echo "adobe creative cloud installed"