diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5cf8f85..4b0bd85 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,9 +18,9 @@ jobs: # Pinned deliberately: an unpinned ruff picks up new rules on release and # turns a green branch red without anything in this repo changing. - - run: pip install ruff==0.16.2 vulture==2.14 + - run: pip install ruff==0.16.2 vulture==2.14 pre-commit==4.6.2 - run: ruff check . - name: Dead code - run: tools/check-dead-code.sh + run: pre-commit run --all-files --show-diff-on-failure diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7fdfd79 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +# The dead-code gate lives in offworldlabs/ops and is pinned here. Do not +# vendor it back into this repo. See 86cb4jfhz. +# +# The ruff-config hook is deliberately absent: this repo's shared ruff standard +# lives in ruff.toml, and check-ruff-config.py currently reads pyproject.toml +# only. Tracked as 86cb4jfzk; add the hook once that lands. +repos: + - repo: https://github.com/offworldlabs/ops + rev: hooks-v1.0 + hooks: + - id: dead-code diff --git a/tools/check-dead-code.sh b/tools/check-dead-code.sh deleted file mode 100755 index 117e0e5..0000000 --- a/tools/check-dead-code.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# -# Dead-code gate. Shared across offworldlabs Python repos; canonical copy lives -# in offworldlabs/ops. -# -# tools/check-dead-code.sh # fail if anything unwhitelisted is dead -# tools/check-dead-code.sh --list # print findings without failing -# -# Why this wraps vulture rather than calling it directly: -# -# Tests are SCANNED but not REPORTED. Excluding tests entirely — the obvious -# setup — makes anything used only by tests look dead, which is the largest -# single source of false positives. Scanning them fixes that, but then unused -# test helpers become findings in their own right. So we scan everything and -# drop findings whose location is a test file. -# -# Build artefacts are excluded because they contain a stale copy of the source, -# which doubles every finding. - -set -euo pipefail - -cd "$(dirname "${BASH_SOURCE[0]}")/.." - -EXCLUDE=".venv,scripts,htmlcov,__pycache__,node_modules,build,dist,*.egg-info" -# Framework-dispatched handlers: Flask (@bp/@app) and FastAPI (@router/@app). -DECORATORS="@app.*,@bp.*,@router.*" -WHITELIST="" -[ -f vulture_whitelist.py ] && WHITELIST="vulture_whitelist.py" - -findings="$(vulture . $WHITELIST \ - --min-confidence 60 \ - --exclude "$EXCLUDE" \ - --ignore-decorators "$DECORATORS" \ - 2>/dev/null | grep -vE '(^|/)tests?/|/test_|conftest\.py' || true)" - -if [ -z "$findings" ]; then - echo "no dead code found" - exit 0 -fi - -echo "$findings" - -if [ "${1:-}" = "--list" ]; then - exit 0 -fi - -echo >&2 -echo "Dead code found. Delete it, or — only if it is referenced dynamically and" >&2 -echo "vulture cannot see that — add it to vulture_whitelist.py with a reason." >&2 -exit 1