default_install_hook_types = ["pre-commit", "commit-msg"] # Hooks for prek (https://prek.j178.dev/). See README for setup. # # Same shape as the sibling repos, minus what this one has no files for: no # terraform, no cargo, no astro. check-xml earns its place on one file, # bridge/log4j2-quiet.xml, which nothing else parses until MegaMek refuses to # start. [[repos]] repo = "https://github.com/pre-commit/pre-commit-hooks" rev = "v6.0.0" # check-added-large-files: runs/ is gitignored by name, but a match result # copied somewhere else would sail in, and a benchmark produces them by the # hundred. hooks = [ { id = "check-merge-conflict" }, { id = "check-added-large-files" }, { id = "check-toml" }, { id = "check-json" }, { id = "check-xml" }, { id = "mixed-line-ending", args = ["--fix=lf"] }, { id = "end-of-file-fixer" }, { id = "trailing-whitespace" }, ] [[repos]] repo = "https://github.com/shellcheck-py/shellcheck-py" rev = "v0.11.0.1" # Same flags as the sibling repos: -x follows sourced files, info-level notes # do not gate. hooks = [{ id = "shellcheck", args = ["-x", "--severity=warning"] }] [[repos]] repo = "https://github.com/astral-sh/ruff-pre-commit" rev = "v0.16.1" # Covers the harness and the bots. ruff parses the files itself, so a syntax # error fails here too - no separate check-ast. hooks = [ { id = "ruff-check", args = ["--fix"] }, { id = "ruff-format" }, ] [[repos]] repo = "local" # The register's tables are generated from the epics' frontmatter. A row that # disagrees with the file it points at is worse than no row. [[repos.hooks]] id = "plan-register" name = "plan register is current" language = "system" entry = "scripts/gen-plan-readme.py --check" pass_filenames = false files = '^plan/.*\.md$' # Conventional Commits, with the scope naming an epic. See the script. [[repos.hooks]] id = "commit-scope" name = "commit scope names an epic" language = "system" entry = "scripts/check-commit-scope.sh" stages = ["commit-msg"] # The harness's own tests. Fast on purpose - no match is played - so that the # thing which decides whether a result is real is checked on every commit # rather than when somebody remembers. # -j 2 on both, which the sibling repos also do: a full-parallel cargo build has # taken this machine down, and a hook runs on every commit. # # **`-j 2` alone does not bound the test run.** It limits how many *compilation* # jobs cargo starts; the test binary it produces then runs its tests across # every core, because libtest's default thread count is the machine's width and # nothing on the cargo command line reaches it. Measured on this machine: a # debug test binary from this suite at 710% CPU - seven cores - while the # command that started it said `-j 2`. It is the same shape as everything else # this repository keeps finding: a stand-in that looked like the check it was # standing for. # # `-- --test-threads 2` is the flag that actually bounds it. It changes no # result: `cargo test` is order-independent here by design, and the tests that # would notice a thread count are the ones asserting on wall-clock time - which # is exactly what an unbounded run was making flaky. [[repos.hooks]] id = "cargo-fmt" name = "cargo fmt" language = "system" entry = "cargo fmt --all --check" pass_filenames = false files = '\.rs$' [[repos.hooks]] id = "cargo-clippy" name = "cargo clippy" language = "system" entry = "cargo clippy -j 2 --workspace --all-targets -- -D warnings" pass_filenames = false files = '(\.rs|Cargo\.(toml|lock))$' # `docs/FEATURES.md` and `docs/features/*.svg` are generated from # `crates/sds-core/examples/vignettes/`, and `tests/vignettes.rs` is what # compares the two. `docs/TACTICS.md`, `docs/FORMATIONS.md`, `docs/SITUATION.md` # and `docs/tactics/*.svg` come out of `crates/sds-core/examples/tactics/`, and # `tests/tacticdoc.rs::the_checked_in_docs_are_current` is what compares those. # A commit that hand-edits a generated file touches no `.rs`, so without the # docs paths here the one check that would catch it never runs. [[repos.hooks]] id = "cargo-test" name = "cargo test" language = "system" entry = "cargo test -j 2 --workspace -- --test-threads 2" pass_filenames = false files = '(\.rs|Cargo\.(toml|lock)|^docs/FEATURES\.md|^docs/features/.*\.svg|^docs/TACTICS\.md|^docs/FORMATIONS\.md|^docs/SITUATION\.md|^docs/tactics/.*\.svg|^docs/figures\.css)$' # Same reasoning as `cargo-test` above, for the other generator: `docs/LABELS.md` # and `docs/labels/*.svg` come out of `sds/labeldoc.py`, and `docs/figures.css` # is the palette both generators inline. A commit that hand-edits one of those # touches no `.py`, so without them here the staleness check never runs. [[repos.hooks]] id = "harness-tests" name = "harness tests" language = "system" entry = "python3 -m unittest discover -s tests -t ." pass_filenames = false files = '(\.py|^docs/LABELS\.md|^docs/labels/.*\.svg|^docs/figures\.css)$' # Stamp a Change-Id trailer on commits that lack one: the identity a stacked # pull request is matched to its commits by. Added by `atgc repo configure # --hook-config`; the script is atgc's, and does nothing to a commit that has # an id already. [[repos]] repo = "local" hooks = [ { id = "change-id", name = "change-id", entry = "scripts/change-id-hook.sh", language = "system", stages = ["commit-msg"], always_run = true }, ]