#!/bin/sh # Deletes Gradle and Kotlin build output in the main checkout and in every agent worktree (.claude/worktrees/*): # each project's build/ (a directory named build next to a build.gradle.kts or settings.gradle.kts), .gradle/configuration-cache # and .kotlin. Never looks into export/, libs/, models/, spike/ or "samsung sdk/", and never deeper than four levels. # Prints what it removes and the space freed. Waits for the Gradle lock of tools/gradle-serial.sh, so it never deletes # under a running build. The orchestrator runs it after removing a worktree or when the disk is low. # Usage from any checkout: tools/clean-builds.sh [--dry-run] dry=0 case "$1" in --dry-run) dry=1 ;; "") ;; *) echo "usage: $0 [--dry-run]" >&2; exit 2 ;; esac common=$(git rev-parse --path-format=absolute --git-common-dir) || exit 1 main=$(dirname "$common") # Candidates under one checkout root; .claude is skipped here because the worktrees are walked as roots of their own. candidates() { find "$1" -maxdepth 4 \ \( -path "$1/export" -o -path "$1/libs" -o -path "$1/models" -o -path "$1/spike" -o -path "$1/samsung sdk" \ -o -path "$1/.claude" -o -name .git -o -name src -o -name node_modules \) -prune \ -o -type d \( -name build -o -name .kotlin -o -path '*/.gradle/configuration-cache' \) -print -prune } list=$(mktemp) || exit 1 trap 'rm -f "$list"' EXIT for root in "$main" "$main"/.claude/worktrees/*; do [ -d "$root" ] || continue candidates "$root" | while IFS= read -r dir; do if [ "$(basename "$dir")" = build ]; then parent=$(dirname "$dir") [ -f "$parent/build.gradle.kts" ] || [ -f "$parent/settings.gradle.kts" ] || continue fi printf '%s\n' "$dir" done done > "$list" if [ ! -s "$list" ]; then echo "Nothing to remove."; exit 0; fi if [ "$dry" -eq 0 ]; then lock=/tmp/kvitt-gradle.lock while ! mkdir "$lock" 2>/dev/null; do pid=$(cat "$lock/pid" 2>/dev/null) if [ -n "$pid" ] && ! kill -0 "$pid" 2>/dev/null; then rm -rf "$lock"; continue; fi sleep 5 done echo $$ > "$lock/pid" trap 'rm -rf "$lock"; rm -f "$list"' EXIT INT TERM HUP fi total=0 while IFS= read -r dir; do kb=$(du -sk "$dir" 2>/dev/null | cut -f1) kb=${kb:-0} total=$((total + kb)) printf '%8d MB %s\n' $((kb / 1024)) "${dir#"$main"/}" [ "$dry" -eq 1 ] || rm -rf "$dir" done < "$list" if [ "$dry" -eq 1 ]; then verb="Would free"; else verb="Freed"; fi echo "$verb $((total / 1024)) MB in $(wc -l < "$list" | tr -d ' ') directories."