Skip to content

Commit 9ed57ab

Browse files
sbryngelsonclaude
andcommitted
Cache Fortran format hashes to skip unchanged files (10s -> 2s)
Store per-file md5 hashes in build/.cache/format/ after formatting. On subsequent runs, only re-format files whose hash changed. Combined with parallel precheck, total precommit time drops from 35s to 13s. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7da4061 commit 9ed57ab

1 file changed

Lines changed: 44 additions & 22 deletions

File tree

toolchain/bootstrap/format.sh

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,32 +56,54 @@ FORTRAN_FILES=$(find $FORTRAN_DIRS -type f 2>/dev/null | grep -Ev 'autogen' | gr
5656
if [[ -n "$FORTRAN_FILES" ]]; then
5757
FPRETTIFY_OPTS="--silent --indent 4 --c-relations --enable-replacements --enable-decl --whitespace-comma 1 --whitespace-multdiv 0 --whitespace-plusminus 1 --case 1 1 1 1 --strict-indent --line-length 1000"
5858

59-
for niter in 1 2 3 4; do
60-
old_hash=$(echo "$FORTRAN_FILES" | xargs cat | md5sum)
61-
62-
# Run indenter on all files in one process
63-
if ! echo "$FORTRAN_FILES" | xargs python3 toolchain/indenter.py; then
64-
error "Formatting Fortran files failed: indenter.py."
65-
exit 1
59+
# Skip files unchanged since last format (hash cache in build/.cache/format/)
60+
CACHE_DIR="build/.cache/format"
61+
mkdir -p "$CACHE_DIR"
62+
DIRTY_FILES=""
63+
for f in $FORTRAN_FILES; do
64+
cache_key=$(echo "$f" | tr '/' '_')
65+
current_hash=$(md5sum "$f" | cut -d' ' -f1)
66+
cached_hash=$(cat "$CACHE_DIR/$cache_key" 2>/dev/null || true)
67+
if [[ "$current_hash" != "$cached_hash" ]]; then
68+
DIRTY_FILES+="$f"$'\n'
6669
fi
70+
done
71+
DIRTY_FILES=$(echo "$DIRTY_FILES" | sed '/^$/d')
6772

68-
# Run fprettify in parallel (one process per file)
69-
if ! echo "$FORTRAN_FILES" | xargs -P ${JOBS:-1} -L 1 fprettify $FPRETTIFY_OPTS; then
70-
error "Formatting Fortran files failed: fprettify."
71-
exit 1
72-
fi
73+
if [[ -n "$DIRTY_FILES" ]]; then
74+
for niter in 1 2 3 4; do
75+
old_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum)
7376

74-
new_hash=$(echo "$FORTRAN_FILES" | xargs cat | md5sum)
75-
if [[ "$old_hash" == "$new_hash" ]]; then
76-
break
77-
fi
78-
if [[ "$niter" -eq 4 ]]; then
79-
error "Formatting Fortran files failed: no steady-state after $niter iterations."
80-
exit 1
81-
fi
82-
done
77+
# Run indenter on dirty files in one process
78+
if ! echo "$DIRTY_FILES" | xargs python3 toolchain/indenter.py; then
79+
error "Formatting Fortran files failed: indenter.py."
80+
exit 1
81+
fi
82+
83+
# Run fprettify in parallel (one process per file)
84+
if ! echo "$DIRTY_FILES" | xargs -P ${JOBS:-1} -L 1 fprettify $FPRETTIFY_OPTS; then
85+
error "Formatting Fortran files failed: fprettify."
86+
exit 1
87+
fi
88+
89+
new_hash=$(echo "$DIRTY_FILES" | xargs cat | md5sum)
90+
if [[ "$old_hash" == "$new_hash" ]]; then
91+
break
92+
fi
93+
if [[ "$niter" -eq 4 ]]; then
94+
error "Formatting Fortran files failed: no steady-state after $niter iterations."
95+
exit 1
96+
fi
97+
done
98+
99+
# Update hash cache for formatted files
100+
for f in $DIRTY_FILES; do
101+
cache_key=$(echo "$f" | tr '/' '_')
102+
md5sum "$f" | cut -d' ' -f1 > "$CACHE_DIR/$cache_key"
103+
done
83104

84-
echo "$FORTRAN_FILES" | while read -r f; do echo "> $f"; done
105+
echo "$DIRTY_FILES" | while read -r f; do echo "> $f"; done
106+
fi
85107
fi
86108

87109
# Apply safe auto-fixes (import sorting, etc.) before formatting.

0 commit comments

Comments
 (0)