Files
sausage/userland/brush/source/.pre-commit-config.yaml
T
2026-11-11 22:04:16 +00:00

248 lines
12 KiB
YAML

# Third-party linter definitions, and the single place their versions are
# pinned. As with GitHub Actions, each `rev:` is a full commit SHA, since a tag
# can be moved to point at different code; the `# frozen: <tag>` comment records
# which release that is. Dependabot's `pre-commit` ecosystem keeps both current
# (see .github/dependabot.yml).
#
# Two different front ends read this file:
#
# cargo xtask check hooks # runs every hook; needs no knowledge of prek
# cargo xtask check hooks <HOOK>... # runs only the named hooks, by id or by the
# # aliases below: spelling, links, workflows, deps,
# # structure
#
# ...and prek (https://prek.j178.dev) directly, as installed git hooks. CI's
# Pre-commit hooks workflow (.github/workflows/hooks.yaml) goes through
# `cargo xtask check hooks` as well, so CI and a local run execute the same
# command. prek is a single-binary Rust
# reimplementation of pre-commit; it reads this file and reimplements the
# common hygiene hooks natively, so no Python environment is needed for them.
#
# Install: cargo binstall prek (or: uv tool install prek / brew install prek)
# Enable the git hooks (optional): prek install
#
# Useful invocations:
# prek run # staged files, commit-stage hooks
# prek run --all-files # whole tree, commit-stage hooks (= check hooks)
# prek run --all-files --stage pre-push # the cargo-backed check
# prek run --all-files typos # a single hook
# prek run --all-files --skip rustfmt # skip one hook
#
# The upstream Python `pre-commit` also reads this file, but spells two of those
# flags differently: `--hook-stage` rather than `--stage`, and `SKIP=<id>` in the
# environment rather than `--skip`.
#
# Git hooks are entirely optional -- `cargo xtask ci quick` and
# `cargo xtask ci full` are the documented contributor path and neither requires
# `prek install`.
default_install_hook_types: [pre-commit, commit-msg, pre-push]
# `default_stages` only applies to hooks whose upstream manifest doesn't declare
# its own `stages`; several of the hygiene hooks declare [pre-commit, pre-push,
# manual], so they're pinned to the commit stage individually below. Keeping the
# fixing hooks off the pre-push stage matters: a hook that rewrites a file during
# `git push` leaves you with an already-made commit and unstaged fixes.
default_stages: [pre-commit]
repos:
# ---------------------------------------------------------------------------
# File hygiene. prek substitutes its own native Rust implementations for these
# automatically, so nothing is cloned or installed for this block.
# ---------------------------------------------------------------------------
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
hooks:
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
stages: [pre-commit]
# Shell fragments inside compat test cases carry semantically meaningful
# trailing whitespace; insta snapshots must match byte-for-byte; the
# changelog is generated by git-cliff.
exclude: ^(brush-shell/tests/cases/|CHANGELOG\.md$)|\.snap$
- id: end-of-file-fixer
stages: [pre-commit]
exclude: ^(brush-shell/tests/cases/|CHANGELOG\.md$)|\.snap$
- id: mixed-line-ending
args: [--fix=lf]
stages: [pre-commit]
exclude: ^(brush-shell/tests/cases/|CHANGELOG\.md$)|\.snap$
- id: check-merge-conflict
- id: check-symlinks
- id: destroyed-symlinks
stages: [pre-commit]
- id: check-added-large-files
stages: [pre-commit]
- id: detect-private-key
# brush is built and tested on macOS and Windows too.
- id: check-case-conflict
- id: check-illegal-windows-names
- id: check-yaml
- id: check-toml
- id: check-json
# .vscode/*.json are JSONC (comments), not strict JSON.
exclude: ^\.vscode/
- id: check-executables-have-shebangs
stages: [pre-commit]
- id: check-shebang-scripts-are-executable
stages: [pre-commit]
# Rust files opening with an inner attribute (`#![...]`) look like they
# have a shebang.
exclude: \.rs$
# ---------------------------------------------------------------------------
# Schema validation for release-plz.toml, so a misspelled key or wrong type
# fails here instead of at release time. The schema is the one release-plz
# publishes, as of a release-plz release tag. Dependabot doesn't track that
# URL; bump the tag by hand when adopting newer release-plz config.
# check-jsonschema caches the download, so only the first run needs the
# network.
# ---------------------------------------------------------------------------
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: a76b92851fc9eede9f9bc4073eb55202f34eb0df # frozen: 0.39.0
hooks:
- id: check-jsonschema
name: Validate release-plz.toml
files: ^release-plz\.toml$
# Upstream's manifest limits this hook to [json, yaml].
types_or: [toml]
args:
- --schemafile
- https://raw.githubusercontent.com/release-plz/release-plz/release-plz-v0.4.3/.schema/latest.json
# ---------------------------------------------------------------------------
# Spelling. Configured by Cargo.toml [workspace.metadata.typos].
# ---------------------------------------------------------------------------
- repo: https://github.com/crate-ci/typos
rev: b859c0df7f391deba73030f79b957e62b4d81dc6 # frozen: varcon-core-v5.0.7
hooks:
- id: typos
alias: spelling
# Report, don't rewrite. Overriding `args` replaces the upstream
# manifest's `[--write-changes, --force-exclude]`, and dropping
# --write-changes is the point: automatic corrections inside shell test
# cases would silently change what the tests exercise. --force-exclude
# is what makes typos honor its own exclude config for files named
# explicitly on the command line, so keep it.
args: [--force-exclude]
stages: [pre-commit]
# ---------------------------------------------------------------------------
# GitHub Actions security analysis. Configured by zizmor.yml. This is the
# offline pass, which fails fast; the online pass that uploads SARIF lives in
# .github/workflows/workflow-checks.yaml and is not redundant with it.
# ---------------------------------------------------------------------------
- repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: c92afdf2c6ca336aaa8f39e2bd8d48f62dbd8e1f # frozen: v1.31.1
hooks:
- id: zizmor
alias: workflows
args: [--no-progress, --offline]
# ---------------------------------------------------------------------------
# Link checking. Configured by lychee.toml. `types_or` mirrors lychee's own
# default `--extensions` list (markdown, html, css, txt, xml), so this reaches
# the same files as pointing lychee at the whole tree.
#
# Dependabot bumps this SHA but can't rewrite the comment, because lychee's
# tags carry a `lychee-` prefix; fix the comment by hand in its bump PRs.
# ---------------------------------------------------------------------------
- repo: https://github.com/lycheeverse/lychee
rev: 2bba271688c1abb1503097a064e6c3bc1d1b6a9b # frozen: lychee-v0.24.2
hooks:
- id: lychee
alias: links
args: [--no-progress, --offline]
types_or: [markdown, html, css, plain-text, xml]
# ---------------------------------------------------------------------------
# Dependency audit: advisories, licenses, bans, sources. Configured by
# deny.toml. cargo-deny is a third-party cargo subcommand, not a toolchain
# component, so rust-toolchain.toml does not pin it; this does. prek builds
# the pinned release from source (`cargo install --locked`), a one-time cost
# per version bump that is cached afterwards. Upstream's hook already passes
# `--all-features check`, which runs every check, and only fires when a
# Cargo.toml or Cargo.lock is among the files.
# ---------------------------------------------------------------------------
- repo: https://github.com/EmbarkStudios/cargo-deny
rev: bca0dde53651ee946720e4540b5ce2610bec8f06 # frozen: 0.20.2
hooks:
- id: cargo-deny
alias: deps
# ---------------------------------------------------------------------------
# Structural lints over the syntax tree, for architectural rules that clippy
# can't express. Configured by sgconfig.yml; the rules and their tests live
# in .config/ast-grep/. Pre-existing violations are baselined in place, and
# --error=unused-suppression fails once one of those is no longer needed, so
# the baseline can only shrink. This is a thin community wrapper around the
# official @ast-grep/cli npm package, whose version it tracks; a `repo: local`
# hook would avoid it, but Dependabot skips those.
# ---------------------------------------------------------------------------
- repo: https://github.com/boidolr/ast-grep-pre-commit
rev: 13126a89e67880b0dac82cf40350abd2cfedd458 # frozen: 0.51.0
hooks:
- id: ast-grep
alias: structure
args: [--error=unused-suppression]
types: [rust]
# Each rule's test cases must or mustn't match. Skipping snapshot tests
# skips the extra comparison of each match's exact output (span, message)
# against a recorded __snapshots__ file, which would need regenerating on
# every rule edit without telling us more about what the rule catches.
- id: ast-grep-rule-tests
args: [--skip-snapshot-tests]
files: ^(sgconfig\.yml|\.config/ast-grep/)
# ---------------------------------------------------------------------------
# Conventional Commits, as required by CONTRIBUTING.md and consumed by
# git-cliff and release-plz.
# ---------------------------------------------------------------------------
- repo: https://github.com/compilerla/conventional-pre-commit
rev: 33b50eb042bee26eac0ee96ad84aa9c1b4dccdd8 # frozen: v4.5.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
args: [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]
# ---------------------------------------------------------------------------
# Repo-specific checks. These delegate to xtask so that the Rust-side checks
# have exactly one definition, and so that hook users and non-hook users run
# identical code.
# ---------------------------------------------------------------------------
- repo: local
hooks:
# `rustfmt` rather than `cargo fmt --all`: passing the staged files formats
# only what is being committed. `cargo fmt --all` would rewrite files
# outside the commit, and pre-commit stashes unstaged changes before
# running hooks, so rewriting a file that also has unstaged edits makes the
# stash restore conflict. rustfmt reads rustfmt.toml for the edition.
- id: rustfmt
name: rustfmt
entry: rustfmt
language: system
types: [rust]
require_serial: true
# One hook, not four. `ci quick` is the same command CONTRIBUTING.md tells
# contributors to run, so people who install the hooks and people who
# don't execute identical code. It covers fmt, build, clippy, and unit
# tests; schemas, cargo-deny, and integration tests are left to
# `cargo xtask ci full` and to CI.
#
# Deliberately `ci quick` and not `ci full`: `ci full` runs the pre-commit
# hooks, which invoke prek, which is what is running this hook. xtask
# refuses to start prek when PRE_COMMIT is set, so getting this wrong
# fails fast rather than recursing.
- id: xtask-ci-quick
name: cargo xtask ci quick
entry: cargo xtask ci quick
language: system
files: \.rs$|(^|/)Cargo\.(toml|lock)$|(^|/)(rustfmt|clippy)\.toml$
pass_filenames: false
require_serial: true
stages: [pre-push]