MACRO: MacroBackerUpper—it's like Time Machine for your macro library

MacroBackerUpper (MBU) is my new macro designed make it simple to create multiple time-based backups of your KM macro library. It functions much like Time Machine, creating a date-stamped set of folders, each with a full backup in it:

───────────────────────────────────────

__ MacroBackerUpper 2.9 Macros.kmmacros (1.2 MB)

Full instructions for use

────────────────

Feb 12 2024: Version 2.9: For users with macros (in the same group) with identical names, or with leading-dot-named macros and/or groups, this version makes it easier to find and change (if you wish) all such names. The macro now writes the lists of "dupes and dots" names to two files in a temporary directory on your disk, then opens that folder when the macro finishes. (This won't happen again if you disable warnings for dupes and dots when prompted.)

Previous versions

Jan 11 2024: Version 2.8: A maintenance release that updates some naming conventions and re-enables the first-run macro, which was left disabled in the last update.

Dec 21: Version 2.7 fixes a couple fairly small bugs. One caused needless entries in Keyboard Maestro's log file, and the other wrapped some text that shouldn't have been wrapped.

Dec 7: Version 2.6 fixes a bug that @_jims found when the backup folder couldn't be found. Sadly, I caused the bug by changing a routine in the 2.2 release. He also suggested that the macro not tell you it doesn't need an update, if the update checker ran on its schedule (as opposed to you running it). There are a couple other minor changes, but nothing major.

Dec 2: Version 2.5 changes how MBU looks for DefaultFolder X, as it turns out it's not visible to the Keyboard Maestro "is app active?" action if run through SetApp. Using ps in Terminal fixed that. The only other change clears a few large instance variables when MBU is done with them, to free environment space.

Nov 27: Version 2.4 has only two substantive changes, but they're important. First, I was able to work around the Default Folder X issue, as the app is AppleScriptable and includes a very useful enable and disable set of commands. The macro will determine if Default Folder X is running, and if so, disable it before the backup, then re-enable it when the backup is complete. I have tested this myself with the demo of Default Folder X, and it works very well.

The other big change is behind the scenes: I've switched to a more-obscure delimiter for database tasks, which should prevent name-based collision issues a couple users saw. Long story short, you can now use ### in your names again. However, if you happen to use ←🔸→ … well, don't do that. Seriously, just don't :).

Nov 26: Version 2.3 is out with a couple important warnings for Default Folder X users, as well as those who include ### in their macro and/or group names. See the full release notes in the most recent post from me in this thread, or read them onscreen or in the app. There are some other minor fixes, but no new features this time out.

Nov 24: Version 2.2 is out. The macro now includes a diff viewer, so you can see exactly what changed in macros that were marked as modified. (Only for modified macros that have the same name and group as in the last backup.)

The Settings Manager has been rewritten to be easier to use when actually setting settings, and you can do more from the delay box: Cancel, check for an update, or open the diff viewer. I also cleaned up some SQL calls, and fixed a bunch of little things.

Nov 21: Version 2.1 is out. It (hopefully) fixes the two major issues some people had, and cleans up some other stuff I found while going through everything again. The two big issues (macro failing when renamed or leading-dot-named macros/groups existed) were due to me missing one word ("Macros") while editing my existing SQL subroutine calls in three spots across the hundred-odd times I call it.

I also modified the first run experience, so new users only need answer two questions to get going. And I fixed a number of other things, detailed in the release notes post that will soon appear at the bottom of this thread.

Sorry for the issues; I really should have caught those during testing.

Nov 20: Version 2.0. Yes, a major upgrade only weeks after initial release. Why? Due to some structural changes that will make it impossible (without resetting things) to use version 1.4 again after upgrading. But those structural changes enabled some nice new features, including the ability to disable/enable Finder labels, change the delay before backing up, tracking enabled and disabled groups, and more. See the full notes in a separate post below.

Before running version 2.0, I recommend running 1.4 once more, to get your latest changes into a tracked update. The first backup with 2.0 will be a full (no hard links) backup, and without any comparisons to the prior backup. After the first, hard links and analysis return.

Please see the version 2.0 power below for more details on features, upgrading, and downgrading.

Nov 13: Version 1.4: Lots of changes here, but the most important is a typo I found and fixed—I had m where I should have had rm in a shell script command. Not good. I made some changes to reduce the spurious log entries that MBU generates, including one for non-error Type 1 errors from the diff command.

I also removed a routine that tried to manipulate the export window—I think that was causing some of the issues here, so now we'll just have to put up with that window not being centered or sized.

Full release notes in the app, or further down in this thread.

Nov 12: Version 1.3: Big update today. I added some code that will attempt to resolve issues resulting from an incomplete run. To do that, the latest backup is deleted and the database is rebuilt, as that's the only way to get things 'right' for the next backup.

If you use a palette trigger, you should now see the final report if you have it set to show when manually triggered. I also added some code to a key AppleScript to hopefully avoid the spurious -600 errors some users are seeing. Thanks, Chris, for both those tidbits!

Perhaps most importantly, after 3,000+ uses, I managed to find (and fix!) a condition that caused a hard link to fail to be created. As far as I know, this only affected me so far, but please run a new backup after installing 1.3 as it will resolve the issue if you had experienced it.

(The condition: If you had a one-macro group, and you renamed the macro in that group, and you renamed the macro in that group, then the hard link wouldn't be created.)

Nov 10: Version 1.2: Added two new features (let's call it the Chris Release!). You can now control how/if the final onscreen summary dialog appears, and MBU will attempt to put the Keyboard Maestro app back into the same condition it was when the macro ran: Active and visible, active and hidden, or not even running.

I also fixed a few other minor bugs, including one in the update routine, which means you can't use the update routing to update this time. Finally, I added some troubleshooting instructions to the help page.

Nov 9: Version 1.1: A very important bug fix now means MBU should run for everyone, regardless of your number format of choice :). A few other behind-the-scenes updates, too. If you already have 1.0, try the in-macro updater by running the upd | Update check macro. This won't actually install the macro, but it will download it and verify that it hasn't been tampered with.

Nov 7: Version 1.0: Initial release

───────────────────────────────────────

HOW IT WORKS

Just like Time Machine, items in the backup that haven't changed since the last one are replaced with hard links (optional, on by default), which are tiny pointers to the older version of the identical macro. This lets you keep a ridiculously large number of backups in a relatively tiny amount of drive space. After my final round of final testing, I have 24 backups totaling 35MB of drive space—and just one full export of my collection is 24MB.

(Speaking of testing, a big shout out to jims and tiffle, both of whom helped me find and fix quite a few issues with the analysis and reporting in MBU. Thanks!!)

Within each backup folder is a report explaining exactly what changed from the prior backup—MBU analyzes moves, renames, renames and moves, new and deleted macros and groups, and modified macros. Here's a sample of a report:

Very lengthy sample report hides here

backup_report_sample

The geeky timing section at the bottom of the report is optional (and off by default).

BACKING UP

Run •main | MacroBackerUpper, wait three seconds, and the backup starts. It's as simple as that (after initial setup, of course). But what if you want to change those settings you made during setup? Just press the Control key before the timer in the obnoxiously bright green box expires.

Do that, and the settings manager will open:

image

Included in the Settings Manager is the ability to relocate all your backups to a new location. The main downside of hard links is that if you use Finder to copy them to another drive, they become real files, and your backup archive is suddenly huge. There are instructions in the macro on how to avoid this in Terminal, or you can use the Settings Manager.

When a backup completes, you'll see an onscreen summary:

The important bit in the summary is the total disk space usage. If you compare that figure to Finder, you'll find Finder's value is huge, as it treats hard links as if they were full files. The value shown in the summary window is the actual drive space needed for all your backups.

THE ANALYSIS

MBU does its best to identify exactly what changed with every single macro and group in your collection since the last backup. I'd say it's pretty good at it, but there are limitations. One of those is that when you duplicate or rename a group, all of the macros in that group are modified in some way by KM. As such, MBU will report all those macros as modified, because they are, even though you didn't modify them.

There are probably other things like this that I haven't run into yet, but overall, I think MBU does a really nice job of explaining what's changed between the last two backups.

For modified macros that are actually modified, and within the same group (and with the same name) as in the last backup, you can open a visual diff tool to see exactly what changed. The macro supports FileMerge (which requires Xcode), Visual Studio Code, and as a fallback, the built-in diff results in a window. Here's how it looks in FileMerge:

RESTORING MACROS AND MACRO GROUPS

MBU was not written as a full-fledged "backup and restore" tool. It is a backup only tool, as I didn't want it to ever have any chance of harming my macros if I had coded something incorrectly.

So how do you restore? Via Finder, because the backups are just files in Finder. Full instructions are in the help, but basically, any macro or group can be restored with a few clicks (and an important renaming step within KM first).

HOW SAFE IS IT TO USE?

It's incredibly safe to use, because it doesn't touch any of your macros (see above, i.e. why it's not a restore tool as well). The only work that happens within Keyboard Maestro is the initial export of your collection, using Keyboard Maestro's own Export All Macros as Folder option.

After that, everything that happens is working with the files on the drive, not the macros in your collection. During development. I have run the macro over 2,500 times, and not once have I had an issue with my macros, nor the backing up of my macros.

You may see issues with the analysis. You may see issues with a Finder label not being able to be applied. You may see some other issue. But none of these will be about the backup itself, which I've found to be perfect (because KM is doing the work!) every time.

So yes, it's very safe to use.

CONCLUSION

I've tried to make MBU as simple to use as possible; there are only a handful of settings on first run (along with a one-time-only intro screen). During each backup, progress bars let you know what's going on, and certain events are communicated via notifications if necessary.

There's a relatively detailed help page for MBU, and the "Info: Read Me First!" macro contains a condensed version of the help file's key points.

If you've been looking for an easy-to-use somewhat-versioned-like backup system for your macros, give MBU a try and let me know what you think. For me, it's already turned into an essential tool, and I used it a few times during development to get an older version of the macro back.

-rob.

18 Likes

Wow... I don’t really know what to say except, well done. Quick question (this may be answered in the extensive documentation and I’ve simply missed it): does the backup cancel if there have been no changes since the last backup? I’m assuming it doesn’t since it appears to run it’s comparisons after exporting the macro library... just curious. :wink:

1 Like

Yea, it can't cancel because it doesn't know there aren't any changes until it does the backup. (Is there a way to test that within KM? That'd be really handy if so. Are there tokens that could be checked to see what's changed?)

The upside is that if there aren't any changes, the resulting backup will be tiny—I just ran two of them about two seconds apart, and the second backup was all of 84KB. So you lose 20 seconds or so and a bit of drive space if there weren't any changes.

If anyone knows of a way to tell what, if anything, has changed before exporting, that would enable a feature that would really speed up the backups: Instead of exporting all, MBU could just export those that had changed (though figuring out how to do that might be a bit tricky), and then copy the existing hard links for all the other files.

Edit: Thinking about it, it'd be more complicated than that. I'd somehow have to be able to track if a given macro had changed since the last time the macro was run. If the info is available on each macro group's last modification time, I could write a global with the last run time of MBU, and then select based on anything that was modified since then.

Edit 2: Hey wow, you asked about this very thing, and found an answer! OK, so that's something to play with, though ideally, I just need it at the group level: If a group has been modified since the last MBU run, it needs to be exported.

-rob.

3 Likes

Haha that’s why I was wondering if your macro Incorporated something similar. In my case, I have several macros whose only changes are being enabled/disabled, or one whose title is dynamically updated to whatever Apple Music song is being played. Obviously, those are changes I care nothing about for backup purposes, so I wanted a way to exclude them from my own backup system.

You're welcome, @griffman. It's been my pleasure helping you test MacroBackerUpper.


Keyboard Maestro Forum Community: I've seen the incredible work and attention to detail that went into the development of this macro group. I've been enjoying its benefits and I strongly recomment that you give it a try.

2 Likes

I second this 100%.

MBU is simple to set up and dead easy to use and it does the job very efficiently.

I will be continuing to use it regularly.

Big shout out to Rob (@griffman) for investing so much time and effort!

2 Likes

This is an impressive amount of work you have done.

I have now downloaded it and the setup is done, but it stops during the start of the backup.
In the setup I choose all the defaults and selected a local folder.

The process bar ends up here and then no macros are running.

This is in KM 11.0.1 with macOS Sonoma 14.1.

Jimmy:

That's not good :frowning: ... and none of us saw that during our testing, at least not after the early tries. I've sent you a DM with some instructions on getting me some debug info that should let me track down the problem quickly.

Edit: I just tested on my macOS 14.1/KM 11.0.1 installation, starting with the download here and going through the full setup, and it all ran fine. Very strange.

-rob.

1 Like

I have just send you a message.

FWIW, I had an issue this morning with an (-600) AppleScript error (it claimed Keyboard Maestro was not running), and if I recall correctly, it was around the same part of the process.

Here’s the Log entry:

2023-11-08 06:24:10 GetProcessForPID(2164) failed with -600 for <KBMRunningApplication “Keyboard Maestro” <0x600001c9c160> pid=2164 bid=com.stairways.keyboardmaestro.editor abht>, using cached version
1 Like

DM'd you for more info ... and why does this stuff never come out during 3,000 trial runs across three testers?!

-rob.

2 Likes

Haha well not everybody has the stupid -600 error nonsense... but I have it often enough (and across multiple devices) that I started including in any AppleScript I write the following to ensure I don’t get them (substituting whatever app I am calling):

if application "Keyboard Maestro Engine" is not running then tell application "Keyboard Maestro Engine" to launch
2 Likes

I'll add that bit, thanks!

-rob.

3 Likes

Chris - Oddly, after I'd upgraded to KM 11 I started getting error -600s in many of my AppleScripts but they were related to System Events not running. After a lot of searching I came across this tip in the Late Night Software forum:

tell application "System Events" to activate
tell application "System Events"
...

which cleared the problem completely.

I was just wondering if this might work for your case?

e.g.

tell application "Keyboard Maestro Engine" to activate
tell application "Keyboard Maestro Engine"
...
2 Likes

Hey @tiffle, yes that is the solution I use as well, just prepending any tell application "System Events" block with the activate command.

I might be remembering wrong now, but I seem to recall a handful of times where it was other applications returning the -600 errors, which is why I typically just prepend any tell block with that same command.

EDIT: For a little background on my AppleScript progression... I used to use the following setup to “avoid” these errors...

set apscDone1 to false
set loopCount1 to 0
repeat until apscDone1 is true or loopCount1 is 15
	try
		
		# COMMANDS GO HERE
		
		set apscDone1 to true
	on error
		set apscDone1 to false
		set loopCount1 to loopCount1 + 1
	end try
end repeat

Then I realized I could make things a lot simpler by just activating the offending application :sweat_smile:

1 Like

Hi Rob @griffman,
just downloaded your macro and came across the same issue as Jim . Stuck at the setup (Sonoma 14.1 Macbook Air M2)

Dang, I am baffled. I can't replicate here, nor did we see this at all during testing. Sending you a DM.

-rob.

1 Like

Just did a backup and the new folder was created but not renamed as follows:

image

Maybe a timing issue when it comes to renaming the folder?

Or could it be to do with me having 2 KM Editor windows open?

Also, __latest points to the properly-named (previous) folder...

That looks like an annoying timing issue—was the hard drive asleep, perhaps? I saw this like three times during testing, but wasn't sure how to check/fix it. But maybe I can check the folder name at the end of the export, and if it's "Untitled Macros Folder," then change it.

That'll be tricky to test, though. But I think I'll probably do it anyway and then see if anyone has issues—the code would only execute if it sees that name, so should be safe for everyone in general.

thanks;
-rob.

3 Likes

Nope - it's an SSD.

Sounds like a plan.