fix: pos media sync — normalize trailing-slash source + surface find errors

This commit is contained in:
Your Name
2026-08-16 04:02:05 -04:00
parent 2554696cfa
commit ba12a418ff
4 changed files with 44 additions and 4 deletions
+40 -2
View File
@@ -69,8 +69,26 @@ while [[ $# -gt 0 ]]; do
done
[ "$MP3" -eq 1 ] || [ "$MP4" -eq 1 ] || { MP3=1; MP4=1; }
# Normalize a trailing slash on the source: GNU find strips it on the starting
# point (find -H /x/ -type f emits /x/a.mp3, not /x//a.mp3), so with
# SRC=/x/ the rel prefix "${f#"$SRC/"}" becomes /x// which never matches and
# files would nest under <stick>/Music//x/... instead of mirroring the tree.
# Covers both --source /x/ and MEDIA_SYNC_SOURCE=.../.
SRC="${SRC%/}"
[ -n "$SRC" ] || err "Source not found: $SRC"
[ -d "$SRC" ] || err "Source not found: $SRC"
# find -H follows only the command-line source symlink; symlinks INSIDE the
# tree are never followed, so their targets silently never sync. Count them
# (mindepth 1: a symlink source itself IS followed and must not count) and
# surface the skip instead of leaving a partial mirror unexplained.
inner_links="$(find -H "$SRC" -mindepth 1 -type l 2>/dev/null | wc -l)" || true
inner_links="${inner_links// }"
if [ "$inner_links" -gt 0 ]; then
warn "${inner_links} symlink(s) inside the source are not followed (find -H) — their targets will not be synced"
fi
trap 'notify_send "Music sync FAILED"' ERR
section "Music sync"
@@ -112,6 +130,26 @@ if [ "$DRY_RUN" -eq 0 ]; then
mkdir -p "$dest_root"
space_path="$dest_root"
fi
# One find pass into a temp list, sorted once, shared by the space scan and
# the copy loop so both see the identical file set (the old double find is
# gone). The old process substitution swallowed find's exit code and stderr
# (invisible to set -e / pipefail): an unreadable subdir made find exit 1
# with "Permission denied" yet the tool still announced a false "Sync
# complete" on a partial tree. Capture both and surface them explicitly
# instead of continuing silently.
find_list="$(mktemp)"
find_err="$(mktemp)"
trap 'rm -f "$find_list" "$find_err"' EXIT
find_rc=0
find -H "$SRC" "${find_expr[@]}" >"$find_list" 2>"$find_err" || find_rc=$?
sort -o "$find_list" "$find_list"
if [ "$find_rc" -ne 0 ] || [ -s "$find_err" ]; then
warn "find of the source reported problems — results may be incomplete:"
if [ -s "$find_err" ]; then
sed 's/^/ /' "$find_err"
fi
fi
need_kb=0
while IFS= read -r f; do
rel="${f#"$SRC/"}"
@@ -119,7 +157,7 @@ while IFS= read -r f; do
sz="$(stat -c %s "$f" 2>/dev/null || printf 0)"
need_kb=$((need_kb + (sz + 1023) / 1024))
fi
done < <(find -H "$SRC" "${find_expr[@]}")
done < "$find_list"
have_kb="$(df -Pk "$space_path" 2>/dev/null | awk 'NR==2 {print $4}')"
have_kb="${have_kb:-0}"
if [ "$need_kb" -gt "$have_kb" ]; then
@@ -154,7 +192,7 @@ while IFS= read -r f; do
else
unchanged=$((unchanged + 1))
fi
done < <(find -H "$SRC" "${find_expr[@]}" | sort)
done < "$find_list"
if [ "$DRY_RUN" -eq 1 ]; then
echo "DRY RUN — nothing copied. Would sync: ${added} new, ${updated} updated, ${unchanged} unchanged → $dest_root"