chore: add pre-commit ruff hook with auto-fix
Some checks failed
CI / test-cli (push) Successful in 11s
CI / test-sqlmesh (push) Successful in 12s
CI / test-web (push) Failing after 14s
CI / tag (push) Has been skipped

- scripts/hooks/pre-commit: runs ruff --fix for root and web/ (matching CI)
  and re-stages any auto-fixed files so they land in the commit
- Makefile: add install-hooks target (run once after clone)
- pyproject.toml: exclude web/ from root ruff (web has its own config)
- Fix remaining import sort warnings caught by the new hook

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-28 10:19:29 +01:00
parent c5a218490e
commit 42c1309b20
9 changed files with 36 additions and 13 deletions

View File

@@ -2,7 +2,7 @@ TAILWIND_VERSION := v4.1.18
TAILWIND := web/bin/tailwindcss TAILWIND := web/bin/tailwindcss
SOPS_DOTENV := sops --input-type dotenv --output-type dotenv SOPS_DOTENV := sops --input-type dotenv --output-type dotenv
.PHONY: help dev css-build css-watch \ .PHONY: help dev css-build css-watch install-hooks \
secrets-decrypt-dev secrets-decrypt-prod \ secrets-decrypt-dev secrets-decrypt-prod \
secrets-edit-dev secrets-edit-prod \ secrets-edit-dev secrets-edit-prod \
secrets-encrypt-dev secrets-encrypt-prod \ secrets-encrypt-dev secrets-encrypt-prod \
@@ -13,6 +13,7 @@ help:
@echo " dev Start full dev environment (migrate, seed, app + worker + CSS watcher)" @echo " dev Start full dev environment (migrate, seed, app + worker + CSS watcher)"
@echo " css-build Build + minify Tailwind CSS" @echo " css-build Build + minify Tailwind CSS"
@echo " css-watch Watch + rebuild Tailwind CSS" @echo " css-watch Watch + rebuild Tailwind CSS"
@echo " install-hooks Install git pre-commit hook (run once after cloning)"
@echo " secrets-decrypt-dev Decrypt .env.dev.sops → .env" @echo " secrets-decrypt-dev Decrypt .env.dev.sops → .env"
@echo " secrets-decrypt-prod Decrypt .env.prod.sops → .env" @echo " secrets-decrypt-prod Decrypt .env.prod.sops → .env"
@echo " secrets-edit-dev Edit .env.dev.sops in \$$EDITOR" @echo " secrets-edit-dev Edit .env.dev.sops in \$$EDITOR"
@@ -23,6 +24,11 @@ help:
# ── Dev environment ─────────────────────────────────────────────────────────── # ── Dev environment ───────────────────────────────────────────────────────────
install-hooks:
cp scripts/hooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
@echo "✓ pre-commit hook installed"
dev: dev:
@./web/scripts/dev_run.sh @./web/scripts/dev_run.sh

View File

@@ -88,6 +88,7 @@ exclude = [
"site-packages", "site-packages",
"venv", "venv",
"notebooks", "notebooks",
"web",
] ]
indent-width = 4 indent-width = 4

22
scripts/hooks/pre-commit Normal file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Pre-commit hook: ruff lint + auto-fix.
# Install: make install-hooks
set -euo pipefail
REPO_ROOT="$(git rev-parse --show-toplevel)"
RUFF="$REPO_ROOT/.venv/bin/ruff"
if [[ ! -x "$RUFF" ]]; then
echo "pre-commit: ruff not found at $RUFF — run 'uv sync' first" >&2
exit 1
fi
echo "→ ruff check (root)"
"$RUFF" check --fix "$REPO_ROOT"
echo "→ ruff check (web/src web/tests)"
"$RUFF" check --fix "$REPO_ROOT/web/src" "$REPO_ROOT/web/tests" \
--config "$REPO_ROOT/web/pyproject.toml"
# Re-stage any files ruff fixed so they land in the commit.
git diff --name-only | xargs -r git add

View File

@@ -7,7 +7,6 @@ from unittest.mock import AsyncMock, patch
import aiosqlite import aiosqlite
import pytest import pytest
from beanflows import core from beanflows import core
from beanflows.app import create_app from beanflows.app import create_app

View File

@@ -2,10 +2,6 @@
Unit tests for billing SQL helpers, feature/limit access, and plan determination. Unit tests for billing SQL helpers, feature/limit access, and plan determination.
""" """
import pytest import pytest
from hypothesis import HealthCheck, given
from hypothesis import settings as h_settings
from hypothesis import strategies as st
from beanflows.billing.routes import ( from beanflows.billing.routes import (
can_access_feature, can_access_feature,
get_billing_customer, get_billing_customer,
@@ -18,6 +14,9 @@ from beanflows.billing.routes import (
upsert_subscription, upsert_subscription,
) )
from beanflows.core import config from beanflows.core import config
from hypothesis import HealthCheck, given
from hypothesis import settings as h_settings
from hypothesis import strategies as st
# ════════════════════════════════════════════════════════════ # ════════════════════════════════════════════════════════════
# get_subscription # get_subscription

View File

@@ -2,7 +2,6 @@
Tests for the billing event hook system. Tests for the billing event hook system.
""" """
import pytest import pytest
from beanflows.billing.routes import _billing_hooks, _fire_hooks, on_billing_event from beanflows.billing.routes import _billing_hooks, _fire_hooks, on_billing_event

View File

@@ -144,9 +144,8 @@ class TestCancelRoute:
# subscription_required decorator # subscription_required decorator
# ════════════════════════════════════════════════════════════ # ════════════════════════════════════════════════════════════
from quart import Blueprint # noqa: E402
from beanflows.auth.routes import subscription_required # noqa: E402 from beanflows.auth.routes import subscription_required # noqa: E402
from quart import Blueprint # noqa: E402
test_bp = Blueprint("test", __name__) test_bp = Blueprint("test", __name__)

View File

@@ -5,13 +5,12 @@ Covers signature verification, event parsing, subscription lifecycle transitions
import json import json
import pytest import pytest
from beanflows.billing.routes import get_billing_customer, get_subscription
from conftest import make_webhook_payload, sign_payload from conftest import make_webhook_payload, sign_payload
from hypothesis import HealthCheck, given from hypothesis import HealthCheck, given
from hypothesis import settings as h_settings from hypothesis import settings as h_settings
from hypothesis import strategies as st from hypothesis import strategies as st
from beanflows.billing.routes import get_billing_customer, get_subscription
WEBHOOK_PATH = "/billing/webhook/paddle" WEBHOOK_PATH = "/billing/webhook/paddle"
SIG_HEADER = "Paddle-Signature" SIG_HEADER = "Paddle-Signature"

View File

@@ -3,8 +3,6 @@ Tests for role-based access control: role_required decorator, grant/revoke/ensur
and admin route protection. and admin route protection.
""" """
import pytest import pytest
from quart import Blueprint
from beanflows import core from beanflows import core
from beanflows.auth.routes import ( from beanflows.auth.routes import (
ensure_admin_role, ensure_admin_role,
@@ -12,6 +10,7 @@ from beanflows.auth.routes import (
revoke_role, revoke_role,
role_required, role_required,
) )
from quart import Blueprint
# ════════════════════════════════════════════════════════════ # ════════════════════════════════════════════════════════════
# grant_role / revoke_role # grant_role / revoke_role