Skip to content

Instantly share code, notes, and snippets.

@glowinthedark
Last active December 4, 2023 15:32
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save glowinthedark/1f7fae62bf0794af66636361154f2015 to your computer and use it in GitHub Desktop.
MacOS RsyncBackup — simplest possible rsync GUI for MacOS
#!/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);
@imaPheven
Copy link

Nice, hadn't realized you could run JavaScript in there.

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