Files
flowsint/Makefile
T
dextmorgn 8b49497965 build(python): replace black+isort+flake8 with ruff
One tool instead of three, one config instead of four duplicated
blocks. black/isort/flake8 dropped from every package's dev deps,
ruff added once; .flake8 deleted, [tool.black]/[tool.isort] blocks
deleted from all 4 sub-package pyproject.toml files.

Config lives once, at the workspace root: ruff walks up from any file
it's checking until it finds a pyproject.toml with a [tool.ruff]
table (verified empirically — a package's own pyproject.toml lacking
that table doesn't stop the search), so the root-level [tool.ruff]
applies to all four packages without duplication. That's the one real
win over the old per-package black/isort blocks, which had to be
copy-pasted four times and kept in sync by hand.

Same rule surface as before, not more: select = E/F/W/I (pycodestyle
+ pyflakes + isort-equivalent), matching exactly what flake8 checked.
ruff has other rule groups (UP/pyupgrade, B/bugbear) that would
surface real things — deliberately left off. Turning those on finds
new debt and is a separate decision with its own diff to review, not
a side effect of swapping the tool underneath an unchanged rule set.
Same E501 exclusion carried over too, same reasoning: the formatter
is the sole authority on line length.

known-first-party carries over unchanged (same isort concern this
repo already fixed once — see "app" vs "flowsint_api" in the ratchet
history) and the wildcard-import per-file-ignore for
flowsint_core/__init__.py still applies, verified directly.

Six files reformatted by `ruff format` where it disagreed with black
on edge cases (import grouping, ternary line-breaking, blank lines
after a class statement) — all cosmetic, no behavior change, reviewed
diff by diff. One real ruff-check finding (an import block ruff's
isort-equivalent wanted sorted differently) — took ruff check --fix.

Verified: `make lint` clean, `make test` green (all 4 packages),
lint-staged tested with a real staged-file run (not just config
inspection) to confirm `uv run ruff format` / `uv run ruff check --fix`
actually execute, mypy ratchet target unaffected (still fires on its
own pre-existing backlog, unrelated to this change).
2026-08-25 09:33:34 +02:00

248 lines
7.5 KiB
Makefile

PROJECT_ROOT := $(shell pwd)
COMPOSE_DEV := docker compose -f docker-compose.dev.yml
COMPOSE_PROD := docker compose -f docker-compose.prod.yml
.PHONY: \
dev prod \
build-dev \
up-dev up-prod down \
infra-dev infra-prod infra-stop-dev infra-stop-prod \
migrate-dev migrate-prod \
alembic-upgrade alembic-downgrade alembic-revision \
api frontend celery \
test install clean check-env open-browser-dev open-browser-prod \
logs-dev logs-prod status \
regenerate-router \
lint lint-fix typecheck
ENV_DIRS := . flowsint-api flowsint-core flowsint-app
check-env:
@echo "Checking .env files..."
@for dir in $(ENV_DIRS); do \
env_file="$$dir/.env"; \
env_example="$(PROJECT_ROOT)/.env.example"; \
if [ ! -f "$$env_file" ]; then \
cp "$$env_example" "$$env_file"; \
echo "Created $$env_file"; \
fi; \
done
dev:
@echo "Starting DEV environment..."
$(MAKE) check-env
$(MAKE) build-dev
$(MAKE) up-dev
$(MAKE) open-browser-dev
$(COMPOSE_DEV) logs -f
build-dev:
@echo "Building DEV images..."
$(COMPOSE_DEV) build
up-dev:
$(COMPOSE_DEV) up -d
infra-dev:
@echo "Starting DEV infra (postgres / redis / neo4j)..."
$(COMPOSE_DEV) up -d postgres redis neo4j
infra-stop-dev:
@echo "Stopping DEV infra..."
$(COMPOSE_DEV) stop postgres redis neo4j
logs-dev:
$(COMPOSE_DEV) logs -f
open-browser-dev:
@echo "Waiting for frontend on port 5173..."
@bash -c 'until curl -s http://localhost:5173 > /dev/null 2>&1; do sleep 1; done'
@open http://localhost:5173 2>/dev/null || \
xdg-open http://localhost:5173 2>/dev/null || \
echo "Frontend ready at http://localhost:5173"
prod:
@echo "Starting PROD environment (pre-built images)..."
$(MAKE) check-env
$(COMPOSE_PROD) pull
$(MAKE) up-prod
@echo ""
@echo "Production started!"
@echo " Frontend: http://localhost:5173"
@echo " API: http://localhost:5173/api (proxied)"
up-prod:
$(COMPOSE_PROD) up -d
infra-prod:
@echo "Starting PROD infra (postgres / redis / neo4j)..."
$(COMPOSE_PROD) up -d postgres redis neo4j
infra-stop-prod:
@echo "Stopping PROD infra..."
$(COMPOSE_PROD) stop postgres redis neo4j
logs-prod:
$(COMPOSE_PROD) logs -f
open-browser-prod:
@echo "Waiting for frontend on port 5173..."
@bash -c 'until curl -s http://localhost:5173 > /dev/null 2>&1; do sleep 2; done'
@open http://localhost:5173 2>/dev/null || \
xdg-open http://localhost:5173 2>/dev/null || \
echo "Frontend ready at http://localhost:5173"
migrate-dev:
@echo "Running DEV migrations..."
@if ! $(COMPOSE_DEV) ps -q neo4j | grep -q .; then \
echo "Neo4j not running → starting DEV infra"; \
$(COMPOSE_DEV) up -d --wait neo4j; \
fi
yarn migrate
migrate-prod:
@echo "⚠️ Running PROD migrations"
@echo "This will ALTER production data."
@read -p "Type 'prod' to continue: " confirm; \
if [ "$$confirm" != "prod" ]; then \
echo "Aborted."; exit 1; \
fi
yarn migrate
alembic-upgrade:
@echo "Running Alembic migrations (upgrade head)..."
cd $(PROJECT_ROOT)/flowsint-api && uv run alembic upgrade head
alembic-downgrade:
@echo "Rolling back last Alembic migration..."
cd $(PROJECT_ROOT)/flowsint-api && uv run alembic downgrade -1
alembic-revision:
@if [ -z "$(m)" ]; then \
echo "Usage: make alembic-revision m=\"your migration message\""; exit 1; \
fi
@echo "Creating new Alembic migration: $(m)"
cd $(PROJECT_ROOT)/flowsint-api && uv run alembic revision --autogenerate -m "$(m)"
api:
cd $(PROJECT_ROOT)/flowsint-api && \
uv run uvicorn app.main:app --host 0.0.0.0 --port 5001 --reload
frontend:
cd $(PROJECT_ROOT)/flowsint-app && yarn dev
celery:
cd $(PROJECT_ROOT)/flowsint-api && \
uv run celery -A flowsint_core.core.celery \
worker --loglevel=info --pool=threads --concurrency=10
test:
cd flowsint-types && uv run pytest
cd flowsint-core && uv run pytest
cd flowsint-enrichers && uv run pytest
cd flowsint-api && uv run pytest
PY_SRC := flowsint-core/src flowsint-core/tests \
flowsint-api/app flowsint-api/tests \
flowsint-enrichers/src flowsint-enrichers/tests \
flowsint-types/src flowsint-types/tests
# Full-repo, blocking: formatting and lint are 100% clean today, so any
# regression here is new debt — no reason to let it in. ruff replaces
# black+isort+flake8 (one tool, one config — see [tool.ruff] in the root
# pyproject.toml, which every package's ruff invocation inherits by walking
# up the directory tree to find it).
lint:
uv run ruff format --check $(PY_SRC)
uv run ruff check $(PY_SRC)
lint-fix:
uv run ruff format $(PY_SRC)
uv run ruff check --fix $(PY_SRC)
# mypy has ~2200 pre-existing errors across the workspace (real, not fixed
# blindly in one pass — see CI notes). Gating full-repo would be a
# lie from day one. Ratchet instead: block only on files this branch touches,
# so new code is held to the strict config and the backlog shrinks as files
# get touched, without a red CI on every unrelated PR.
BASE_REF ?= origin/main
typecheck:
@changed=$$(git diff --name-only --diff-filter=ACMR $(BASE_REF)...HEAD -- '*.py' 2>/dev/null); \
if [ -z "$$changed" ]; then \
echo "No changed Python files vs $(BASE_REF) — skipping mypy."; \
exit 0; \
fi; \
echo "$$changed"; \
mypy_status=0; \
for pkg in flowsint-core flowsint-api flowsint-enrichers flowsint-types; do \
files=$$(echo "$$changed" | grep "^$$pkg/" | sed "s|^$$pkg/||"); \
[ -z "$$files" ] && continue; \
echo "== mypy: $$pkg =="; \
(cd $$pkg && echo "$$files" | xargs -r uv run mypy) || mypy_status=1; \
done; \
exit $$mypy_status
install:
$(MAKE) infra-dev
uv sync
cd flowsint-api && uv run alembic upgrade head
status:
@echo "=== DEV Containers ==="
@$(COMPOSE_DEV) ps 2>/dev/null || echo "No DEV containers"
@echo ""
@echo "=== PROD Containers ==="
@$(COMPOSE_PROD) ps 2>/dev/null || echo "No PROD containers"
down:
-$(COMPOSE_DEV) down
-$(COMPOSE_PROD) down
clean:
@echo "This will remove ALL Docker data. Continue? [y/N]"
@read confirm; \
if [ "$$confirm" != "y" ]; then exit 1; fi
-$(COMPOSE_DEV) down -v --rmi all --remove-orphans
-$(COMPOSE_PROD) down -v --rmi all --remove-orphans
rm -rf flowsint-app/node_modules
rm -rf .venv
regenerate-router:
@echo "Regenerating flowsint-app/src/routeTree.gen.ts"
cd $(PROJECT_ROOT)/flowsint-app && npx tsr generate
help:
@echo "Flowsint Makefile"
@echo ""
@echo "Development:"
@echo " make dev - Start DEV environment (local build, hot-reload)"
@echo " make build-dev - Build DEV images"
@echo " make up-dev - Start DEV containers"
@echo " make logs-dev - Follow DEV logs"
@echo " make infra-dev - Start only infra (postgres/redis/neo4j)"
@echo ""
@echo "Production (pre-built GHCR images):"
@echo " make prod - Pull images and start PROD environment"
@echo " make up-prod - Start PROD containers"
@echo " make logs-prod - Follow PROD logs"
@echo ""
@echo "Local (no Docker):"
@echo " make api - Run API locally"
@echo " make frontend - Run frontend locally"
@echo " make celery - Run Celery worker locally"
@echo ""
@echo "Migrations:"
@echo " make migrate-dev - Run Neo4j DEV migrations"
@echo " make migrate-prod - Run Neo4j PROD migrations"
@echo " make alembic-upgrade - Run Alembic migrations (upgrade head)"
@echo " make alembic-downgrade - Rollback last Alembic migration"
@echo " make alembic-revision m=.. - Create new Alembic migration"
@echo ""
@echo "Utilities:"
@echo " make status - Show container status"
@echo " make down - Stop all containers"
@echo " make clean - Remove all Docker data"
@echo " make install - Install dependencies locally"
@echo " make test - Run tests"