fix(mackup): safer defaults + recovery after broken symlink sync

- Default-off SSR_MACKUP_PRESYMLINK for DynamicProfiles pre-symlink (was
  risking empty/wrong iCloud trees and breaking iTerm2).
- Remove incorrect skip entries: built-in cfgs use different paths than
  ~/.zsh, ~/.vscode*, ~/.iterm2 — skipping hid real overlap from scan only
  but the presymlink change was the main footgun.
- Add `ssr mackup unlink` → `mackup -f link uninstall` to copy configs back
  from Mackup storage and drop symlinks (official undo).
- Docs: ssr.conf.example, README sync/restore wording, completions.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-12 20:09:23 +02:00
parent ccc1db1e93
commit 51fb589ef2
8 changed files with 71 additions and 42 deletions
+3 -3
View File
@@ -27,14 +27,14 @@ Usage:
Commands:
install First-time install: links binary, seeds config, schedules sync.
sync Run a backup: brew bundle dump + mackup backup → cloud.
restore [Brewfile] Restore a machine: brew bundle + mackup restore + macOS defaults.
sync Run a backup: brew bundle dump + mackup link install → cloud.
restore [Brewfile] Restore a machine: brew bundle + mackup link + macOS defaults.
update [--dry-run] Pull latest ssr code, refresh launchd if needed.
schedule on|off Enable/disable the scheduled launchd sync job.
config show|edit Print or edit the active config file.
completions Install or remove shell completions (zsh/bash/fish).
status Show last sync time, cloud target, and scheduled state.
mackup scan|list|clean Manage auto-generated Mackup app definitions.
mackup scan|list|clean|unlink Mackup ssr-*.cfg helpers + symlink revert.
version Print version.
Options:
+36 -10
View File
@@ -2,10 +2,11 @@
# ssr-mackup — Manage auto-generated Mackup app definitions for dot-dirs.
#
# Subcommands:
# scan Dry-run: show which ssr-*.cfg files would be created / updated,
# then ask for confirmation before writing anything.
# list List existing ~/.mackup/ssr-*.cfg files with the path they cover.
# clean Remove all generated ssr-*.cfg files (prompts first).
# scan Per-item prompts for new ~/.mackup/ssr-*.cfg files.
# list List existing ~/.mackup/ssr-*.cfg files with the path they cover.
# clean Remove all generated ssr-*.cfg files (prompts first).
# unlink Run `mackup link uninstall` — copy configs back from Mackup
# storage and remove symlinks (fixes broken iTerm / shell paths).
set -euo pipefail
SSR_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -27,12 +28,17 @@ Manage auto-generated Mackup app definitions for dot-dirs not covered
by Mackup's built-in app definitions.
Subcommands:
scan Show suggested ~/.mackup/ssr-*.cfg files and confirm before writing.
scan Suggest new ~/.mackup/ssr-*.cfg files (confirm each item).
list List existing generated files.
clean Remove all generated ssr-*.cfg files.
unlink Revert Mackup symlinks (copy from cloud → real files in ~).
Run 'ssr mackup scan' once after install (or whenever new dot-dirs appear)
and commit the generated files alongside your dotfiles.
Run 'ssr mackup scan' when new dot-dirs appear; commit ~/.mackup/ssr-*.cfg
with your dotfiles if you use them.
If Terminal/iTerm or other apps break after sync, run:
ssr mackup unlink
That runs Mackup's official undo for symlink-based installs.
EOF
}
@@ -245,15 +251,35 @@ cmd_clean() {
ssr::ok "Removed ${#found[@]} file(s)."
}
# ---------------------------------------------------------------------------
# unlink — mackup link uninstall (recovery)
# ---------------------------------------------------------------------------
cmd_unlink() {
cat <<'EOF'
This runs: mackup -f link uninstall
Mackup copies each managed path from your Mackup storage folder back into
$HOME and removes the symlinks. Use when settings broke after `ssr sync` /
`mackup link install` (e.g. iTerm2, shell init files pointing at iCloud).
After unlink, apps use normal local files again. Run `ssr sync` only when
you are ready to re-apply symlink-based backup.
EOF
printf '\n'
ssr::confirm "Run mackup link uninstall now?" 120 || { printf 'Aborted.\n'; return 0; }
ssr::mackup::link_uninstall && ssr::ok "mackup link uninstall finished."
}
# ---------------------------------------------------------------------------
# Dispatch
# ---------------------------------------------------------------------------
[[ $# -gt 0 ]] || { usage; exit 1; }
case "$1" in
scan) cmd_scan ;;
list) cmd_list ;;
clean) cmd_clean ;;
scan) cmd_scan ;;
list) cmd_list ;;
clean) cmd_clean ;;
unlink) cmd_unlink ;;
-h|--help) usage ;;
*) ssr::err "Unknown subcommand: $1"; usage; exit 1 ;;
esac