WUT_Computer_Science/.pre-commit-config.yaml
Krzysztof kuhy Rudnicki e512bde26f Gate the invariants, fix ECOTE's unrunnable tests, contain build output
Two invariants had been established by hand and left ungated, which is the
"a remedy that only works if someone remembers" pattern:

  - scripts/check_ignore_consistency.sh fails the commit if any TRACKED file
    is also gitignored. .binary-allowlist used to *instruct* the reader to
    re-run that check; now it is enforced. Verified both ways -- passes on the
    tree, and fails when an ignored file is force-added.

DOCS-runnability.md now really has two columns. Each environment writes only
its own gates/runnability-<env>.tsv and the doc renders from both, so a CI run
cannot clobber the local results. The ci tsv is gitignored: committing a copy
generated here would label this machine's capabilities as the runner's.
Rendering it surfaced a classic bug -- awk's NR==FNR idiom silently swallows
the SECOND file when the first is empty, so the table came out with a header
and no rows. It compares FILENAME instead.

runnability.yml deliberately does NOT diff against a committed baseline. A
status is a property of the machine, so `runnable` locally and `blocked` on a
runner is correct rather than drift, and diffing would make the workflow red
by construction. It fails on `error` instead -- a runner that crashes or
reports an unknown kind.

Then five more courses were actually run, because EADS alone had produced four
real bugs and one sample proves nothing:

  - ECOAR and EPFU build (nasm + 32-bit gcc, and gcc respectively).
  - ECOTE's 17 test modules could not run AT ALL. Its package is named `code/`,
    which shadows the standard library: pytest's debugging plugin imports pdb,
    pdb imports code, and it got this directory instead, so the suite died
    with an INTERNALERROR before collecting a single test. Renamed to
    translator/ with all 17 imports updated -- 26 tests now pass.
  - A LaTeX report builds. That one exposed a hazard rather than a bug:
    latexmk wrote its PDF beside the source, and in a course where the built
    name matches the submitted one it would have silently overwritten a
    tracked deliverable. Both the LaTeX and C++ runners now build into a
    gitignored build/, and rebuilding ECOGR leaves `git status` empty.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0172dj34FDpao6wsix8ZuCzE
2026-08-28 18:43:13 +02:00

85 lines
3.4 KiB
YAML

# Install: ./install.sh (or: pre-commit install && pre-commit install --hook-type pre-push)
# Fast lint: pre-commit run --all-files
#
# Ordering rule for this repo: a hook lands only once the thing it gates is
# already clean, so `pre-commit run --all-files` is green at every commit.
# Hooks still to come, each blocked on its own cleanup:
# - file-length blocked on the .tex/code splits and TODO-file-length-250.md
# - ruff / mypy blocked on the root pyproject.toml (Milestone 4)
# - dependency-freshness blocked on the upgrade itself; the gate and the
# upgrade must land in the SAME commit or the repo is
# instantly and permanently red
# - trailing-whitespace / end-of-file-fixer these REWRITE files, so they get
# their own reviewed cleanup commit first
default_language_version:
python: python3
default_stages: [pre-commit]
fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
# Structural checks only -- none of these rewrite a file.
- id: check-merge-conflict
- id: check-case-conflict
- id: check-symlinks
- id: destroyed-symlinks
- id: detect-private-key
# tsconfig*.json and .vscode/*.json are JSONC -- both TypeScript and
# VS Code document comments and trailing commas as valid there, and
# check-json uses a strict RFC parser. This is the wrong parser for
# those files, not a defect being suppressed; every other .json is
# still checked. (The one real failure this hook found, a committed
# merge conflict in EARIN/.vscode/extensions.json, is fixed.)
- id: check-json
exclude: |
(?x)^(
.*/tsconfig[^/]*\.json|
.*/\.vscode/[^/]*\.json
)$
- id: check-toml
- id: check-yaml
args: [--unsafe]
# 2 MB. The four 39 MB movies.csv copies are already tracked and stay
# (approved decision 6); this stops the NEXT one.
- id: check-added-large-files
args: [--maxkb=2000]
- repo: local
hooks:
# Coursework deliverables are allowed under the two course trees;
# compiled output is allowed nowhere. See .binary-allowlist.
- id: no-binaries
name: block binary files outside the allowlist
entry: scripts/check_no_binaries.sh
language: script
pass_filenames: true
# A tracked file that .gitignore also matches fails silently on
# `git add`. 130 of those were fixed by hand; this keeps them fixed.
- id: ignore-consistency
name: no tracked file is gitignored
entry: scripts/check_ignore_consistency.sh
language: script
pass_filenames: false
always_run: true
# Thin shim into ~/utils, which owns the four markdown namespaces.
- id: md-naming
name: markdown naming convention
entry: scripts/check_md_naming.sh
language: system
files: \.(md|markdown)$
# -x so shellcheck FOLLOWS sourced files. The 44 per-course run.sh stubs
# source scripts/course_lib.sh; without -x every one of them reports
# SC1091 "not following", and the only other way to silence that is a
# per-file disable, which is banned here.
- id: shellcheck
name: shellcheck
entry: bash -c 'printf "%s\0" "$@" | xargs -0 -n 40 shellcheck -x' --
language: system
types: [shell]
exclude_types: [zsh]