From 9838f682dba9ef2954ed2c65ea5adbc32b8bfc6c Mon Sep 17 00:00:00 2001 From: Darrell van Swinderen Date: Tue, 22 Sep 2026 23:58:29 +0200 Subject: [PATCH] fix(scripts): a second OBS backup on one day gets its own folder The folder is named after the date, so a second run the same day copied into the first one's folder, hashed that run's `hashes.json` and `MANIFEST.txt` as if they were OBS files, rewrote them, and then reported both as different: VERIFICATION FAILED on a good backup. Found taking the backup before running dev against the real library. A run now picks `obs--2`, `-3` and so on when the folder or its zip exists. Two runs back to back: both "Verified". Co-Authored-By: Claude Opus 5.5 (1M context) --- scripts/obs-backup.mjs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/scripts/obs-backup.mjs b/scripts/obs-backup.mjs index 753e3ffa..1338975f 100644 --- a/scripts/obs-backup.mjs +++ b/scripts/obs-backup.mjs @@ -43,8 +43,27 @@ const EXTRAS = [ ]; const stamp = new Date().toISOString().slice(0, 10); -const destination = - process.argv[2] ?? path.join(os.homedir(), 'Documents', 'GoodBit backups', `obs-${stamp}`); + +/* + * A folder of its own every run, even twice in one day. + * + * The name is the date, so a second run the same day copied into the first + * run's folder: its `hashes.json` and `MANIFEST.txt` were hashed as if they + * were OBS's own files, then rewritten, and the read back reported both as + * different. A verification that fails on a good backup teaches somebody to + * ignore it on a bad one. + */ +function freshFolder(base) { + if (!existsSync(base) && !existsSync(`${base}.zip`)) return base; + for (let n = 2; ; n++) { + const candidate = `${base}-${n}`; + if (!existsSync(candidate) && !existsSync(`${candidate}.zip`)) return candidate; + } +} + +const destination = freshFolder( + process.argv[2] ?? path.join(os.homedir(), 'Documents', 'GoodBit backups', `obs-${stamp}`), +); /** Every file under a directory, relative to it. */ function walk(root, prefix = '') {