#!/usr/bin/osascript -l JavaScript // ^^^^ COMMENT/REMOVE THIS SHEBANG IF RUNNING FROM SCRIPT EDITOR!!!!! ^^^^^^^^^^^ // The SHEBANG is only needed if the file is executable and is run from a terminal with `./RsyncBackup.js` // 1. In MacOS Spotlight type 'Script Editor' and paste the code below // 2. Click the top-left dropdown which says 'AppleScript' and select 'JavaScript' // 3. Under menu File pick Export // 4. In the Export dialog select File Format = Application // 5. Save the app in /Applications var app = Application.currentApplication() app.includeStandardAdditions = true app.displayAlert("Rsync Backup Wizard v 0.21", { message: "Press Continue to select the rsync location and SOURCE/TARGET folders...", buttons: ["Cancel", "Continue"], defaultButton: "Continue", cancelButton: "Cancel", withIcon: "caution" }) var cmd_find_rsync; if (app.doShellScript('echo $SHELL') == '/bin/zsh') { cmd_find_rsync = 'source ~/.zshrc || true && which -a rsync | uniq'; } else { cmd_find_rsync = 'source ~/.bashrc || true && which -a rsync | uniq'; } output = app.doShellScript(cmd_find_rsync); rsync_paths = output.match(/[^\r]+/g); var rsyncPath = app.chooseFromList(rsync_paths, { withPrompt: "Select the rsync binary path:", defaultItems: [rsync_paths[0]] }); var sourceFolder = app.chooseFolder({ withPrompt: "Please select the SOURCE folder:" }); var targetFolder = app.chooseFolder({ withPrompt: "Please select the TARGET:" }); // TODO: include output of: // sudo mdfind "com_apple_backup_excludeItem = 'com.apple.backupd'" var cmd = String(rsyncPath) + " --checksum" + " -av" + " --progress" + " --ignore-errors" + " --no-compress" + " --whole-file" + " --ignore-existing" + " --exclude '.cache'" + " --exclude '.com.apple.backupd.mvlist.plist'" + " --exclude '.docker'" + " --exclude '.DocumentRevisions-V100'" + " --exclude '.DS_Store*'" + " --exclude '.electron'" + " --exclude '.fseventsd'" + " --exclude '.hotfiles.btree'" + " --exclude '.journal*'" + " --exclude '.journal_info_block*'" + " --exclude '.MobileBackups'" + " --exclude '.MobileBackups.trash'" + " --exclude '.Spotlight-V100'" + " --exclude '.TemporaryItems*'" + " --exclude '.Trash'" + " --exclude '.Trashes'" + " --exclude '.vol'" + " --exclude '/automount'" + " --exclude '/cores'" + " --exclude '/dev'" + " --exclude '/home'" + " --exclude '/net'" + " --exclude '/Network'" + " --exclude '/private/etc/kcpassword'" + " --exclude '/private/Network'" + " --exclude '/private/tftpboot'" + " --exclude '/private/tmp'" + " --exclude '/private/var'" + " --exclude '/private/var/automount'" + " --exclude '/private/var/db/com.apple.backupd.backupVerification'" + " --exclude '/private/var/db/dhcpclient'" + " --exclude '/private/var/db/dyld'" + " --exclude '/private/var/db/dyld/shared_region_roots'" + " --exclude '/private/var/db/efw_cache'" + " --exclude '/private/var/db/fseventsd'" + " --exclude '/private/var/db/Spotlight'" + " --exclude '/private/var/db/Spotlight-V100'" + " --exclude '/private/var/db/systemstats'" + " --exclude '/private/var/folders'" + " --exclude '/private/var/lib/postfix/greylist.db'" + " --exclude '/private/var/log'" + " --exclude '/private/var/run'" + " --exclude '/private/var/spool/cups'" + " --exclude '/private/var/spool/fax'" + " --exclude '/private/var/spool/uucp'" + " --exclude '/private/var/tmp'" + " --exclude '/private/var/vm'" + " --exclude '/System/Library/Caches'" + " --exclude '/System/Library/Extensions/Caches'" + " --exclude '/Users/Guest'" + " --exclude 'Autosave Information'" + " --exclude 'Backups.backupdb'" + " --exclude 'Cache'" + " --exclude 'Desktop DB'" + " --exclude 'Desktop DF'" + " --exclude 'DiagnosticReports*'" + " --exclude 'Library/Caches'" + " --exclude 'Library/Containers'" + " --exclude 'Library/Group Containers'" + " --exclude 'Library/LanguageModeling'" + " --exclude 'Library/Logs'" + " --exclude 'Library/Mail/AvailableFeeds'" + " --exclude 'Library/Mail/Metadata/BackingStoreUpdateJournal'" + " --exclude 'Library/Mail/V2/MailData/AvailableFeeds'" + " --exclude 'Library/Mail/V2/MailData/BackingStoreUpdateJournal'" + " --exclude 'Library/Mail/V2/MailData/Envelope*'" + " --exclude 'Library/Metadata/CoreSpotlight'" + " --exclude 'Library/Mirrors'" + " --exclude 'Library/PubSub'" + " --exclude 'Library/Safari/HistoryIndex.sk'" + " --exclude 'Library/Safari/Icons.db'" + " --exclude 'Library/Safari/WebpageIcons.db'" + " --exclude 'Library/Updates'" + " --exclude 'Logs'" + " --exclude 'lost+found'" + " --exclude 'MobileBackups.trash'" + " --exclude 'node_modules'" + " --exclude 'Saved Application State'" + " '" + String(sourceFolder) + "\/' " + "'" + String(targetFolder) + "'"; var confirmationResponse = app.displayDialog("Press Continue to execute the following command in the terminal:", { defaultAnswer: cmd, withIcon: "note", buttons: ["Cancel", "Continue"], defaultButton: "Continue" }) cmd = String(confirmationResponse.textReturned) app.displayAlert(cmd, { message: "The rsync command will be started in the terminal", buttons: ["Cancel", "🚀 Start Backup!"], defaultButton: "🚀 Start Backup!", cancelButton: "Cancel", withIcon: "caution" }) var terminal = Application('Terminal'); terminal.activate(); delay(4) terminal.doScript(cmd);