Files
tatlock-ui/ci/check_codegen.sh
jpmschweitzer f04672f350 build(make): prove setup converged instead of trusting build_runner's exit code
`make setup` ran build_runner and reported success whether it produced the
39 files a fresh clone needs or almost nothing. `flutter test`'s only guard
checked a single sentinel file, which is why the 2026-08-09 4-of-46 gap
still read as 26 passed / 17 failed instead of a missing build step.

ci/check_codegen.sh walks every `part` directive under lib/ and confirms
the sibling file it names exists, then wires into both `setup` (fail loud
right after codegen if it under-produced) and `test` (fail loud, exit 69,
if nobody ran setup at all). Replaces the one-file guard, which would have
missed 44 of the 45 directives that exist today.
2026-08-17 12:05:06 +02:00

51 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Prove that generated sources exist for every part directive that requires
# one, after `make generate` has run. Lives here rather than inline in the
# Makefile so it can be read, run by hand (`make check-codegen`), and changed
# under review — same reasoning as ci/secrets.sh (D-27).
set -euo pipefail
cd "$(git rev-parse --show-toplevel)"
# *.freezed.dart and lib/**/*.g.dart are gitignored, so a fresh or stale
# checkout can silently have some but not all of the files a `part`
# directive names. `dart run build_runner build` exits 0 whether it produced
# everything the tree needs or almost nothing — exit code is not evidence
# (T-47). What IS evidence: every `part '<name>';` directive in lib/ names a
# sibling file, and that file either exists or it doesn't. This walks every
# directive and checks its target directly, rather than trusting a single
# sentinel file (the old `test` guard checked one file,
# user_preferences.freezed.dart, and would have missed 44 other gaps).
#
# On 2026-08-09 this exact condition was 4 generated files present where 46
# were needed. `flutter analyze` would also catch it, but slower and later —
# this check is the cheapest thing that proves the same fact.
missing=0
checked=0
while IFS=: read -r file part_line; do
# grep -H prefixes exactly one "file:" — no line numbers, so a colon
# inside the match (there is none here, but be safe) can't split wrong.
# part_line looks like: part 'auth_state.freezed.dart';
target=$(printf '%s' "$part_line" | sed -E "s/^part '([^']+)';.*/\1/")
dir=$(dirname "$file")
checked=$((checked + 1))
if [ ! -f "$dir/$target" ]; then
echo "MISSING generated file: $dir/$target (required by 'part' directive in $file)" >&2
missing=$((missing + 1))
fi
done < <(grep -rH "^part '" lib --include='*.dart')
if [ "$checked" -eq 0 ]; then
echo "FAIL check-codegen — found zero 'part' directives under lib/; the check itself is broken, not the tree." >&2
exit 1
fi
if [ "$missing" -gt 0 ]; then
echo "FAIL check-codegen — $missing of $checked generated files are missing. Run: make generate" >&2
exit 1
fi
echo "check-codegen — $checked/$checked generated files present."