diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b1c2b2b --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +# Команды разработки tabular-parser. Backend — api/.venv; запуск из корня репозитория. +VENV := api/.venv +BIN := $(CURDIR)/$(VENV)/bin +COMPOSE_FILE ?= ../docs/dev/docker-compose.yml + +.PHONY: venv lint test test-integration check docker-build check-full up + +# Python 3.11 (версия платформы); внутренние пакеты raisa_* вне банка недоступны — пропускаем их +venv: + cd api && uv venv --python 3.11 --allow-existing .venv + cd api && grep -v '^raisa_' requirements.txt | uv pip install --python .venv/bin/python -r - + cd api && grep -v '^-r' requirements-dev.txt | uv pip install --python .venv/bin/python -r - + +lint: + cd api && $(BIN)/ruff check . + cd api && $(BIN)/ruff format --check . + cd api && $(BIN)/mypy src + +# Код 5 («тесты не собраны») допускаем только до появления первых тестов; после — убрать обёртку +test: + cd api && $(BIN)/pytest -m "not integration"; rc=$$?; if [ $$rc -eq 5 ]; then echo "тестов пока нет (pytest exit 5) — допустимо"; exit 0; fi; exit $$rc + +test-integration: + cd api && $(BIN)/pytest -m integration + +check: lint test + +# Сборка образа из корня репозитория +docker-build: + docker build -t tabular-parser . + +# Полная проверка перед PR: быстрые проверки, затем NATS/MinIO из compose (make up), затем образ +check-full: check test-integration docker-build + +# Только инфраструктура, нужная сервису (без arm-core): NATS и MinIO; postgres — для общей среды compose +up: + docker compose -f $(COMPOSE_FILE) up -d --wait postgres nats minio diff --git a/README.md b/README.md index ff67937..38b931f 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ openspec/ требования и дельта текущего ср | `make check-full` | `make check` + `make test-integration` + `docker build`; запускать перед PR | | `make up` | `docker compose -f ../docs/dev/docker-compose.yml up -d --wait postgres nats minio` | -Цели `Makefile` появляются в задачах 2.1 (`venv`, `lint`, `test`, `test-integration`, `check`, `up`) и 5.1 (`check-full`). +Все цели `Makefile` (включая `check-full`) создаются задачей 2.1; `docker build` в `check-full` заработает после задачи 2.2 (`Dockerfile`). ## Запуск локально против compose diff --git a/api/pyproject.toml b/api/pyproject.toml new file mode 100644 index 0000000..048aae1 --- /dev/null +++ b/api/pyproject.toml @@ -0,0 +1,30 @@ +# Настройки инструментов качества (ruff, mypy). Зависимости — в requirements*.txt, pytest (маркеры, env) — в pytest.ini. + +[tool.ruff] +line-length = 120 +target-version = "py311" + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "B", "PL"] + +[tool.ruff.lint.isort] +known-first-party = ["src"] + +[tool.mypy] +python_version = "3.11" +strict = false +check_untyped_defs = true +plugins = ["pydantic.mypy"] +mypy_path = "." +explicit_package_bases = true + +# Сторонние пакеты без типов (или недоступные вне банка) +[[tool.mypy.overrides]] +module = ["nkeys.*", "nats.*", "raisa_fastapi_protected_api", "raisa_fastapi_protected_api.*"] +ignore_missing_imports = true + +# miniopy_async: пакет типизирован с ошибкой (Minio не виден mypy при реэкспорте) — типы не подтягиваем, Minio = Any +[[tool.mypy.overrides]] +module = ["miniopy_async", "miniopy_async.*"] +follow_imports = "skip" +ignore_missing_imports = true diff --git a/api/pytest.ini b/api/pytest.ini index 2dc434a..cf530e1 100644 --- a/api/pytest.ini +++ b/api/pytest.ini @@ -19,3 +19,6 @@ env = APP_ENV=test ENV_FILE=.env.test norecursedirs = .git __pycache__ .venv env build dist +markers = + integration: тесты, которым нужны NATS и MinIO (docker compose, make up); запускаются отдельно от юнит-тестов + fixtures: тесты на реальных данных из ../fixtures (внутренний доступ) diff --git a/api/requirements-dev.txt b/api/requirements-dev.txt index e4d6841..043c04c 100644 --- a/api/requirements-dev.txt +++ b/api/requirements-dev.txt @@ -1,50 +1,10 @@ -aiosqlite -alembic -annotated-types==0.7.0 -anyio==4.8.0 -argon2-cffi -asyncpg -certifi==2024.12.14 -click==8.1.8 -colorama==0.4.6 -dnspython==2.7.0 -email_validator==2.2.0 -et_xmlfile==2.0.0 -fastapi==0.115.7 -fastapi-cli==0.0.7 -h11==0.14.0 -httpcore==1.0.7 -httptools==0.6.4 -httpx==0.27.2 -idna==3.10 -itsdangerous==2.2.0 -Jinja2==3.1.5 -markdown-it-py==3.0.0 -MarkupSafe==3.0.2 -mdurl==0.1.2 -openpyxl==3.1.5 -orjson==3.10.15 -pydantic==2.10.6 -pydantic-extra-types==2.10.2 -pydantic-settings==2.7.1 -pydantic_core==2.27.2 -Pygments==2.19.1 -python-dotenv==1.0.1 -python-jose -python-multipart==0.0.20 -PyYAML==6.0.2 -rich==13.9.4 -rich-toolkit==0.13.2 -shellingham==1.5.4 -sniffio==1.3.1 -sqlalchemy -starlette==0.45.3 -typer==0.15.1 -typing_extensions==4.12.2 -ujson==5.10.0 -uvicorn==0.34.0 -watchfiles==1.0.4 -websockets==14.2 -pytest-asyncio -pytest-env -cosmic-ray \ No newline at end of file +# Инструменты разработки и проверок. Платформенные зависимости — в requirements.txt (не меняем). +# Нижние границы мажорных версий: воспроизводимо, но без конфликта с пинами платформы. +-r requirements.txt +ruff>=0.8 +mypy>=1.13 +pytest>=8.3 +pytest-asyncio>=0.24 +pytest-env>=1.1 +httpx>=0.27 +jsonschema>=4.23 diff --git a/docs/superpowers/plans/2026-10-03-slice-0-skeleton.md b/docs/superpowers/plans/2026-10-03-slice-0-skeleton.md index 72d68ea..ee785d7 100644 --- a/docs/superpowers/plans/2026-10-03-slice-0-skeleton.md +++ b/docs/superpowers/plans/2026-10-03-slice-0-skeleton.md @@ -31,7 +31,7 @@ ### Task 4: [2.1] `api/pyproject.toml` (ruff -- [ ] `api/pyproject.toml` (ruff: line-length 120, E,F,I,UP,B,PL; mypy с плагином pydantic), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`; проверка: `make venv && make lint` зелёные +- [x] `api/pyproject.toml` (ruff: line-length 120, E,F,I,UP,B,PL; mypy с плагином pydantic), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`; проверка: `make venv && make lint` зелёные ### Task 5: [2.2] `Dockerfile` (`python diff --git a/openspec/changes/slice-0-skeleton/tasks.md b/openspec/changes/slice-0-skeleton/tasks.md index 5cda2a4..1ec1b1a 100644 --- a/openspec/changes/slice-0-skeleton/tasks.md +++ b/openspec/changes/slice-0-skeleton/tasks.md @@ -18,7 +18,7 @@ ## 2. Инструменты -- [ ] 2.1 `api/pyproject.toml` (ruff: line-length 120, E,F,I,UP,B,PL; mypy с плагином pydantic), `requirements-dev.txt` +- [x] 2.1 `api/pyproject.toml` (ruff: line-length 120, E,F,I,UP,B,PL; mypy с плагином pydantic), `requirements-dev.txt` = `-r requirements.txt` + ruff, mypy, pytest, pytest-asyncio, pytest-env, httpx, jsonschema; `Makefile`: `venv` (python3.11), `lint`, `test`, `test-integration`, `check`, `check-full`, `up`; проверка: `make venv && make lint` зелёные - [ ] 2.2 `Dockerfile` (`python:3.11-slim`), `.env.example`, `.env.test`; проверка: `docker build -t tabular-parser .` успешен