Add a pre-commit gate against a local crdt_sync dependency_override
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
Tests / test (3.10) (push) Has been cancelled
Tests / test (3.11) (push) Has been cancelled
Tests / test (3.12) (push) Has been cancelled
Tests / lock-popup-safety (push) Has been cancelled
release-apk / release (APK) (push) Has been cancelled

A dependency_override pointing crdt_sync at a local path is invaluable
while developing an unreleased library change, and silently catastrophic
if it survives the commit: local tests go green against code CI never
built. Enforce it can't ship instead of relying on someone remembering
to remove it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013SH7XBkpEqQX4KghHdgx9T
This commit is contained in:
Krzysztof Rudnicki 2026-08-12 19:18:21 +02:00
parent 507030d63b
commit 3a5f0962de
2 changed files with 96 additions and 0 deletions

View File

@ -138,6 +138,14 @@ repos:
- repo: local
hooks:
# Fails a commit that still points crdt_sync at a local path. Local
# tests would go green against a library CI has never seen, silently.
- id: crdt-sync-override
name: no local crdt_sync dependency_override
entry: bash scripts/check_no_crdt_sync_override.sh stronglift_replacement/workout_app/pubspec.yaml
language: system
pass_filenames: false
always_run: true
- id: shellcheck
name: shellcheck
entry: bash -c 'printf "%s\0" "$@" | xargs -0 -n 40 shellcheck --severity=warning' --

View File

@ -0,0 +1,88 @@
#!/bin/bash
# ============================================================================
# Fail if a pubspec still overrides crdt_sync with a local path.
#
# The apps depend on crdt_sync as a *git dependency pinned to a tag*, so what
# CI builds is whatever that tag points at. A `dependency_overrides:` entry
# pointing at ~/utils/crdt_sync_dart is invaluable while developing an unreleased
# library change -- and catastrophic if it survives the commit: local tests go
# green against code CI has never seen, and the failure is silent in both
# directions.
#
# A comment in the pubspec asking someone to remember is deployment hygiene,
# not a fix. This is the gate.
#
# Usage: check_no_crdt_sync_override.sh [pubspec.yaml ...]
# With no arguments, checks ./pubspec.yaml.
# ============================================================================
set -euo pipefail
SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_NAME
usage() {
echo "Usage: $SCRIPT_NAME [pubspec.yaml ...]"
echo " Fails when a pubspec overrides crdt_sync with a local path."
exit 0
}
# Returns 0 (found) when the file has a crdt_sync entry under
# dependency_overrides. Deliberately a small state machine rather than a grep:
# `path:` appears under plenty of other keys, and a false positive here blocks
# a legitimate commit.
has_override() {
local file="$1"
awk '
# Track indent depth explicitly. An earlier version used an awk
# interval expression ({1,4}) to spot a sibling key, which plain awk
# does not enable by default -- so the check silently never fired and
# reported every file clean. A safety check that fails open is worse
# than none, so this version is written to be obvious instead of terse.
function indent(line, n) {
n = match(line, /[^ ]/)
return (n == 0) ? 0 : n - 1
}
/^[[:space:]]*#/ { next } # comments
/^[[:space:]]*$/ { next } # blank lines
/^dependency_overrides:[[:space:]]*$/ { in_overrides = 1; next }
/^[^[:space:]]/ { in_overrides = 0; in_crdt = 0; next }
in_overrides {
if ($0 ~ /^[[:space:]]+crdt_sync:[[:space:]]*$/) {
in_crdt = 1
crdt_indent = indent($0)
next
}
# Any key at or above crdt_sync{s} own indent ends its block.
if (in_crdt && indent($0) <= crdt_indent) { in_crdt = 0 }
if (in_crdt && $0 ~ /^[[:space:]]+path:/) { found = 1 }
}
END { exit(found ? 0 : 1) }
' "$file"
}
main() {
local -a files=("$@")
if [[ ${#files[@]} -eq 0 ]]; then
files=("pubspec.yaml")
fi
local failed=0
for file in "${files[@]}"; do
[[ -f "$file" ]] || continue
if has_override "$file"; then
echo "Error: $file still has a local crdt_sync dependency_override." >&2
echo " Remove it and bump the git 'ref:' to the released tag" >&2
echo " before committing, or CI will build different code." >&2
failed=1
fi
done
return "$failed"
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
fi
main "$@"