From 3a5f0962de80cd98114979f1341fabe5bdebeebd Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Wed, 12 Aug 2026 19:18:21 +0200 Subject: [PATCH] Add a pre-commit gate against a local crdt_sync dependency_override 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 Claude-Session: https://claude.ai/code/session_013SH7XBkpEqQX4KghHdgx9T --- .pre-commit-config.yaml | 8 +++ scripts/check_no_crdt_sync_override.sh | 88 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100755 scripts/check_no_crdt_sync_override.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f9c694..256ff6c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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' -- diff --git a/scripts/check_no_crdt_sync_override.sh b/scripts/check_no_crdt_sync_override.sh new file mode 100755 index 0000000..967e6c8 --- /dev/null +++ b/scripts/check_no_crdt_sync_override.sh @@ -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 "$@"