chore: add mise format and lint tasks (ruff + Biome)

Tools are pinned in mise.toml. ruff.toml points first-party detection at backend/, since the frontend's src/auth, src/books and src/notes otherwise get matched as first-party. biome.json uses spaces to match the existing Prettier-style formatting. Also combines a nested with in test_passwords.py (ruff SIM117).
This commit is contained in:
2026-10-02 15:06:56 -05:00
parent 0801a69cc0
commit d9b824851a
4 changed files with 41 additions and 5 deletions
+4 -3
View File
@@ -8,7 +8,6 @@ from unittest import mock
from auth import ITERATIONS, hash_password, load_pepper, needs_rehash, verify_password from auth import ITERATIONS, hash_password, load_pepper, needs_rehash, verify_password
PEPPER = b"p" * 32 PEPPER = b"p" * 32
# Independently computed: HMAC-SHA256(PEPPER, password) -> PBKDF2-SHA256, 1000 iterations, 16 zero-byte salt.
KNOWN_ANSWER = "pbkdf2_sha256$1000$AAAAAAAAAAAAAAAAAAAAAA==$9ZLLEusnEPU3Km8h+vnd4ue9fw7rHdm4QwuBX5ozynE=" KNOWN_ANSWER = "pbkdf2_sha256$1000$AAAAAAAAAAAAAAAAAAAAAA==$9ZLLEusnEPU3Km8h+vnd4ue9fw7rHdm4QwuBX5ozynE="
@@ -41,8 +40,10 @@ class PasswordHashTests(unittest.TestCase):
class PepperTests(unittest.TestCase): class PepperTests(unittest.TestCase):
def test_env_pepper_must_be_long_enough(self): def test_env_pepper_must_be_long_enough(self):
with mock.patch.dict(os.environ, {"PASSWORD_PEPPER": "short"}): with (
with self.assertRaisesRegex(RuntimeError, "at least 32 characters"): mock.patch.dict(os.environ, {"PASSWORD_PEPPER": "short"}),
self.assertRaisesRegex(RuntimeError, "at least 32 characters"),
):
load_pepper(Path("/nonexistent")) load_pepper(Path("/nonexistent"))
def test_env_pepper_is_used_when_set(self): def test_env_pepper_is_used_when_set(self):
+6
View File
@@ -0,0 +1,6 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.15/schema.json",
"formatter": {
"indentStyle": "space"
}
}
+26 -1
View File
@@ -1,10 +1,11 @@
[tools] [tools]
python = "3.14" python = "3.14"
node = "24" node = "24"
ruff = "0.16.10"
biome = "2.5.15"
[tasks.setup] [tasks.setup]
description = "Create the venv and install backend and frontend dependencies" description = "Create the venv and install backend and frontend dependencies"
# ponytail: reinstalls on every run (fast when up to date); add sources/outputs if it ever gets slow
run = [ run = [
"python -m venv .venv", "python -m venv .venv",
".venv/bin/pip install -q --disable-pip-version-check -r backend/requirements.txt", ".venv/bin/pip install -q --disable-pip-version-check -r backend/requirements.txt",
@@ -31,3 +32,27 @@ run = "npm run dev"
[tasks.dev] [tasks.dev]
description = "Start the app for local testing (API + UI)" description = "Start the app for local testing (API + UI)"
depends = ["dev:api", "dev:web"] depends = ["dev:api", "dev:web"]
[tasks."format:py"]
description = "Sort imports and format the backend"
run = ["ruff check --select I --fix backend", "ruff format backend"]
[tasks."format:ts"]
description = "Sort imports and format the frontend"
run = "biome check --write --linter-enabled=false src vite.config.ts"
[tasks.format]
description = "Format and auto-fix Python and TypeScript"
depends = ["format:py", "format:ts"]
[tasks."lint:py"]
description = "Lint the backend and verify formatting (no writes)"
run = ["ruff check backend", "ruff format --check backend"]
[tasks."lint:ts"]
description = "Lint the frontend and verify formatting (no writes)"
run = "biome check src vite.config.ts"
[tasks.lint]
description = "Lint and format-check Python and TypeScript (CI-safe, no writes)"
depends = ["lint:py", "lint:ts"]
+4
View File
@@ -0,0 +1,4 @@
# The backend imports its modules as top-level names (`import db`). Without this, ruff's
# first-party detection matches the frontend's src/auth, src/books, src/notes directories
# instead, and splits backend imports into two groups.
src = ["backend"]