Skip to content

Update Fleet-maintained apps - #46307

Merged
allenhouchins merged 1 commit into
mainfrom
fma-2605280022
May 28, 2026
Merged

Update Fleet-maintained apps#46307
allenhouchins merged 1 commit into
mainfrom
fma-2605280022

Conversation

@fleet-release

@fleet-release fleet-release commented May 28, 2026

Copy link
Copy Markdown
Contributor

Automated ingestion of latest Fleet-maintained app data.

Summary by CodeRabbit

  • Chores
    • Updated maintained application metadata for 18+ apps including 1Password, Google Chrome, Signal, Visual Studio Code, and others to support newer versions on macOS and Windows platforms.
    • Synchronized installer URLs, integrity checksums, and version references for latest releases.
    • Enhanced uninstall scripts for improved application cleanup on system removal.

Review Change Stack

Generated automatically with cmd/maintained-apps.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

Copy link
Copy Markdown
Contributor

Script Diff Results

ee/maintained-apps/outputs/1password/darwin.json

=== Install Script (no changes) ===
=== Uninstall // f58c31b3 -> dadf8c51 ===

--- /tmp/old.UCbzlG	2026-05-28 00:25:20.501624304 +0000
+++ /tmp/new.m0kkdF	2026-05-28 00:25:20.501624304 +0000
@@ -5,6 +5,46 @@
 LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
 # functions
 
+quit_application() {
+  local bundle_id="$1"
+  local timeout_duration=10
+
+  # check if the application is running
+  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 [[ -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
+  fi
+
+  echo "Quitting application '$bundle_id'..."
+
+  # try to quit the application within the timeout period
+  local quit_success=false
+  SECONDS=0
+  while (( SECONDS < timeout_duration )); do
+    if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+      if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+        echo "Application '$bundle_id' quit successfully."
+        quit_success=true
+        break
+      fi
+    fi
+    sleep 1
+  done
+
+  if [[ "$quit_success" = false ]]; then
+    echo "Application '$bundle_id' did not quit."
+  fi
+}
+
+
 trash() {
   local logged_in_user="$1"
   local target_file="$2"
@@ -27,6 +67,7 @@
   fi
 }
 
+quit_application 'com.1password.1password'
 sudo rm -rf "$APPDIR/1Password.app"
 trash $LOGGED_IN_USER '~/Library/Application Scripts/2BUA8C4S2C.com.1password*'
 trash $LOGGED_IN_USER '~/Library/Application Scripts/2BUA8C4S2C.com.agilebits'

ee/maintained-apps/outputs/amazon-chime/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/cursor/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/drawio/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/dropbox/darwin.json

=== Install Script (no changes) ===
=== Uninstall // 4d5c7d9c -> f2e8d2ab ===

--- /tmp/old.WW9dct	2026-05-28 00:25:20.710622343 +0000
+++ /tmp/new.kKT2hU	2026-05-28 00:25:20.710622343 +0000
@@ -5,6 +5,46 @@
 LOGGED_IN_USER=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
 # functions
 
+quit_application() {
+  local bundle_id="$1"
+  local timeout_duration=10
+
+  # check if the application is running
+  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 [[ -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
+  fi
+
+  echo "Quitting application '$bundle_id'..."
+
+  # try to quit the application within the timeout period
+  local quit_success=false
+  SECONDS=0
+  while (( SECONDS < timeout_duration )); do
+    if osascript -e "tell application id \"$bundle_id\" to quit" >/dev/null 2>&1; then
+      if ! pgrep -f "$bundle_id" >/dev/null 2>&1; then
+        echo "Application '$bundle_id' quit successfully."
+        quit_success=true
+        break
+      fi
+    fi
+    sleep 1
+  done
+
+  if [[ "$quit_success" = false ]]; then
+    echo "Application '$bundle_id' did not quit."
+  fi
+}
+
+
 remove_launchctl_service() {
   local service="$1"
   local booleans=("true" "false")
@@ -73,6 +113,7 @@
 }
 
 remove_launchctl_service 'com.dropbox.DropboxMacUpdate.agent'
+quit_application 'com.getdropbox.dropbox'
 sudo rm -rf '/Library/DropboxHelperTools'
 sudo rm -rf '/Library/Preferences/com.getdropbox.dropbox.dbkextd.plist'
 sudo rm -rf "$APPDIR/Dropbox.app"

ee/maintained-apps/outputs/google-chrome/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/gotomeeting/windows.json

=== Install Script (no changes) ===
=== Uninstall // cef7f8fa -> f5235386 ===

--- /tmp/old.qEPBWy	2026-05-28 00:25:20.803621470 +0000
+++ /tmp/new.lElPxl	2026-05-28 00:25:20.803621470 +0000
@@ -1,15 +1,11 @@
-# Best-effort uninstall for GoToMeeting.
+# Uninstall for GoToMeeting.
 #
 # The winget installer is the GoToMeeting "Setup" bootstrapper (ARPSYSTEMCOMPONENT=1,
 # so it hides itself from Programs and Features). It installs the actual GoToMeeting
 # app, which self-registers a separate, visible uninstall entry (DisplayName like
 # "GoToMeeting <version>") whose uninstaller is G2MUninstall.exe.
 #
-# We locate that entry and run G2MUninstall.exe directly. NOTE: the registry
-# QuietUninstallString uses "/S", which G2MUninstall.exe does not recognize as a
-# silent switch (it hangs waiting on UI). The vendor's documented silent switch
-# is "/silent" (see silentinstallhq.com), so we build the arguments ourselves
-# rather than trusting the registry string.
+# We locate that entry and run G2MUninstall.exe directly.
 
 $softwareNameLike = "GoToMeeting*"

ee/maintained-apps/outputs/granola/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/granola/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/jabra-direct/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/krita/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/microsoft-edge/windows.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/onedrive/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/signal/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/visual-studio-code/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/whatsapp/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/wrike/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zed/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

ee/maintained-apps/outputs/zen/darwin.json

=== Install Script (no changes) ===
=== Uninstall Script (no changes) ===

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR updates installed app metadata across 19 maintained applications. Most changes bump the application version, update the SQL patched query threshold to match the new version, and provide new installer URLs and SHA-256 checksums. Three apps (1Password, Dropbox, and GoToMeeting) additionally reference new uninstall script definitions that introduce quit_application steps to gracefully terminate the app before removal.

Possibly related PRs

  • fleetdm/fleet#46247: Updates app uninstall scripts to add quit_application steps before removal, similar to the script reference changes in 1Password and Dropbox.
  • fleetdm/fleet#45786: Switches multiple app uninstall_script_ref values to new refs that add quit_application logic for graceful app shutdown.
  • fleetdm/fleet#46055: Modifies 1Password macOS version targeting and associated script metadata.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update Fleet-maintained apps' is directly related to the changeset, which updates version metadata and installer references for 16 Fleet-maintained applications across multiple platforms.
Description check ✅ Passed The PR description is minimal but appropriate for an automated data ingestion. The template is designed for substantial feature/fix PRs with testing and database considerations that don't apply to this data-only update.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fma-2605280022

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/dropbox/darwin.json`:
- Line 20: The trash() function treats wildcard paths as literals so patterns
like those passed from callers (e.g., trash $LOGGED_IN_USER
'~/Library/Application Scripts/*.com.getdropbox.dropbox.sync') never expand;
update trash() to expand globs and iterate matches: after expanding ~ to
/Users/$logged_in_user, enable globbing with shopt -s nullglob (save/restore
previous state), create an array matches=( $target_file ) (unquoted to allow
expansion), then loop over "${matches[@]}" and perform the existence check and
mv for each file (keeping the timestamp/rand naming), and if matches is empty
print the "doesn't exist" message. Ensure the change references the trash()
function and the target_file/local variables so callers using wildcard patterns
are removed.
🪄 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: a3256615-b7f0-421a-81ef-f36288a7f28c

📥 Commits

Reviewing files that changed from the base of the PR and between e642e6a and a1f7882.

📒 Files selected for processing (19)
  • ee/maintained-apps/outputs/1password/darwin.json
  • ee/maintained-apps/outputs/amazon-chime/darwin.json
  • ee/maintained-apps/outputs/cursor/windows.json
  • ee/maintained-apps/outputs/drawio/darwin.json
  • ee/maintained-apps/outputs/dropbox/darwin.json
  • ee/maintained-apps/outputs/google-chrome/windows.json
  • ee/maintained-apps/outputs/gotomeeting/windows.json
  • ee/maintained-apps/outputs/granola/darwin.json
  • ee/maintained-apps/outputs/granola/windows.json
  • ee/maintained-apps/outputs/jabra-direct/darwin.json
  • ee/maintained-apps/outputs/krita/windows.json
  • ee/maintained-apps/outputs/microsoft-edge/windows.json
  • ee/maintained-apps/outputs/onedrive/darwin.json
  • ee/maintained-apps/outputs/signal/darwin.json
  • ee/maintained-apps/outputs/visual-studio-code/darwin.json
  • ee/maintained-apps/outputs/whatsapp/darwin.json
  • ee/maintained-apps/outputs/wrike/darwin.json
  • ee/maintained-apps/outputs/zed/darwin.json
  • ee/maintained-apps/outputs/zen/darwin.json

"4d5c7d9c": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\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\nremove_launchctl_service 'com.dropbox.DropboxMacUpdate.agent'\nsudo rm -rf '/Library/DropboxHelperTools'\nsudo rm -rf '/Library/Preferences/com.getdropbox.dropbox.dbkextd.plist'\nsudo rm -rf \"$APPDIR/Dropbox.app\"\ntrash $LOGGED_IN_USER '~/.dropbox'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/*.com.getdropbox.dropbox.sync'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.alternatenotificationservice'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.client.crashpad'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.foldertagger'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.TransferExtension'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Application Support/DropboxElectron'\ntrash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Caches/CloudKit/com.apple.bird/iCloud.com.getdropbox.Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dropbox.DropboxUpdater'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.getdropbox.dropbox'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.getdropbox.DropboxMetaInstaller'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.plausiblelabs.crashreporter.data/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/CloudStorage/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.activityprovider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.alternatenotificationservice'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.foldertagger'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.TransferExtension'\ntrash $LOGGED_IN_USER '~/Library/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Dropbox/DropboxMacUpdate.app/Contents/MacOS/DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/*.com.getdropbox.dropbox.sync'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/com.dropbox.client.crashpad'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.getdropbox.dropbox'\ntrash $LOGGED_IN_USER '~/Library/LaunchAgents/com.dropbox.DropboxMacUpdate.agent.plist'\ntrash $LOGGED_IN_USER '~/Library/Logs/Dropbox_debug.log'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.apple.FileProvider/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.DropboxMacUpdate.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.DropboxMonitor.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.tungsten.helper.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.getdropbox.dropbox.plist'\n",
"59c04bcb": "#!/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)\nhdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\"\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\"\n# copy to the applications folder\nquit_and_track_application 'com.getdropbox.dropbox'\nif [ -d \"$APPDIR/Dropbox.app\" ]; then\n\tsudo mv \"$APPDIR/Dropbox.app\" \"$TMPDIR/Dropbox.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Dropbox.app\" \"$APPDIR\"\nrelaunch_application 'com.getdropbox.dropbox'\n"
"59c04bcb": "#!/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)\nhdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\"\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\"\n# copy to the applications folder\nquit_and_track_application 'com.getdropbox.dropbox'\nif [ -d \"$APPDIR/Dropbox.app\" ]; then\n\tsudo mv \"$APPDIR/Dropbox.app\" \"$TMPDIR/Dropbox.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Dropbox.app\" \"$APPDIR\"\nrelaunch_application 'com.getdropbox.dropbox'\n",
"f2e8d2ab": "#!/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\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\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\nremove_launchctl_service 'com.dropbox.DropboxMacUpdate.agent'\nquit_application 'com.getdropbox.dropbox'\nsudo rm -rf '/Library/DropboxHelperTools'\nsudo rm -rf '/Library/Preferences/com.getdropbox.dropbox.dbkextd.plist'\nsudo rm -rf \"$APPDIR/Dropbox.app\"\ntrash $LOGGED_IN_USER '~/.dropbox'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/*.com.getdropbox.dropbox.sync'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.alternatenotificationservice'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.client.crashpad'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.dropbox.foldertagger'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.getdropbox.dropbox.TransferExtension'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Application Support/DropboxElectron'\ntrash $LOGGED_IN_USER '~/Library/Application Support/FileProvider/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Caches/CloudKit/com.apple.bird/iCloud.com.getdropbox.Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dropbox.DropboxUpdater'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.getdropbox.dropbox'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.getdropbox.DropboxMetaInstaller'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.plausiblelabs.crashreporter.data/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/CloudStorage/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.activityprovider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.alternatenotificationservice'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dropbox.foldertagger'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.getdropbox.dropbox.TransferExtension'\ntrash $LOGGED_IN_USER '~/Library/Dropbox'\ntrash $LOGGED_IN_USER '~/Library/Dropbox/DropboxMacUpdate.app/Contents/MacOS/DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/*.com.getdropbox.dropbox.sync'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/com.dropbox.client.crashpad'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/com.getdropbox.dropbox.garcon'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.dropbox.DropboxMacUpdate'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.getdropbox.dropbox'\ntrash $LOGGED_IN_USER '~/Library/LaunchAgents/com.dropbox.DropboxMacUpdate.agent.plist'\ntrash $LOGGED_IN_USER '~/Library/Logs/Dropbox_debug.log'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.apple.FileProvider/com.getdropbox.dropbox.fileprovider'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.DropboxMacUpdate.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.DropboxMonitor.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dropbox.tungsten.helper.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.getdropbox.dropbox.plist'\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Wildcard paths in trash() are handled as literals, so cleanup misses globbed targets.

trash() uses [[ -e "$target_file" ]] and mv -f "$target_file" ... while callers pass patterns like ~/Library/Application Scripts/*.com.getdropbox...; those won’t expand and won’t be removed.

Proposed helper fix (bash snippet)
 trash() {
   local logged_in_user="$1"
   local target_file="$2"
   local timestamp="$(date +%Y-%m-%d-%s)"
   local rand="$(jot -r 1 0 99999)"
@@
-  local trash="/Users/$logged_in_user/.Trash"
-  local file_name="$(basename "${target_file}")"
-
-  if [[ -e "$target_file" ]]; then
-    echo "removing $target_file."
-    mv -f "$target_file" "$trash/${file_name}_${timestamp}_${rand}"
-  else
-    echo "$target_file doesn't exist."
-  fi
+  local trash="/Users/$logged_in_user/.Trash"
+  local matched=false
+  local path
+
+  while IFS= read -r path; do
+    matched=true
+    local file_name
+    file_name="$(basename "$path")"
+    echo "removing $path."
+    mv -f "$path" "$trash/${file_name}_${timestamp}_${rand}"
+  done < <(compgen -G "$target_file")
+
+  if [[ "$matched" = false ]]; then
+    echo "$target_file doesn't exist."
+  fi
 }
🤖 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/dropbox/darwin.json` at line 20, The trash()
function treats wildcard paths as literals so patterns like those passed from
callers (e.g., trash $LOGGED_IN_USER '~/Library/Application
Scripts/*.com.getdropbox.dropbox.sync') never expand; update trash() to expand
globs and iterate matches: after expanding ~ to /Users/$logged_in_user, enable
globbing with shopt -s nullglob (save/restore previous state), create an array
matches=( $target_file ) (unquoted to allow expansion), then loop over
"${matches[@]}" and perform the existence check and mv for each file (keeping
the timestamp/rand naming), and if matches is empty print the "doesn't exist"
message. Ensure the change references the trash() function and the
target_file/local variables so callers using wildcard patterns are removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants