Added Ableton Live Suite to FMA - #46430
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #46430 +/- ##
==========================================
+ Coverage 66.90% 66.91% +0.01%
==========================================
Files 2834 2837 +3
Lines 224862 225011 +149
Branches 11512 11475 -37
==========================================
+ Hits 150435 150562 +127
- Misses 60772 60785 +13
- Partials 13655 13664 +9
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:
|
WalkthroughThis PR adds Ableton Live Suite 12.4.1 support for macOS. It includes a homebrew input manifest defining the app metadata, an output configuration with version information, SQL presence/patch detection queries, and both installation and uninstallation bash scripts. The installation script handles DMG extraction, app placement in Possibly related PRs
🚥 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: 3
🤖 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/ableton-live-suite/darwin.json`:
- Line 19: The script currently moves the existing bundle to a .bkp before
ensuring the new app was fully staged, risking app loss if copying fails; update
the install flow in the section after MOUNT_POINT handling to first stage the
new bundle into a safe temporary path (use "$TMPDIR/Ableton Live 12 Suite.app"
as the staged copy), validate that the staged copy exists and is
readable/writable, then atomically swap: move the existing "$APPDIR/Ableton Live
12 Suite.app" to a .bkp and move the staged bundle into "$APPDIR" using sudo,
and on any failure restore the .bkp back to its original location; keep existing
quit_and_track_application and relaunch_application calls, and ensure cleanup of
the .bkp and staged copy only after a successful installation.
- Line 20: The cleanup patterns are passed literally into trash() because shell
globs aren't expanded; update the uninstall script to enable globbing (e.g.,
shopt -s nullglob) and replace direct trash calls that pass patterns (e.g.,
"Trash $LOGGED_IN_USER '...Max_*.*_resource.diag'") with loops that expand
matches and call trash per expanded path; keep the existing trash() signature
and ensure you quote the expanded path when calling trash (refer to the trash()
function and its callers and also the quit_application() / APPDIR removal area
to locate where to make the changes).
In `@frontend/pages/SoftwarePage/components/icons/index.ts`:
- Line 357: The map entry using the loose key 'live' is too generic and should
be renamed to scoped keys so prefix matching doesn't misclassify other software;
replace the 'live' key that maps to AbletonLive12Suite with one or two more
specific keys such as "ableton live" and/or "ableton live suite" (i.e., change
the map entry from live: AbletonLive12Suite to "ableton live":
AbletonLive12Suite and optionally "ableton live suite": AbletonLive12Suite) so
the matching logic remains targeted to Ableton products.
🪄 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: 6e7a01fa-4aa0-4c05-b46f-9e0ddb553bbf
⛔ Files ignored due to path filters (1)
website/assets/images/app-icon-ableton-live-suite-60x60@2x.pngis excluded by!**/*.png
📒 Files selected for processing (5)
ee/maintained-apps/inputs/homebrew/ableton-live-suite.jsonee/maintained-apps/outputs/ableton-live-suite/darwin.jsonee/maintained-apps/outputs/apps.jsonfrontend/pages/SoftwarePage/components/icons/AbletonLive12Suite.tsxfrontend/pages/SoftwarePage/components/icons/index.ts
| } | ||
| ], | ||
| "refs": { | ||
| "b31309ba": "#!/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.ableton.live'\nif [ -d \"$APPDIR/Ableton Live 12 Suite.app\" ]; then\n\tsudo mv \"$APPDIR/Ableton Live 12 Suite.app\" \"$TMPDIR/Ableton Live 12 Suite.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Ableton Live 12 Suite.app\" \"$APPDIR\"\nrelaunch_application 'com.ableton.live'\n", |
There was a problem hiding this comment.
Preserve the existing app until the replacement is fully staged.
This script moves /Applications/Ableton Live 12 Suite.app to a backup before verifying that "$TMPDIR/Ableton Live 12 Suite.app" was copied out of the DMG and can be installed. If the DMG copy or the final cp -R fails, the machine is left without a working app. Stage the new bundle first, then swap it in atomically or restore the backup on failure.
🤖 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/ableton-live-suite/darwin.json` at line 19, The
script currently moves the existing bundle to a .bkp before ensuring the new app
was fully staged, risking app loss if copying fails; update the install flow in
the section after MOUNT_POINT handling to first stage the new bundle into a safe
temporary path (use "$TMPDIR/Ableton Live 12 Suite.app" as the staged copy),
validate that the staged copy exists and is readable/writable, then atomically
swap: move the existing "$APPDIR/Ableton Live 12 Suite.app" to a .bkp and move
the staged bundle into "$APPDIR" using sudo, and on any failure restore the .bkp
back to its original location; keep existing quit_and_track_application and
relaunch_application calls, and ensure cleanup of the .bkp and staged copy only
after a successful installation.
| ], | ||
| "refs": { | ||
| "b31309ba": "#!/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.ableton.live'\nif [ -d \"$APPDIR/Ableton Live 12 Suite.app\" ]; then\n\tsudo mv \"$APPDIR/Ableton Live 12 Suite.app\" \"$TMPDIR/Ableton Live 12 Suite.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Ableton Live 12 Suite.app\" \"$APPDIR\"\nrelaunch_application 'com.ableton.live'\n", | ||
| "f227fade": "#!/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.ableton.live'\nsudo rm -rf \"$APPDIR/Ableton Live 12 Suite.app\"\ntrash $LOGGED_IN_USER '/Library/Logs/DiagnosticReports/Max_*.*_resource.diag'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Ableton'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Ableton *_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Live_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Max_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Cycling '74'\ntrash $LOGGED_IN_USER '~/Library/Caches/Ableton'\ntrash $LOGGED_IN_USER '~/Library/Preferences/Ableton'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.ableton.live.plist*'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.cycling74.Max*.plist*'\ntrash $LOGGED_IN_USER '~/Music/Ableton'\ntrash $LOGGED_IN_USER '~/Documents/Max [0-9]'\ntrash $LOGGED_IN_USER '/Users/Shared/Max [0-9]'\n" |
There was a problem hiding this comment.
Wildcard cleanup targets are treated as literal paths.
trash() only checks [[ -e "$target_file" ]] and then mv "$target_file" ..., so entries like Max_*.*_resource.diag, Ableton *_*.plist, and Max [0-9] never expand and will always be skipped. The uninstall will remove the app bundle, but a large part of the promised cleanup won't happen.
Suggested shape
shopt -s nullglob
for path in /Library/Logs/DiagnosticReports/Max_*.*_resource.diag; do
trash "$LOGGED_IN_USER" "$path"
done
for path in "$HOME"/Library/Application\ Support/CrashReporter/Ableton\ *_*.plist; do
trash "$LOGGED_IN_USER" "$path"
done🤖 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/ableton-live-suite/darwin.json` at line 20, The
cleanup patterns are passed literally into trash() because shell globs aren't
expanded; update the uninstall script to enable globbing (e.g., shopt -s
nullglob) and replace direct trash calls that pass patterns (e.g., "Trash
$LOGGED_IN_USER '...Max_*.*_resource.diag'") with loops that expand matches and
call trash per expanded path; keep the existing trash() signature and ensure you
quote the expanded path when calling trash (refer to the trash() function and
its callers and also the quit_application() / APPDIR removal area to locate
where to make the changes).
| kitty: Kitty, | ||
| krita: Krita, | ||
| lastpass: LastPass, | ||
| live: AbletonLive12Suite, |
There was a problem hiding this comment.
Use a more specific match key than live.
Because this map is used for loose prefix matching, live can pick the Ableton icon for unrelated software names that happen to start with “Live”. Matching on "ableton live" and/or "ableton live suite" keeps this scoped to the product being added.
Possible tweak
- live: AbletonLive12Suite,
+ "ableton live": AbletonLive12Suite,
+ "ableton live suite": AbletonLive12Suite,📝 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.
| live: AbletonLive12Suite, | |
| "ableton live": AbletonLive12Suite, | |
| "ableton live suite": AbletonLive12Suite, |
🤖 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 `@frontend/pages/SoftwarePage/components/icons/index.ts` at line 357, The map
entry using the loose key 'live' is too generic and should be renamed to scoped
keys so prefix matching doesn't misclassify other software; replace the 'live'
key that maps to AbletonLive12Suite with one or two more specific keys such as
"ableton live" and/or "ableton live suite" (i.e., change the map entry from
live: AbletonLive12Suite to "ableton live": AbletonLive12Suite and optionally
"ableton live suite": AbletonLive12Suite) so the matching logic remains targeted
to Ableton products.
|
@desmonet Please make the necessary changes to get this to pass the |
|
App will be added here: #47058 |
Addition of Ableton Live Suite to the Fleet-Maintained apps list.
Product information: https://www.ableton.com/fr/live
Homebrew formula: https://formulae.brew.sh/cask/ableton-live-suite#default
Thanks!
@allenhouchins
Summary by CodeRabbit