Files
FabledGrimoire/tests/test_hook_pipefail_head.py
T
bvandeusenandClaude Opus 5.5 79de8938b9 docs(6209): forty test files — design cascade and stylesheet, embeddings, family canon, forge, backup round trips, inception, placement, platforms, moments, rule move and verification, search scope, facets
Module and test docstrings state what is pinned without the record number
or step that introduced it. Incident accounts become the failure shape in
the present tense: the pipefail head, the code_shapes import, the export
order, the facet dialects, the cross-kind repeat, the write-once kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 21:40:25 -04:00

60 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Under `pipefail`, an early-exiting `head` must not void the output it kept.
The hooks run with `set -uo pipefail`. `hits=$(git grep -l … | head -4) ||
hits=""` loses its four hits whenever git grep is still writing when head
exits: SIGPIPE, a failed substitution, and the fallback wipes the result. It
only shows on big outputs, so the by-name duplicate arm goes silent for
exactly the most-duplicated names.
Two halves: the real function on a repo big enough to overflow the pipe, and
the check_plugin pattern that keeps the shape out of every hook (shown able to
fail).
"""
from __future__ import annotations
import os
import shutil
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
DEFS = ROOT / "plugin" / "hooks" / "scribe_defs.sh"
def test_the_duplicate_arm_still_names_a_name_defined_in_thousands_of_files(tmp_path):
for tool in ("git", "bash"):
if shutil.which(tool) is None:
pytest.skip(f"{tool!r} not installed")
env = {"PATH": os.environ["PATH"], "HOME": str(tmp_path),
"GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@x",
"GIT_COMMITTER_NAME": "t", "GIT_COMMITTER_EMAIL": "t@x"}
repo = tmp_path / "repo"
repo.mkdir()
subprocess.run(["git", "init", "-q"], cwd=repo, check=True, env=env)
# ~3000 × ~60 bytes of `git grep -l` output: well past a 64 KiB pipe buffer,
# so git grep is still writing when head has its four lines.
for i in range(3000):
(repo / f"module_with_a_fairly_long_descriptive_name_{i}.py").write_text("def slug(t):\n return t\n")
subprocess.run(["git", "add", "."], cwd=repo, check=True, env=env)
subprocess.run(["git", "commit", "-q", "-m", "base"], cwd=repo, check=True, env=env)
script = f'set -uo pipefail\n. "{DEFS}"\nprintf "sym\\tslug\\n" | scribe_local_dups "{repo}" new.py\n'
out = subprocess.run(["bash", "-c", script], capture_output=True, text=True, env=env, timeout=60)
assert out.returncode == 0, out.stderr
assert "`slug` is already defined in 4 other file(s)" in out.stdout
def test_the_lint_pattern_catches_the_shape_and_passes_the_fix():
from scripts.check_plugin import PATTERNS
pattern = next(p for p, label, _why in PATTERNS if label.startswith("early-exit consumer"))
for bad in ('hits=$(git grep -l x | head -4) || hits=""',
" | grep -m1 -v '^[[:space:]]*$') || old_first=\"\"",
'x=$(a | grep -q b) || x=""'):
assert pattern.search(bad), bad
for good in ('hits=$(git grep -l x | head -4 || true)',
'ln=$(grep -nF -m1 -- "$a" "$f" | cut -d: -f1) || ln=""'):
assert not pattern.search(good), good