From fa3dd827f947c5ee7e637e9c7b0e2ff710b3f3dd Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Thu, 15 Oct 2026 22:44:24 +0800 Subject: [PATCH] chore: add pre-commit hook running ruff and mypy checks on staged files Mirrors the fast static checks from CI (justfile lint + type-check): ruff check, ruff format --check and mypy (gns3server package only, matching the files = ["gns3server"] scope in pyproject.toml). Only staged Python files are checked; pytest and pip check are left to CI. Enable with: just install-hooks --- .githooks/pre-commit | 54 ++++++++++++++++++++++++++++++++++++++++++++ justfile | 5 ++++ 2 files changed, 59 insertions(+) create mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..7e367091d --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# Pre-commit checks mirroring the CI checks that are fast enough to run on +# every commit (justfile "lint" + "type-check"; pytest and pip check are not +# run here). Only staged Python files are checked. +# +# Install with: just install-hooks + +set -euo pipefail + +# Prefer the repo virtualenv, fall back to whatever python is on PATH +PYTHON="venv/bin/python" +if [ ! -x "$PYTHON" ]; then + PYTHON="python" +fi +if ! command -v "$PYTHON" >/dev/null 2>&1; then + echo "pre-commit: no python interpreter found, skipping checks" >&2 + exit 0 +fi + +# Staged .py files (deletions excluded) +mapfile -t staged < <(git diff --cached --name-only --diff-filter=d -- '*.py') +if [ ${#staged[@]} -eq 0 ]; then + exit 0 +fi + +status=0 + +echo "pre-commit: ruff check" +"$PYTHON" -m ruff check --exit-non-zero-on-fix "${staged[@]}" || status=1 + +echo "pre-commit: ruff format --check" +"$PYTHON" -m ruff format --check --diff "${staged[@]}" || status=1 + +# mypy is configured with files = ["gns3server"] in pyproject.toml, i.e. CI +# never type-checks tests: only pass staged files from that package. +mypy_targets=() +for f in "${staged[@]}"; do + case "$f" in + gns3server/*) mypy_targets+=("$f") ;; + esac +done + +if [ ${#mypy_targets[@]} -gt 0 ]; then + echo "pre-commit: mypy" + "$PYTHON" -m mypy "${mypy_targets[@]}" || status=1 +fi + +if [ "$status" -ne 0 ]; then + echo "" + echo "pre-commit: checks failed. Fix the issues above (try 'just format')," >&2 + echo "or bypass with: git commit --no-verify" >&2 +fi + +exit "$status" diff --git a/justfile b/justfile index b07fefc81..c9dd64787 100644 --- a/justfile +++ b/justfile @@ -9,6 +9,11 @@ install: python -m pip install --upgrade pip python -m pip install -e '.[ai-features,dev]' +# Install the git pre-commit hook (lint + type-check on staged files) +[group('dev')] +install-hooks: + git config core.hooksPath .githooks + # Apply ruff autofixes for the enforced rules [group('dev')] format: