DMG install script use yes and update scripts - #45895
Conversation
Pipe `yes` into `hdiutil attach` to auto-accept DMG license prompts, make attach failures exit, and ignore detach failures. Add a unit test to verify the DMG extract commands. Remove per-app install script files and corresponding install_script_path entries from inputs, and update outputs to reference consolidated install scripts that track/relaunch running apps after installation (updated install_script_ref hashes).
Script Diff Resultsee/maintained-apps/outputs/dbeaver-enterprise/darwin.json=== Install // a96abe07 -> 5a0440c4 ===
--- /tmp/old.xtlX0l 2026-05-20 16:07:33.520609811 +0000
+++ /tmp/new.Muhm1V 2026-05-20 16:07:33.520609811 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.enterprise'
+quit_and_track_application 'com.dbeaver.product.enterprise'
if [ -d "$APPDIR/DBeaverEE.app" ]; then
sudo mv "$APPDIR/DBeaverEE.app" "$TMPDIR/DBeaverEE.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverEE.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.enterprise'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverlite/darwin.json=== Install // c1cba05a -> c72c1bb0 ===
--- /tmp/old.hfxaiw 2026-05-20 16:07:33.574609382 +0000
+++ /tmp/new.4Man1q 2026-05-20 16:07:33.575609374 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.lite'
+quit_and_track_application 'com.dbeaver.product.lite'
if [ -d "$APPDIR/DBeaverLite.app" ]; then
sudo mv "$APPDIR/DBeaverLite.app" "$TMPDIR/DBeaverLite.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverLite.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.lite'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverultimate/darwin.json=== Install // 0a44a77f -> 52243cd3 ===
--- /tmp/old.Y9womQ 2026-05-20 16:07:33.619609024 +0000
+++ /tmp/new.IW5cJL 2026-05-20 16:07:33.619609024 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.ultimate'
+quit_and_track_application 'com.dbeaver.product.ultimate'
if [ -d "$APPDIR/DBeaverUltimate.app" ]; then
sudo mv "$APPDIR/DBeaverUltimate.app" "$TMPDIR/DBeaverUltimate.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverUltimate.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.ultimate'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/darwin.json=== Install // a83831d7 -> 67a65f7d ===
--- /tmp/old.CYry5Z 2026-05-20 16:07:33.669608627 +0000
+++ /tmp/new.KzXsQ2 2026-05-20 16:07:33.669608627 +0000
@@ -2,26 +2,34 @@
# variables
APPDIR="/Applications/"
-TMPDIR=$(dirname "$(realpath $INSTALLER_PATH)")
-
+TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.evernote.Evernote'
+quit_and_track_application 'com.evernote.Evernote'
if [ -d "$APPDIR/Evernote.app" ]; then
sudo mv "$APPDIR/Evernote.app" "$TMPDIR/Evernote.app.bkp"
fi
sudo cp -R "$TMPDIR/Evernote.app" "$APPDIR"
+relaunch_application 'com.evernote.Evernote'
=== Uninstall // 31b95715 -> b7960ac0 ===
--- /tmp/old.CTtFUi 2026-05-20 16:07:33.685608500 +0000
+++ /tmp/new.v8ZBHO 2026-05-20 16:07:33.685608500 +0000
@@ -10,13 +10,15 @@
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
return
fiee/maintained-apps/outputs/omnigraffle/darwin.json=== Install // d2d63787 -> c20e090b ===
--- /tmp/old.1cp2To 2026-05-20 16:07:33.728608158 +0000
+++ /tmp/new.Alf5Ik 2026-05-20 16:07:33.728608158 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.omnigroup.OmniGraffle7'
+quit_and_track_application 'com.omnigroup.OmniGraffle7'
if [ -d "$APPDIR/OmniGraffle.app" ]; then
sudo mv "$APPDIR/OmniGraffle.app" "$TMPDIR/OmniGraffle.app.bkp"
fi
sudo cp -R "$TMPDIR/OmniGraffle.app" "$APPDIR"
+relaunch_application 'com.omnigroup.OmniGraffle7'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/royal-tsx/darwin.json=== Install // 8a40c4cb -> db51aef0 ===
--- /tmp/old.wKrlpn 2026-05-20 16:07:33.775607784 +0000
+++ /tmp/new.uUGPtX 2026-05-20 16:07:33.775607784 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.lemonmojo.RoyalTSX.App'
+quit_and_track_application 'com.lemonmojo.RoyalTSX.App'
if [ -d "$APPDIR/Royal TSX.app" ]; then
sudo mv "$APPDIR/Royal TSX.app" "$TMPDIR/Royal TSX.app.bkp"
fi
sudo cp -R "$TMPDIR/Royal TSX.app" "$APPDIR"
+relaunch_application 'com.lemonmojo.RoyalTSX.App'
=== Uninstall Script (no changes) === |
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
|
Caution Review failedFailed to post review comments WalkthroughThis PR migrates Homebrew app installers from static per-app shell scripts to dynamically generated scripts. The script builder in Go now auto-accepts DMG license prompts by piping 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ee/maintained-apps/outputs/dbeaver-enterprise/darwin.json`:
- Line 19: The quit detection in quit_and_track_application is using pgrep -f
"$bundle_id" which won't reliably find processes by bundle identifier; replace
that check with polling the same AppleScript used earlier (osascript -e
"application id \"$bundle_id\" is running") inside the quit loop to confirm the
app has actually stopped before proceeding, update any template that generates
this manifest so other DMG manifests are regenerated with the same fix, and
ensure the variable bundle_id and quit_success logic remain consistent when
switching to the osascript-based check.
In `@ee/maintained-apps/outputs/evernote/darwin.json`:
- Line 20: The quit_application function currently uses pgrep -f "$bundle_id"
(which can miss apps) to detect quit success; replace that check with the same
osascript-based verification used earlier (e.g., call osascript -e "application
id \"$bundle_id\" is running" inside the loop) so you accurately detect whether
the app is still running, set quit_success only when osascript returns false,
and have quit_application return a non-zero status when the timeout expires;
then in the main sequence, check the return value of quit_application for
'com.evernote.Evernote' and 'com.evernote.EvernoteHelper' and abort the
subsequent sudo rm -rf and trash calls if either quit_application failed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2984c9e8-5d87-4e82-83a8-531a38b63b88
📒 Files selected for processing (20)
ee/maintained-apps/ingesters/homebrew/scripts.goee/maintained-apps/ingesters/homebrew/scripts_test.goee/maintained-apps/inputs/homebrew/dbeaver-enterprise.jsonee/maintained-apps/inputs/homebrew/dbeaverlite.jsonee/maintained-apps/inputs/homebrew/dbeaverultimate.jsonee/maintained-apps/inputs/homebrew/evernote.jsonee/maintained-apps/inputs/homebrew/omnigraffle.jsonee/maintained-apps/inputs/homebrew/royal-tsx.jsonee/maintained-apps/inputs/homebrew/scripts/dbeaver-enterprise-install.shee/maintained-apps/inputs/homebrew/scripts/dbeaverlite-install.shee/maintained-apps/inputs/homebrew/scripts/dbeaverultimate-install.shee/maintained-apps/inputs/homebrew/scripts/evernote-install.shee/maintained-apps/inputs/homebrew/scripts/omnigraffle-install.shee/maintained-apps/inputs/homebrew/scripts/royal-tsx-install.shee/maintained-apps/outputs/dbeaver-enterprise/darwin.jsonee/maintained-apps/outputs/dbeaverlite/darwin.jsonee/maintained-apps/outputs/dbeaverultimate/darwin.jsonee/maintained-apps/outputs/evernote/darwin.jsonee/maintained-apps/outputs/omnigraffle/darwin.jsonee/maintained-apps/outputs/royal-tsx/darwin.json
💤 Files with no reviewable changes (10)
- ee/maintained-apps/inputs/homebrew/scripts/dbeaver-enterprise-install.sh
- ee/maintained-apps/inputs/homebrew/scripts/evernote-install.sh
- ee/maintained-apps/inputs/homebrew/scripts/dbeaverlite-install.sh
- ee/maintained-apps/inputs/homebrew/dbeaverultimate.json
- ee/maintained-apps/inputs/homebrew/scripts/omnigraffle-install.sh
- ee/maintained-apps/inputs/homebrew/evernote.json
- ee/maintained-apps/inputs/homebrew/dbeaver-enterprise.json
- ee/maintained-apps/inputs/homebrew/scripts/royal-tsx-install.sh
- ee/maintained-apps/inputs/homebrew/dbeaverlite.json
- ee/maintained-apps/inputs/homebrew/scripts/dbeaverultimate-install.sh
| "refs": { | ||
| "a320a418": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nsend_signal() {\n local signal=\"$1\"\n local bundle_id=\"$2\"\n local logged_in_user=\"$3\"\n local logged_in_uid pids\n\n if [ -z \"$signal\" ] || [ -z \"$bundle_id\" ] || [ -z \"$logged_in_user\" ]; then\n echo \"Usage: uninstall_signal <signal> <bundle_id> <logged_in_user>\"\n return 1\n fi\n\n logged_in_uid=$(id -u \"$logged_in_user\")\n if [ -z \"$logged_in_uid\" ]; then\n echo \"Could not find UID for user '$logged_in_user'.\"\n return 1\n fi\n\n echo \"Signalling '$signal' to application ID '$bundle_id' for user '$logged_in_user'\"\n\n pids=$(/bin/launchctl asuser \"$logged_in_uid\" sudo -iu \"$logged_in_user\" /bin/launchctl list | awk -v bundle_id=\"$bundle_id\" '\n $3 ~ bundle_id { print $1 }')\n\n if [ -z \"$pids\" ]; then\n echo \"No processes found for bundle ID '$bundle_id'.\"\n return 0\n fi\n\n echo \"Unix PIDs are $pids for processes with bundle identifier $bundle_id\"\n for pid in $pids; do\n if kill -s \"$signal\" \"$pid\" 2>/dev/null; then\n echo \"Successfully signaled PID $pid with signal $signal.\"\n else\n echo \"Failed to kill PID $pid with signal $signal. Check permissions.\"\n fi\n done\n\n sleep 3\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsend_signal 'TERM' 'com.dbeaver.product.enterprise' \"$LOGGED_IN_USER\"\nsudo rm -rf \"$APPDIR/DBeaverEE.app\"\ntrash $LOGGED_IN_USER '~/Library/DBeaverData'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dbeaver.product.enterprise.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.dbeaver.product.enterprise.savedState'\n", | ||
| "a96abe07": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n# extract contents\n# Use 'yes' to automatically accept license agreement when mounting DMG\n# This replicates Homebrew's behavior for DMG files with license agreements\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n\n# copy to the applications folder\nquit_application 'com.dbeaver.product.enterprise'\nif [ -d \"$APPDIR/DBeaverEE.app\" ]; then\n\tsudo mv \"$APPDIR/DBeaverEE.app\" \"$TMPDIR/DBeaverEE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/DBeaverEE.app\" \"$APPDIR\"\n" | ||
| "5a0440c4": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.dbeaver.product.enterprise'\nif [ -d \"$APPDIR/DBeaverEE.app\" ]; then\n\tsudo mv \"$APPDIR/DBeaverEE.app\" \"$TMPDIR/DBeaverEE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/DBeaverEE.app\" \"$APPDIR\"\nrelaunch_application 'com.dbeaver.product.enterprise'\n", |
There was a problem hiding this comment.
Use the real app state to detect quit completion.
pgrep -f "$bundle_id" is checking the wrong identifier type here. For DBeaverEE.app, the process argv typically will not contain com.dbeaver.product.enterprise, so this loop can mark the app as quit immediately after tell ... quit and start copying over a still-running app. Poll application id "$bundle_id" is running again, or match the actual executable name/path, before continuing. Because this is generated output, fixing the shared template and regenerating should cover the other updated DMG manifests too.
Possible fix
- if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ if [[ "$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)" != "true" ]]; then
echo "Application '$bundle_id' quit successfully."
quit_success=true
break
fi
@@
- if [[ "$quit_success" = false ]]; then
- echo "Application '$bundle_id' did not quit."
- fi
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ return 1
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "5a0440c4": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.dbeaver.product.enterprise'\nif [ -d \"$APPDIR/DBeaverEE.app\" ]; then\n\tsudo mv \"$APPDIR/DBeaverEE.app\" \"$TMPDIR/DBeaverEE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/DBeaverEE.app\" \"$APPDIR\"\nrelaunch_application 'com.dbeaver.product.enterprise'\n", | |
| "5a0440c4": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if [[ \"$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\" != \"true\" ]]; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n return 1\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.dbeaver.product.enterprise'\nif [ -d \"$APPDIR/DBeaverEE.app\" ]; then\n\tsudo mv \"$APPDIR/DBeaverEE.app\" \"$TMPDIR/DBeaverEE.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/DBeaverEE.app\" \"$APPDIR\"\nrelaunch_application 'com.dbeaver.product.enterprise'\n", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ee/maintained-apps/outputs/dbeaver-enterprise/darwin.json` at line 19, The
quit detection in quit_and_track_application is using pgrep -f "$bundle_id"
which won't reliably find processes by bundle identifier; replace that check
with polling the same AppleScript used earlier (osascript -e "application id
\"$bundle_id\" is running") inside the quit loop to confirm the app has actually
stopped before proceeding, update any template that generates this manifest so
other DMG manifests are regenerated with the same fix, and ensure the variable
bundle_id and quit_success logic remain consistent when switching to the
osascript-based check.
| "31b95715": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'com.evernote.Evernote'\nquit_application 'com.evernote.EvernoteHelper'\nsudo rm -rf \"$APPDIR/Evernote.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Caches/evernote-client-updater'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.EvernoteHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Cookies/com.evernote.Evernote.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Logs/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.Evernote.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.EvernoteHelper.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.evernote.Evernote.savedState'\n", | ||
| "a83831d7": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath $INSTALLER_PATH)\")\n\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n# extract contents\n# Use 'yes' to automatically accept license agreement when mounting DMG\n# This replicates Homebrew's behavior for DMG files with license agreements\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n\n# copy to the applications folder\nquit_application 'com.evernote.Evernote'\nif [ -d \"$APPDIR/Evernote.app\" ]; then\n\tsudo mv \"$APPDIR/Evernote.app\" \"$TMPDIR/Evernote.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Evernote.app\" \"$APPDIR\"\n\n" | ||
| "67a65f7d": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.evernote.Evernote'\nif [ -d \"$APPDIR/Evernote.app\" ]; then\n\tsudo mv \"$APPDIR/Evernote.app\" \"$TMPDIR/Evernote.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Evernote.app\" \"$APPDIR\"\nrelaunch_application 'com.evernote.Evernote'\n", | ||
| "b7960ac0": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'com.evernote.Evernote'\nquit_application 'com.evernote.EvernoteHelper'\nsudo rm -rf \"$APPDIR/Evernote.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Caches/evernote-client-updater'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.EvernoteHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Cookies/com.evernote.Evernote.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Logs/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.Evernote.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.EvernoteHelper.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.evernote.Evernote.savedState'\n" |
There was a problem hiding this comment.
Don't start uninstall cleanup from a false quit-success signal.
quit_application uses pgrep -f "$bundle_id" to decide whether Evernote has exited, but the running process normally won't expose com.evernote.Evernote or com.evernote.EvernoteHelper in its argv. That means the function can report success too early and the subsequent rm -rf / trash steps can race with a still-running app. Re-check the app's actual running state and stop the uninstall if the timeout expires.
Possible fix
- if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+ if [[ "$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)" != "true" ]]; then
echo "Application '$bundle_id' quit successfully."
quit_success=true
break
fi
@@
- if [[ "$quit_success" = false ]]; then
- echo "Application '$bundle_id' did not quit."
- fi
+ if [[ "$quit_success" = false ]]; then
+ echo "Application '$bundle_id' did not quit."
+ return 1
+ fi
@@
-quit_application 'com.evernote.Evernote'
-quit_application 'com.evernote.EvernoteHelper'
+quit_application 'com.evernote.Evernote' || exit 1
+quit_application 'com.evernote.EvernoteHelper' || exit 1📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "b7960ac0": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'com.evernote.Evernote'\nquit_application 'com.evernote.EvernoteHelper'\nsudo rm -rf \"$APPDIR/Evernote.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Caches/evernote-client-updater'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.EvernoteHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Cookies/com.evernote.Evernote.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Logs/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.Evernote.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.EvernoteHelper.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.evernote.Evernote.savedState'\n" | |
| "b7960ac0": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if [[ \"$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\" != \"true\" ]]; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n return 1\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'com.evernote.Evernote' || exit 1\nquit_application 'com.evernote.EvernoteHelper' || exit 1\nsudo rm -rf \"$APPDIR/Evernote.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Caches/evernote-client-updater'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.evernote.EvernoteHelper'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.evernote.Evernote'\ntrash $LOGGED_IN_USER '~/Library/Cookies/com.evernote.Evernote.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Logs/Evernote'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.Evernote.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.evernote.EvernoteHelper.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.evernote.Evernote.savedState'\n" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ee/maintained-apps/outputs/evernote/darwin.json` at line 20, The
quit_application function currently uses pgrep -f "$bundle_id" (which can miss
apps) to detect quit success; replace that check with the same osascript-based
verification used earlier (e.g., call osascript -e "application id
\"$bundle_id\" is running" inside the loop) so you accurately detect whether the
app is still running, set quit_success only when osascript returns false, and
have quit_application return a non-zero status when the timeout expires; then in
the main sequence, check the return value of quit_application for
'com.evernote.Evernote' and 'com.evernote.EvernoteHelper' and abort the
subsequent sudo rm -rf and trash calls if either quit_application failed.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #45895 +/- ##
==========================================
+ Coverage 66.83% 66.86% +0.02%
==========================================
Files 2755 2756 +1
Lines 220198 220724 +526
Branches 10916 10916
==========================================
+ Hits 147170 147582 +412
- Misses 59734 59804 +70
- Partials 13294 13338 +44
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the Homebrew DMG install script generation to auto-accept DMG license prompts and improve install robustness, while consolidating per-app install scripts and refreshing generated app outputs.
Changes:
- Update DMG extraction to pipe
yesintohdiutil attach, fail fast on attach errors, and ignore detach failures. - Remove per-app
install_script_pathinputs and delete the corresponding script files. - Regenerate app outputs to reference updated consolidated install scripts (including quit/track/relaunch behavior) and update Evernote metadata.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ee/maintained-apps/outputs/royal-tsx/darwin.json | Update generated install script ref to consolidated quit/track/relaunch + DMG attach behavior. |
| ee/maintained-apps/outputs/omnigraffle/darwin.json | Update generated install script ref to consolidated quit/track/relaunch + DMG attach behavior. |
| ee/maintained-apps/outputs/evernote/darwin.json | Update generated install/uninstall script refs; also changes Evernote version/URL/checksum metadata. |
| ee/maintained-apps/outputs/dbeaverultimate/darwin.json | Update generated install script ref to consolidated quit/track/relaunch + DMG attach behavior. |
| ee/maintained-apps/outputs/dbeaverlite/darwin.json | Update generated install script ref to consolidated quit/track/relaunch + DMG attach behavior. |
| ee/maintained-apps/outputs/dbeaver-enterprise/darwin.json | Update generated install script ref to consolidated quit/track/relaunch + DMG attach behavior. |
| ee/maintained-apps/inputs/homebrew/scripts/royal-tsx-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/scripts/omnigraffle-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/scripts/evernote-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/scripts/dbeaverultimate-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/scripts/dbeaverlite-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/scripts/dbeaver-enterprise-install.sh | Remove per-app install script file (now consolidated/generated). |
| ee/maintained-apps/inputs/homebrew/royal-tsx.json | Drop install_script_path input field. |
| ee/maintained-apps/inputs/homebrew/omnigraffle.json | Drop install_script_path input field. |
| ee/maintained-apps/inputs/homebrew/evernote.json | Drop install_script_path input field (keeps frozen). |
| ee/maintained-apps/inputs/homebrew/dbeaverultimate.json | Drop install_script_path input field. |
| ee/maintained-apps/inputs/homebrew/dbeaverlite.json | Drop install_script_path input field. |
| ee/maintained-apps/inputs/homebrew/dbeaver-enterprise.json | Drop install_script_path input field. |
| ee/maintained-apps/ingesters/homebrew/scripts_test.go | Add unit test asserting DMG extract uses `yes |
| ee/maintained-apps/ingesters/homebrew/scripts.go | Implement yes piping + attach fail-fast + detach ignore in DMG extraction builder. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| s.Write(`MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX) | ||
| hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" | ||
| yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1 | ||
| sudo cp -R "$MOUNT_POINT"/* "$TMPDIR" | ||
| hdiutil detach "$MOUNT_POINT"`) | ||
| hdiutil detach "$MOUNT_POINT" || true`) |
| "version": "10.105.4", | ||
| "queries": { | ||
| "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.evernote.Evernote';" | ||
| "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.evernote.Evernote';", | ||
| "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.evernote.Evernote' AND version_compare(bundle_short_version, '10.105.4') < 0);" | ||
| }, | ||
| "installer_url": "https://mac.desktop.evernote.com/builds/Evernote-latest.dmg", | ||
| "install_script_ref": "a83831d7", | ||
| "uninstall_script_ref": "31b95715", | ||
| "sha256": "no_check", | ||
| "installer_url": "https://mac.desktop.evernote.com/builds/Evernote-10.105.4-mac-ddl-stage-20240910164757-a2e60a8d876a07eded5d212fa56ba45214114ad0.dmg", | ||
| "install_script_ref": "67a65f7d", | ||
| "uninstall_script_ref": "b7960ac0", | ||
| "sha256": "98d1f6d52718a0b05222b7cdce14a3755ece619edf0a1b8557af75afbfe2cd73", |
| "refs": { | ||
| "81081b86": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/OmniGraffle.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.omnigroup.OmniGraffle7'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CloudDocs/session/containers/iCloud.com.omnigroup.OmniGraffle'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CloudDocs/session/containers/iCloud.com.omnigroup.OmniGraffle.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.omnigroup.omnigraffle7.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.omnigroup.OmniGraffle7'\ntrash $LOGGED_IN_USER '~/Library/Mobile Documents/iCloud~com~omnigroup~OmniGraffle'\n", | ||
| "d2d63787": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n# extract contents\n# Use 'yes' to automatically accept license agreement when mounting DMG\n# This replicates Homebrew's behavior for DMG files with license agreements\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n\n# copy to the applications folder\nquit_application 'com.omnigroup.OmniGraffle7'\nif [ -d \"$APPDIR/OmniGraffle.app\" ]; then\n\tsudo mv \"$APPDIR/OmniGraffle.app\" \"$TMPDIR/OmniGraffle.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/OmniGraffle.app\" \"$APPDIR\"\n\n" | ||
| "c20e090b": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.omnigroup.OmniGraffle7'\nif [ -d \"$APPDIR/OmniGraffle.app\" ]; then\n\tsudo mv \"$APPDIR/OmniGraffle.app\" \"$TMPDIR/OmniGraffle.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/OmniGraffle.app\" \"$APPDIR\"\nrelaunch_application 'com.omnigroup.OmniGraffle7'\n" |
| "refs": { | ||
| "81081b86": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/OmniGraffle.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.omnigroup.OmniGraffle7'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CloudDocs/session/containers/iCloud.com.omnigroup.OmniGraffle'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CloudDocs/session/containers/iCloud.com.omnigroup.OmniGraffle.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.omnigroup.omnigraffle7.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.omnigroup.OmniGraffle7'\ntrash $LOGGED_IN_USER '~/Library/Mobile Documents/iCloud~com~omnigroup~OmniGraffle'\n", | ||
| "d2d63787": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n# extract contents\n# Use 'yes' to automatically accept license agreement when mounting DMG\n# This replicates Homebrew's behavior for DMG files with license agreements\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n\n# copy to the applications folder\nquit_application 'com.omnigroup.OmniGraffle7'\nif [ -d \"$APPDIR/OmniGraffle.app\" ]; then\n\tsudo mv \"$APPDIR/OmniGraffle.app\" \"$TMPDIR/OmniGraffle.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/OmniGraffle.app\" \"$APPDIR\"\n\n" | ||
| "c20e090b": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.omnigroup.OmniGraffle7'\nif [ -d \"$APPDIR/OmniGraffle.app\" ]; then\n\tsudo mv \"$APPDIR/OmniGraffle.app\" \"$TMPDIR/OmniGraffle.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/OmniGraffle.app\" \"$APPDIR\"\nrelaunch_application 'com.omnigroup.OmniGraffle7'\n" |
Script Diff Resultsee/maintained-apps/outputs/dbeaver-enterprise/darwin.json=== Install // a96abe07 -> 5a0440c4 ===
--- /tmp/old.L9g3JD 2026-05-22 03:09:15.988505657 +0000
+++ /tmp/new.hwHbxm 2026-05-22 03:09:15.988505657 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.enterprise'
+quit_and_track_application 'com.dbeaver.product.enterprise'
if [ -d "$APPDIR/DBeaverEE.app" ]; then
sudo mv "$APPDIR/DBeaverEE.app" "$TMPDIR/DBeaverEE.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverEE.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.enterprise'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverlite/darwin.json=== Install // c1cba05a -> c72c1bb0 ===
--- /tmp/old.0AEV7T 2026-05-22 03:09:16.034506922 +0000
+++ /tmp/new.gyUqGY 2026-05-22 03:09:16.034506922 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.lite'
+quit_and_track_application 'com.dbeaver.product.lite'
if [ -d "$APPDIR/DBeaverLite.app" ]; then
sudo mv "$APPDIR/DBeaverLite.app" "$TMPDIR/DBeaverLite.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverLite.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.lite'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverultimate/darwin.json=== Install // 0a44a77f -> 52243cd3 ===
--- /tmp/old.jXXWzS 2026-05-22 03:09:16.078508132 +0000
+++ /tmp/new.ESR4df 2026-05-22 03:09:16.079508159 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.ultimate'
+quit_and_track_application 'com.dbeaver.product.ultimate'
if [ -d "$APPDIR/DBeaverUltimate.app" ]; then
sudo mv "$APPDIR/DBeaverUltimate.app" "$TMPDIR/DBeaverUltimate.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverUltimate.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.ultimate'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/darwin.json=== Install // a83831d7 -> 67a65f7d ===
--- /tmp/old.1HGTpn 2026-05-22 03:09:16.121509314 +0000
+++ /tmp/new.a4vpg4 2026-05-22 03:09:16.121509314 +0000
@@ -2,26 +2,34 @@
# variables
APPDIR="/Applications/"
-TMPDIR=$(dirname "$(realpath $INSTALLER_PATH)")
-
+TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.evernote.Evernote'
+quit_and_track_application 'com.evernote.Evernote'
if [ -d "$APPDIR/Evernote.app" ]; then
sudo mv "$APPDIR/Evernote.app" "$TMPDIR/Evernote.app.bkp"
fi
sudo cp -R "$TMPDIR/Evernote.app" "$APPDIR"
+relaunch_application 'com.evernote.Evernote'
=== Uninstall // 31b95715 -> b7960ac0 ===
--- /tmp/old.ryUC38 2026-05-22 03:09:16.135509699 +0000
+++ /tmp/new.r37Xwu 2026-05-22 03:09:16.135509699 +0000
@@ -10,13 +10,15 @@
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
return
fiee/maintained-apps/outputs/omnigraffle/darwin.json=== Install // d2d63787 -> c20e090b ===
--- /tmp/old.VYcxg2 2026-05-22 03:09:16.171510690 +0000
+++ /tmp/new.ZwxJqZ 2026-05-22 03:09:16.171510690 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.omnigroup.OmniGraffle7'
+quit_and_track_application 'com.omnigroup.OmniGraffle7'
if [ -d "$APPDIR/OmniGraffle.app" ]; then
sudo mv "$APPDIR/OmniGraffle.app" "$TMPDIR/OmniGraffle.app.bkp"
fi
sudo cp -R "$TMPDIR/OmniGraffle.app" "$APPDIR"
+relaunch_application 'com.omnigroup.OmniGraffle7'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/royal-tsx/darwin.json=== Install // 8a40c4cb -> db51aef0 ===
--- /tmp/old.WBcQnr 2026-05-22 03:09:16.208511707 +0000
+++ /tmp/new.fN2mhQ 2026-05-22 03:09:16.208511707 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.lemonmojo.RoyalTSX.App'
+quit_and_track_application 'com.lemonmojo.RoyalTSX.App'
if [ -d "$APPDIR/Royal TSX.app" ]; then
sudo mv "$APPDIR/Royal TSX.app" "$TMPDIR/Royal TSX.app.bkp"
fi
sudo cp -R "$TMPDIR/Royal TSX.app" "$APPDIR"
+relaunch_application 'com.lemonmojo.RoyalTSX.App'
=== Uninstall Script (no changes) === |
Script Diff Resultsee/maintained-apps/outputs/dbeaver-enterprise/darwin.json=== Install // a96abe07 -> 5a0440c4 ===
--- /tmp/old.GgSIVX 2026-05-26 15:48:13.097398375 +0000
+++ /tmp/new.QSemJH 2026-05-26 15:48:13.097398375 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.enterprise'
+quit_and_track_application 'com.dbeaver.product.enterprise'
if [ -d "$APPDIR/DBeaverEE.app" ]; then
sudo mv "$APPDIR/DBeaverEE.app" "$TMPDIR/DBeaverEE.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverEE.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.enterprise'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverlite/darwin.json=== Install // c1cba05a -> c72c1bb0 ===
--- /tmp/old.M7QZa7 2026-05-26 15:48:13.152398889 +0000
+++ /tmp/new.kBvrXk 2026-05-26 15:48:13.152398889 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.lite'
+quit_and_track_application 'com.dbeaver.product.lite'
if [ -d "$APPDIR/DBeaverLite.app" ]; then
sudo mv "$APPDIR/DBeaverLite.app" "$TMPDIR/DBeaverLite.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverLite.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.lite'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverultimate/darwin.json=== Install // 0a44a77f -> 52243cd3 ===
--- /tmp/old.RZjt5m 2026-05-26 15:48:13.204399376 +0000
+++ /tmp/new.fvOaSM 2026-05-26 15:48:13.204399376 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.ultimate'
+quit_and_track_application 'com.dbeaver.product.ultimate'
if [ -d "$APPDIR/DBeaverUltimate.app" ]; then
sudo mv "$APPDIR/DBeaverUltimate.app" "$TMPDIR/DBeaverUltimate.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverUltimate.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.ultimate'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/darwin.json=== Install // a83831d7 -> 67a65f7d ===
--- /tmp/old.BfhP8M 2026-05-26 15:48:13.261399909 +0000
+++ /tmp/new.BghH7K 2026-05-26 15:48:13.261399909 +0000
@@ -2,26 +2,34 @@
# variables
APPDIR="/Applications/"
-TMPDIR=$(dirname "$(realpath $INSTALLER_PATH)")
-
+TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.evernote.Evernote'
+quit_and_track_application 'com.evernote.Evernote'
if [ -d "$APPDIR/Evernote.app" ]; then
sudo mv "$APPDIR/Evernote.app" "$TMPDIR/Evernote.app.bkp"
fi
sudo cp -R "$TMPDIR/Evernote.app" "$APPDIR"
+relaunch_application 'com.evernote.Evernote'
=== Uninstall // 31b95715 -> b7960ac0 ===
--- /tmp/old.U3iE7b 2026-05-26 15:48:13.278400068 +0000
+++ /tmp/new.O8PVc8 2026-05-26 15:48:13.278400068 +0000
@@ -10,13 +10,15 @@
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
return
fiee/maintained-apps/outputs/omnigraffle/darwin.json=== Install // d2d63787 -> c20e090b ===
--- /tmp/old.hj7tn7 2026-05-26 15:48:13.320400461 +0000
+++ /tmp/new.u8aIyK 2026-05-26 15:48:13.320400461 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.omnigroup.OmniGraffle7'
+quit_and_track_application 'com.omnigroup.OmniGraffle7'
if [ -d "$APPDIR/OmniGraffle.app" ]; then
sudo mv "$APPDIR/OmniGraffle.app" "$TMPDIR/OmniGraffle.app.bkp"
fi
sudo cp -R "$TMPDIR/OmniGraffle.app" "$APPDIR"
+relaunch_application 'com.omnigroup.OmniGraffle7'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/royal-tsx/darwin.json=== Install // 8a40c4cb -> db51aef0 ===
--- /tmp/old.BHKYwC 2026-05-26 15:48:13.363400863 +0000
+++ /tmp/new.MKOnom 2026-05-26 15:48:13.363400863 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.lemonmojo.RoyalTSX.App'
+quit_and_track_application 'com.lemonmojo.RoyalTSX.App'
if [ -d "$APPDIR/Royal TSX.app" ]; then
sudo mv "$APPDIR/Royal TSX.app" "$TMPDIR/Royal TSX.app.bkp"
fi
sudo cp -R "$TMPDIR/Royal TSX.app" "$APPDIR"
+relaunch_application 'com.lemonmojo.RoyalTSX.App'
=== Uninstall Script (no changes) === |
Script Diff Resultsee/maintained-apps/outputs/dbeaver-enterprise/darwin.json=== Install // a96abe07 -> 5a0440c4 ===
--- /tmp/old.oCH6wu 2026-05-26 17:45:03.318143914 +0000
+++ /tmp/new.04uPoD 2026-05-26 17:45:03.318143914 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.enterprise'
+quit_and_track_application 'com.dbeaver.product.enterprise'
if [ -d "$APPDIR/DBeaverEE.app" ]; then
sudo mv "$APPDIR/DBeaverEE.app" "$TMPDIR/DBeaverEE.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverEE.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.enterprise'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverlite/darwin.json=== Install // c1cba05a -> c72c1bb0 ===
--- /tmp/old.jUiarW 2026-05-26 17:45:03.414144242 +0000
+++ /tmp/new.1HxJs3 2026-05-26 17:45:03.414144242 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.lite'
+quit_and_track_application 'com.dbeaver.product.lite'
if [ -d "$APPDIR/DBeaverLite.app" ]; then
sudo mv "$APPDIR/DBeaverLite.app" "$TMPDIR/DBeaverLite.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverLite.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.lite'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/dbeaverultimate/darwin.json=== Install // 0a44a77f -> 52243cd3 ===
--- /tmp/old.63J26U 2026-05-26 17:45:03.458144393 +0000
+++ /tmp/new.kEtoaq 2026-05-26 17:45:03.458144393 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.dbeaver.product.ultimate'
+quit_and_track_application 'com.dbeaver.product.ultimate'
if [ -d "$APPDIR/DBeaverUltimate.app" ]; then
sudo mv "$APPDIR/DBeaverUltimate.app" "$TMPDIR/DBeaverUltimate.app.bkp"
fi
sudo cp -R "$TMPDIR/DBeaverUltimate.app" "$APPDIR"
+relaunch_application 'com.dbeaver.product.ultimate'
=== Uninstall Script (no changes) ===ee/maintained-apps/outputs/evernote/darwin.json=== Install // a83831d7 -> 67a65f7d ===
--- /tmp/old.cgfLDg 2026-05-26 17:45:03.501144540 +0000
+++ /tmp/new.ebJ5JI 2026-05-26 17:45:03.502144543 +0000
@@ -2,26 +2,34 @@
# variables
APPDIR="/Applications/"
-TMPDIR=$(dirname "$(realpath $INSTALLER_PATH)")
-
+TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
-yes | hdiutil attach -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
+yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.evernote.Evernote'
+quit_and_track_application 'com.evernote.Evernote'
if [ -d "$APPDIR/Evernote.app" ]; then
sudo mv "$APPDIR/Evernote.app" "$TMPDIR/Evernote.app.bkp"
fi
sudo cp -R "$TMPDIR/Evernote.app" "$APPDIR"
+relaunch_application 'com.evernote.Evernote'
=== Uninstall // 31b95715 -> b7960ac0 ===
--- /tmp/old.uc2b51 2026-05-26 17:45:03.517144595 +0000
+++ /tmp/new.Q1AAHO 2026-05-26 17:45:03.518144598 +0000
@@ -10,13 +10,15 @@
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
return
fiee/maintained-apps/outputs/royal-tsx/darwin.json=== Install // 8a40c4cb -> db51aef0 ===
--- /tmp/old.sevvtK 2026-05-26 17:45:03.561144745 +0000
+++ /tmp/new.gxs1gP 2026-05-26 17:45:03.561144745 +0000
@@ -3,25 +3,33 @@
# variables
APPDIR="/Applications/"
TMPDIR=$(dirname "$(realpath "$INSTALLER_PATH")")
-
# functions
-quit_application() {
+quit_and_track_application() {
local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
local timeout_duration=10
# check if the application is running
- if ! osascript -e "application id \"$bundle_id\" is running" 2>/dev/null; then
+ local app_running
+ app_running=$(osascript -e "application id \"$bundle_id\" is running" 2>/dev/null)
+ if [[ "$app_running" != "true" ]]; then
+ eval "export $var_name=0"
return
fi
local console_user
console_user=$(stat -f "%Su" /dev/console)
- if [[ $EUID -eq 0 && "$console_user" == "root" ]]; then
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
echo "Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'."
+ eval "export $var_name=0"
return
fi
+ # App was running, mark it for relaunch
+ eval "export $var_name=1"
+ echo "Application '$bundle_id' was running; will relaunch after installation."
+
echo "Quitting application '$bundle_id'..."
# try to quit the application within the timeout period
@@ -43,17 +51,58 @@
fi
}
+
+relaunch_application() {
+ local bundle_id="$1"
+ local var_name="APP_WAS_RUNNING_$(echo "$bundle_id" | tr '.-' '__')"
+ local was_running
+
+ # Check if the app was running before installation
+ eval "was_running=\$$var_name"
+ if [[ "$was_running" != "1" ]]; then
+ return
+ fi
+
+ local console_user
+ console_user=$(stat -f "%Su" /dev/console)
+ if [[ -z "$console_user" || "$console_user" == "root" || "$console_user" == "loginwindow" ]]; then
+ echo "Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'."
+ return
+ fi
+
+ echo "Relaunching application '$bundle_id'..."
+
+ # Launch the app in the logged-in user's GUI session. Apps launched by root
+ # won't register with the user's Dock/GUI, so run 'open' as the console user.
+ # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace
+ # and GUI session — 'sudo -u' alone doesn't do this, which can cause
+ # LSOpenURLsWithRole() failures even when 'open' exits 0.
+ local open_status=0
+ if [[ $EUID -eq 0 ]]; then
+ local console_uid
+ console_uid=$(id -u "$console_user")
+ /bin/launchctl asuser "$console_uid" sudo -u "$console_user" open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ else
+ open -b "$bundle_id" >/dev/null 2>&1 || open_status=$?
+ fi
+
+ if [[ $open_status -eq 0 ]]; then
+ echo "Application '$bundle_id' relaunched successfully."
+ else
+ echo "Failed to relaunch application '$bundle_id'."
+ fi
+}
+
+
# extract contents
-# Use 'yes' to automatically accept license agreement when mounting DMG
-# This replicates Homebrew's behavior for DMG files with license agreements
MOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)
yes | hdiutil attach -plist -nobrowse -readonly -mountpoint "$MOUNT_POINT" "$INSTALLER_PATH" || exit 1
sudo cp -R "$MOUNT_POINT"/* "$TMPDIR"
hdiutil detach "$MOUNT_POINT" || true
-
# copy to the applications folder
-quit_application 'com.lemonmojo.RoyalTSX.App'
+quit_and_track_application 'com.lemonmojo.RoyalTSX.App'
if [ -d "$APPDIR/Royal TSX.app" ]; then
sudo mv "$APPDIR/Royal TSX.app" "$TMPDIR/Royal TSX.app.bkp"
fi
sudo cp -R "$TMPDIR/Royal TSX.app" "$APPDIR"
+relaunch_application 'com.lemonmojo.RoyalTSX.App'
=== Uninstall Script (no changes) === |
Pipe
yesintohdiutil attachto auto-accept DMG license prompts, make attach failures exit, and ignore detach failures. Add a unit test to verify the DMG extract commands. Remove per-app install script files and corresponding install_script_path entries from inputs, and update outputs to reference consolidated install scripts that track/relaunch running apps after installation (updated install_script_ref hashes).Summary by CodeRabbit
New Features
Bug Fixes
Tests