feat: selective sub-path backup for volatile dot-dirs

Mackup with engine=file_system already uses symlinks for all backed-up
apps (/Users/osurke/.docker → <cloud>/Mackup/mackup/.docker). The copy PHASE
fails when the source dir contains sockets or dangling symlinks.

For dirs like .claude that have a volatile debug/ subdir, the clean fix
is to list only the stable sub-paths in the Mackup cfg rather than the
whole directory — debug/ is never touched.

_SSR_MACKUP_SELECTIVE: built-in overrides for .claude, .cursor, .codex,
.vscode, .factory — lists only config files (settings.json, CLAUDE.md,
skills, plugins, agents, …), skipping logs/, debug/, etc.

_ssr_mackup_resolve_paths(): resolves the [configuration_files] entries
for a given item using the selective table, falling back to the whole dir.

ssr mackup scan now shows '6 sub-path(s) of .claude/' in the plan
instead of '.claude/' to make the selective behaviour visible.

Configurable via SSR_MACKUP_SELECTIVE_PATHS in ssr.conf.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-12 14:58:16 +02:00
parent 36d4941c95
commit 93c23c60a9
3 changed files with 78 additions and 7 deletions
+14 -4
View File
@@ -90,11 +90,12 @@ cmd_scan() {
local -a labels=()
local -a cfg_paths=()
local it app_name desired existing cfg_file
local it app_name desired existing cfg_file paths_block
for it in "${items[@]:-}"; do
app_name="$(_ssr_mackup_cfg_name "$it")"
cfg_file="$cfg_dir/${app_name}.cfg"
desired="$(printf '[application]\nname = %s\n\n[configuration_files]\n%s\n' "$app_name" "$it")"
paths_block="$(_ssr_mackup_resolve_paths "$it")"
desired="$(printf '[application]\nname = %s\n\n[configuration_files]\n%s\n' "$app_name" "$paths_block")"
if [[ -f "$cfg_file" ]]; then
existing="$(cat "$cfg_file")"
if [[ "$existing" == "$desired" ]]; then
@@ -123,8 +124,17 @@ cmd_scan() {
local path="${cfg_paths[$i]##*/}"
local colour
[[ "$label" == "NEW" ]] && colour="\033[32m" || colour="\033[33m"
printf " ${colour}%s\033[0m %-38s (%s)\n" \
"$label" "~/.mackup/$path" "${to_write[$i]}"
# Show resolved paths (selective or whole dir).
local resolved; resolved="$(_ssr_mackup_resolve_paths "${to_write[$i]}")"
local line_count; line_count="$(printf '%s\n' "$resolved" | wc -l | tr -d ' ')"
local paths_hint
if [[ "$line_count" -eq 1 && "$resolved" == "${to_write[$i]}" ]]; then
paths_hint="${to_write[$i]}/" # whole directory
else
paths_hint="$line_count sub-path(s) of ${to_write[$i]}/"
fi
printf " ${colour}%s\033[0m %-38s %s\n" \
"$label" "~/.mackup/$path" "$paths_hint"
done
fi