From 2fac1ecba063baf0b63dad5b8035c2c8998c1ba2 Mon Sep 17 00:00:00 2001 From: Jacob Hagstedt Date: Sun, 18 Oct 2026 22:11:07 +0200 Subject: [PATCH] tools: one Gradle lock helper (gradle-lock.sh) for gradle-serial.sh and clean-builds.sh Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B --- tools/clean-builds.sh | 12 ++++-------- tools/gradle-lock.sh | 24 ++++++++++++++++++++++++ tools/gradle-serial.sh | 12 ++++-------- 3 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 tools/gradle-lock.sh diff --git a/tools/clean-builds.sh b/tools/clean-builds.sh index 53dbfba..4fe2755 100755 --- a/tools/clean-builds.sh +++ b/tools/clean-builds.sh @@ -5,6 +5,8 @@ # 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] +# shellcheck source-path=SCRIPTDIR source=gradle-lock.sh +. "$(dirname "$0")/gradle-lock.sh" dry=0 case "$1" in --dry-run) dry=1 ;; @@ -39,14 +41,8 @@ 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 + gradle_lock_acquire + trap 'rm -rf "$KVITT_GRADLE_LOCK"; rm -f "$list"' EXIT INT TERM HUP fi total=0 diff --git a/tools/gradle-lock.sh b/tools/gradle-lock.sh new file mode 100644 index 0000000..910800f --- /dev/null +++ b/tools/gradle-lock.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# The one-Gradle-build-at-a-time lock (CLAUDE.md › Build and verify). Sourced, not run, by tools/gradle-serial.sh, +# tools/clean-builds.sh, infra/dev/build.sh and infra/build-images.sh; plain POSIX sh, so sh and bash scripts share it. +# The lock is a directory holding the pid of its owner; a lock whose owner has died is taken over. +# shellcheck disable=SC2034 # KVITT_GRADLE_LOCK is used by the scripts that source this file +KVITT_GRADLE_LOCK=/tmp/kvitt-gradle.lock + +# Prints the pid of the live process holding the lock and succeeds; fails when nobody holds it. +gradle_lock_holder() { + _pid=$(cat "$KVITT_GRADLE_LOCK/pid" 2>/dev/null) || return 1 + [ -n "$_pid" ] && kill -0 "$_pid" 2>/dev/null || return 1 + printf '%s\n' "$_pid" +} + +# Waits until the lock is free, then takes it for this shell ($$). The caller removes it on exit: +# trap 'rm -rf "$KVITT_GRADLE_LOCK"' EXIT INT TERM HUP +gradle_lock_acquire() { + while ! mkdir "$KVITT_GRADLE_LOCK" 2>/dev/null; do + _pid=$(cat "$KVITT_GRADLE_LOCK/pid" 2>/dev/null) + if [ -n "$_pid" ] && ! kill -0 "$_pid" 2>/dev/null; then rm -rf "$KVITT_GRADLE_LOCK"; continue; fi + sleep 5 + done + echo $$ > "$KVITT_GRADLE_LOCK/pid" +} diff --git a/tools/gradle-serial.sh b/tools/gradle-serial.sh index f9befb4..c7d7a04 100755 --- a/tools/gradle-serial.sh +++ b/tools/gradle-serial.sh @@ -3,14 +3,10 @@ # (CLAUDE.md › Build and verify: parallel builds exhaust memory). Waits for a running build to finish, then runs. # The Gradle project lives in android/; the wrapper there is used whatever directory this is started from. # Usage from any directory of a checkout or worktree: tools/gradle-serial.sh check (or ../tools/gradle-serial.sh from android/) -lock=/tmp/kvitt-gradle.lock +# shellcheck source-path=SCRIPTDIR source=gradle-lock.sh +. "$(dirname "$0")/gradle-lock.sh" top=$(git rev-parse --show-toplevel) || exit 1 [ -x "$top/android/gradlew" ] || { echo "gradle-serial: no android/gradlew in $top yet" >&2; exit 1; } -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"' EXIT INT TERM HUP +gradle_lock_acquire +trap 'rm -rf "$KVITT_GRADLE_LOCK"' EXIT INT TERM HUP cd "$top/android" && ./gradlew "$@"