fix(hooks): falha fechada ao gravar a população e teste MIG-GRANDE que também vigia em locale C

- pop_migrations agora grava com `{ ...; } >arquivo || bloqueia`: falha ao abrir/escrever o arquivo não é mais engolida
- a mensagem de mktemp falho termina com a válvula do dono
- `LC_ALL=C sort -u` na dica de próximo livre
- fixture MIG-GRANDE sobe para 600 refs (~301 mil linhas) para o hook antigo estourar o limite também em locale C

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
melgarafael
2026-09-30 00:01:20 -03:00
co-authored by Claude Opus 5.5
parent 0c031e2d54
commit acb365051d
4 changed files with 17 additions and 15 deletions
@@ -129,7 +129,7 @@ fi
# (29/09/2026) ela tinha ~1,29 M linhas (~112 MB), e o teste de vazio que havia aqui,
# `${populacao// /}`, é uma substituição de padrão do bash — quadrática no tamanho da
# string. O hook não terminava em 45 min. O grep lê o arquivo direto.
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida." >&2; exit 1; }
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
trap 'rm -f "$populacao"' EXIT
if declare -F pop_migrations >/dev/null 2>&1; then
# O HEAD entra SEMPRE: `pop_refs_de_outrem` tira a ref cujo SHA é o do HEAD (a
@@ -137,7 +137,7 @@ if declare -F pop_migrations >/dev/null 2>&1; then
# sumia da conta — a segunda 0411 e o carimbo repetido passavam calados, e a
# dica de próximo livre apontava para o número da branch. O próprio arquivo
# encenado não é acusado: o `grep -vE " <nome>$"` abaixo o tira.
pop_migrations $refs HEAD >"$populacao" 2>/dev/null || true
{ pop_migrations $refs HEAD 2>/dev/null || true; } >"$populacao" || { echo "pre-commit BLOQUEADO: não foi possível gravar a população de migrations em $populacao. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
fi
if ! grep -q . "$populacao"; then
# A biblioteca não está (clone antigo, cópia da skill de versão anterior) ou
@@ -181,7 +181,7 @@ while IFS= read -r caminho; do
onde="$(awk '{printf "%s(%s) ", $1, $2}' <<<"$donos_n" | sed 's/ $//')"
echo "pre-commit BLOQUEADO: NNNN=$nnnn de '$nome' já existe em: $onde" >&2
if declare -F pop_dica_proximo_livre >/dev/null 2>&1; then
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | sort -u)" >&2
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | LC_ALL=C sort -u)" >&2
else
echo " Para o próximo número livre (main do produto ∪ PRs abertos): pnpm checar:colisao-de-migration" >&2
fi
@@ -129,7 +129,7 @@ fi
# (29/09/2026) ela tinha ~1,29 M linhas (~112 MB), e o teste de vazio que havia aqui,
# `${populacao// /}`, é uma substituição de padrão do bash — quadrática no tamanho da
# string. O hook não terminava em 45 min. O grep lê o arquivo direto.
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida." >&2; exit 1; }
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
trap 'rm -f "$populacao"' EXIT
if declare -F pop_migrations >/dev/null 2>&1; then
# O HEAD entra SEMPRE: `pop_refs_de_outrem` tira a ref cujo SHA é o do HEAD (a
@@ -137,7 +137,7 @@ if declare -F pop_migrations >/dev/null 2>&1; then
# sumia da conta — a segunda 0411 e o carimbo repetido passavam calados, e a
# dica de próximo livre apontava para o número da branch. O próprio arquivo
# encenado não é acusado: o `grep -vE " <nome>$"` abaixo o tira.
pop_migrations $refs HEAD >"$populacao" 2>/dev/null || true
{ pop_migrations $refs HEAD 2>/dev/null || true; } >"$populacao" || { echo "pre-commit BLOQUEADO: não foi possível gravar a população de migrations em $populacao. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
fi
if ! grep -q . "$populacao"; then
# A biblioteca não está (clone antigo, cópia da skill de versão anterior) ou
@@ -181,7 +181,7 @@ while IFS= read -r caminho; do
onde="$(awk '{printf "%s(%s) ", $1, $2}' <<<"$donos_n" | sed 's/ $//')"
echo "pre-commit BLOQUEADO: NNNN=$nnnn de '$nome' já existe em: $onde" >&2
if declare -F pop_dica_proximo_livre >/dev/null 2>&1; then
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | sort -u)" >&2
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | LC_ALL=C sort -u)" >&2
else
echo " Para o próximo número livre (main do produto ∪ PRs abertos): pnpm checar:colisao-de-migration" >&2
fi
+3 -3
View File
@@ -112,7 +112,7 @@ fi
# (29/09/2026) ela tinha ~1,29 M linhas (~112 MB), e o teste de vazio que havia aqui,
# `${populacao// /}`, é uma substituição de padrão do bash — quadrática no tamanho da
# string. O hook não terminava em 45 min. O grep lê o arquivo direto.
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida." >&2; exit 1; }
populacao="$(mktemp)" || { echo "pre-commit BLOQUEADO: mktemp falhou — a população de migrations não pôde ser medida. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
trap 'rm -f "$populacao"' EXIT
if declare -F pop_migrations >/dev/null 2>&1; then
# O HEAD entra SEMPRE: `pop_refs_de_outrem` tira a ref cujo SHA é o do HEAD (a
@@ -120,7 +120,7 @@ if declare -F pop_migrations >/dev/null 2>&1; then
# sumia da conta — a segunda 0411 e o carimbo repetido passavam calados, e a
# dica de próximo livre apontava para o número da branch. O próprio arquivo
# encenado não é acusado: o `grep -vE " <nome>$"` abaixo o tira.
pop_migrations $refs HEAD >"$populacao" 2>/dev/null || true
{ pop_migrations $refs HEAD 2>/dev/null || true; } >"$populacao" || { echo "pre-commit BLOQUEADO: não foi possível gravar a população de migrations em $populacao. Correção orientada pelo dono: DESKCOMM_GOV_MIGRATION_EDIT=1." >&2; exit 1; }
fi
if ! grep -q . "$populacao"; then
if ! declare -F pop_migrations >/dev/null 2>&1; then
@@ -155,7 +155,7 @@ while IFS= read -r path; do
if [ -n "$conflict" ]; then
echo "pre-commit BLOQUEADO: sequência NNNN=$nnnn de '$fname' já existe em: $(awk '{printf "%s(%s) ", $1, $2}' <<<"$conflict" | sed 's/ $//')" >&2
if declare -F pop_dica_proximo_livre >/dev/null 2>&1; then
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | sort -u)" >&2
pop_dica_proximo_livre "$nnnn" "$base" "$(cut -d' ' -f2- "$populacao" | LC_ALL=C sort -u)" >&2
else
echo "Para o próximo número livre (main do produto ∪ PRs abertos): pnpm checar:colisao-de-migration" >&2
fi
+8 -6
View File
@@ -981,10 +981,12 @@ assert_exit "$(exit_de "$r")" 0 "MIG-CONTROLE: e um número de fato livre passa"
# (~112 MB) de população, e o hook não terminava em 45 min. A causa era o teste de
# vazio `${populacao// /}`: a substituição de padrão do bash é quadrática no tamanho da
# string (medido aqui: 25 mil linhas → 18 s só nessa linha; 100 mil → ~400 s o hook).
# A população agora vive num ARQUIVO e o grep lê o arquivo. O fixture tem ~100 mil
# linhas (500 migrations × 200 refs para o mesmo commit — `pop_migrations` emite uma
# A população agora vive num ARQUIVO e o grep lê o arquivo. O fixture tem ~300 mil
# linhas (500 migrations × 600 refs para o mesmo commit — `pop_migrations` emite uma
# linha por ref) e o LIMITE é folgado para máquina lenta: o hook de antes estoura
# qualquer limite razoável aqui, o de agora leva ~1 s. Rodam os DOIS hooks: o do
# qualquer limite razoável aqui, o de agora leva ~1 s. O fixture foi dimensionado para o
# antigo estourar TAMBÉM em locale C (LANG vazio), onde ele termina em ~10 s com 100 mil
# linhas e o caso passaria sem vigiar; em UTF-8 o antigo é bem mais lento. Rodam os DOIS hooks: o do
# contribuidor tinha a mesma linha.
printf '\ncheck-migration-triple.sh — população grande termina (mantenedor e contribuidor)\n'
LIMITE_S=30
@@ -1012,10 +1014,10 @@ for i in $(seq 1 500); do : > "$g/supabase/migrations/$(printf '2026010100%04d_%
commitar "$g" "500 migrations"
c_outra=$(git -C "$g" rev-parse HEAD)
git -C "$g" checkout -q main
seq 1 200 | awk -v c="$c_outra" '{ printf "create refs/heads/r%05d %s\n", $1, c }' | git -C "$g" update-ref --stdin
seq 1 600 | awk -v c="$c_outra" '{ printf "create refs/heads/r%05d %s\n", $1, c }' | git -C "$g" update-ref --stdin
linhas=$( cd "$g" && bash -c '. scripts/migration-populacao.sh; pop_migrations $(pop_refs_de_outrem "") HEAD | wc -l' | tr -d ' ')
if [ "${linhas:-0}" -ge 100000 ]; then ok "MIG-GRANDE: a população do fixture tem $linhas linhas (premissa do volume)"
else falha "MIG-GRANDE: população >= 100000 linhas" "veio ${linhas:-nada} — o caso não estressa o hook"; fi
if [ "${linhas:-0}" -ge 300000 ]; then ok "MIG-GRANDE: a população do fixture tem $linhas linhas (premissa do volume)"
else falha "MIG-GRANDE: população >= 300000 linhas" "veio ${linhas:-nada} — o caso não estressa o hook"; fi
tripla "$g" 20990101000000_9999_livre.sql
for h in loop/hooks/check-migration-triple.sh contrib/check-migration-triple.sh; do
r=$(rodar_com_limite "$g" "$h")