From 1175756e23622cf2d654cfc34666f3194fb6791c Mon Sep 17 00:00:00 2001 From: andrussal Date: Sat, 20 Dec 2025 07:12:44 +0100 Subject: [PATCH] ops: make clean target removal resilient Add retries and macOS flag/permission cleanup when removing target/.tmp so clean doesn't fail with transient 'Directory not empty' during concurrent builds (e.g. rust-analyzer/cargo). --- scripts/ops/clean.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/scripts/ops/clean.sh b/scripts/ops/clean.sh index f106de0..740752f 100755 --- a/scripts/ops/clean.sh +++ b/scripts/ops/clean.sh @@ -62,6 +62,29 @@ clean::rm_path() { local path="$1" if [ -e "${path}" ]; then echo "==> Removing ${path}" + # On macOS, IDE tooling (rust-analyzer) or background cargo processes can + # repopulate `target/` while we're deleting it, leading to "Directory not + # empty" failures. Be resilient with a short retry loop and best-effort + # permission/flag cleanup. + local attempt=1 + local max_attempts=5 + while [ "${attempt}" -le "${max_attempts}" ]; do + rm -rf "${path}" 2>/dev/null || true + + if [ ! -e "${path}" ]; then + return 0 + fi + + if [ "$(uname -s 2>/dev/null || true)" = "Darwin" ] && clean::have chflags; then + chflags -R nouchg,noschg "${path}" 2>/dev/null || true + fi + chmod -R u+w "${path}" 2>/dev/null || true + + sleep "0.${attempt}" + attempt=$((attempt + 1)) + done + + # Final attempt with stderr so the failure mode is visible. rm -rf "${path}" else echo "==> Skipping missing ${path}"