Spaces:
Running
Running
| # Makefile β Picarones | |
| # Usage : make <cible> | |
| # Cibles principales : install, test, demo, serve, build, build-exe, docker-build, clean | |
| build build-exe docker-build docker-run docker-compose-up clean help | |
| PYTHON := python3 | |
| PIP := pip | |
| VENV := .venv | |
| VENV_BIN := $(VENV)/bin | |
| PICARONES := $(VENV_BIN)/picarones | |
| PYTEST := $(VENV_BIN)/pytest | |
| PACKAGE := picarones | |
| # Couleurs | |
| BOLD := \033[1m | |
| GREEN := \033[32m | |
| CYAN := \033[36m | |
| RESET := \033[0m | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Aide | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| help: ## Affiche cette aide | |
| @echo "" | |
| @echo "$(BOLD)Picarones β Commandes disponibles$(RESET)" | |
| @echo "" | |
| @grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) \ | |
| | sort \ | |
| | awk 'BEGIN {FS = ":.*## "}; {printf " $(CYAN)%-18s$(RESET) %s\n", $$1, $$2}' | |
| @echo "" | |
| all: install test ## Installer et tester | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Installation | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| $(VENV): | |
| $(PYTHON) -m venv $(VENV) | |
| install: $(VENV) ## Installe Picarones en mode Γ©ditable (dΓ©pendances de base) | |
| $(VENV_BIN)/pip install --upgrade pip | |
| $(VENV_BIN)/pip install -e . | |
| @echo "$(GREEN)β Installation de base terminΓ©e$(RESET)" | |
| @echo " Activez l'environnement : source $(VENV)/bin/activate" | |
| install-dev: $(VENV) ## Installe avec les dΓ©pendances de dΓ©veloppement (tests, lint) | |
| $(VENV_BIN)/pip install --upgrade pip | |
| $(VENV_BIN)/pip install -e ".[dev]" | |
| @echo "$(GREEN)β Installation dev terminΓ©e$(RESET)" | |
| install-web: $(VENV) ## Installe avec l'interface web (FastAPI + uvicorn) | |
| $(VENV_BIN)/pip install --upgrade pip | |
| $(VENV_BIN)/pip install -e ".[web,dev]" | |
| @echo "$(GREEN)β Installation web terminΓ©e$(RESET)" | |
| install-all: $(VENV) ## Installe avec tous les extras (web, HuggingFace, dev) | |
| $(VENV_BIN)/pip install --upgrade pip | |
| $(VENV_BIN)/pip install -e ".[web,hf,dev]" | |
| @echo "$(GREEN)β Installation complΓ¨te terminΓ©e$(RESET)" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Tests | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| test: ## Lance la suite de tests complète | |
| $(PYTEST) tests/ -q --tb=short | |
| @echo "$(GREEN)β Tests terminΓ©s$(RESET)" | |
| test-cov: ## Tests avec rapport de couverture HTML | |
| $(PYTEST) tests/ --cov=$(PACKAGE) --cov-report=html --cov-report=term-missing -q | |
| @echo "$(GREEN)β Rapport de couverture : htmlcov/index.html$(RESET)" | |
| test-fast: ## Tests rapides uniquement (exclut les tests lents) | |
| $(PYTEST) tests/ -q --tb=short -x | |
| test-sprint9: ## Tests Sprint 9 uniquement | |
| $(PYTEST) tests/integration/test_packaging.py -v | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # QualitΓ© du code | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| lint: ## VΓ©rifie le style du code (configuration lue depuis pyproject.toml) | |
| @# La config ruff vit dans [tool.ruff] de pyproject.toml : cette cible, | |
| @# le job CI et une invocation directe `ruff check` produisent le mΓͺme | |
| @# rΓ©sultat. Lancez avant tout push pour Γ©viter un Γ©chec en PR. | |
| @if command -v ruff > /dev/null 2>&1; then \ | |
| ruff check $(PACKAGE)/ tests/; \ | |
| elif $(VENV_BIN)/python -m ruff --version > /dev/null 2>&1; then \ | |
| $(VENV_BIN)/python -m ruff check $(PACKAGE)/ tests/; \ | |
| else \ | |
| echo "ruff non installΓ© β installation : pip install ruff"; \ | |
| exit 1; \ | |
| fi | |
| doc-check: ## Audit de cohΓ©rence README/SPECS/CHANGELOG (Sprint A2) | |
| @# Vérifie que la documentation reflète le code réel : moteurs annoncés | |
| @# ont un adapter, commandes CLI listΓ©es existent, endpoints API | |
| @# documentΓ©s sont exposΓ©s, compteur de tests Γ jour, sprints | |
| @# rΓ©fΓ©rencΓ©s dans CHANGELOG rΓ©solvent. Voir docs/developer/doc-consistency.md. | |
| @# Fallback Python système si .venv/ absent (pattern aligné avec ``lint``). | |
| @if [ -x $(VENV_BIN)/python ]; then \ | |
| $(VENV_BIN)/python -m pytest tests/docs/ -q --tb=short --no-header; \ | |
| else \ | |
| $(PYTHON) -m pytest tests/docs/ -q --tb=short --no-header; \ | |
| fi | |
| sync-counters: ## Régénère README/CLAUDE.md avec les compteurs réels (script gen_readme_tables.py) | |
| @if [ -x $(VENV_BIN)/python ]; then \ | |
| $(VENV_BIN)/python scripts/gen_readme_tables.py; \ | |
| else \ | |
| $(PYTHON) scripts/gen_readme_tables.py; \ | |
| fi | |
| sync-counters-check: ## CI : Γ©choue si README/CLAUDE.md divergent du code (compteurs tests + tables) | |
| @if [ -x $(VENV_BIN)/python ]; then \ | |
| $(VENV_BIN)/python scripts/gen_readme_tables.py --check; \ | |
| else \ | |
| $(PYTHON) scripts/gen_readme_tables.py --check; \ | |
| fi | |
| docs: ## Construit le site mkdocs en mode strict (Γ©choue sur les warnings) | |
| @if [ -x $(VENV_BIN)/python ]; then \ | |
| $(VENV_BIN)/python -m mkdocs build --strict; \ | |
| else \ | |
| $(PYTHON) -m mkdocs build --strict; \ | |
| fi | |
| docs-serve: ## Lance mkdocs en mode dev (http://localhost:8000) | |
| @if [ -x $(VENV_BIN)/python ]; then \ | |
| $(VENV_BIN)/python -m mkdocs serve; \ | |
| else \ | |
| $(PYTHON) -m mkdocs serve; \ | |
| fi | |
| typecheck: ## VΓ©rification de types avec mypy (si installΓ©) | |
| @$(VENV_BIN)/python -m mypy $(PACKAGE)/ --ignore-missing-imports --no-strict-optional 2>/dev/null \ | |
| || echo "mypy non installΓ© : pip install mypy" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # DΓ©monstration | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| demo: ## Génère un rapport de démonstration complet (rapport_demo.html) | |
| $(PICARONES) demo --docs 12 --output rapport_demo.html \ | |
| --with-history --with-robustness | |
| @echo "$(GREEN)β Rapport demo : rapport_demo.html$(RESET)" | |
| @echo " Ouvrez : file://$(PWD)/rapport_demo.html" | |
| demo-json: ## Génère rapport demo + export JSON | |
| $(PICARONES) demo --docs 12 --output rapport_demo.html --json-output resultats_demo.json | |
| @echo "$(GREEN)β Rapport : rapport_demo.html | JSON : resultats_demo.json$(RESET)" | |
| demo-history: ## DΓ©monstration du suivi longitudinal | |
| $(PICARONES) history --demo --regression | |
| demo-robustness: ## DΓ©monstration de l'analyse de robustesse | |
| mkdir -p /tmp/picarones_demo_corpus | |
| $(PICARONES) robustness \ | |
| --corpus /tmp/picarones_demo_corpus \ | |
| --engine tesseract \ | |
| --demo \ | |
| --degradations noise,blur,rotation | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Serveur web | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| serve: ## Lance l'interface web locale (http://localhost:8000) | |
| $(PICARONES) serve --host 127.0.0.1 --port 8000 | |
| serve-public: ## Lance le serveur en mode public (0.0.0.0:8000) | |
| $(PICARONES) serve --host 0.0.0.0 --port 8000 | |
| serve-dev: ## Lance le serveur en mode dΓ©veloppement (rechargement automatique) | |
| $(PICARONES) serve --reload --verbose | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Build & packaging | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| build: ## Construit la distribution Python (wheel + sdist) | |
| $(VENV_BIN)/pip install --upgrade build | |
| $(VENV_BIN)/python -m build | |
| @echo "$(GREEN)β Distribution : dist/$(RESET)" | |
| build-exe: ## Génère un exécutable standalone avec PyInstaller | |
| @echo "$(CYAN)Construction de l'exΓ©cutable standaloneβ¦$(RESET)" | |
| $(VENV_BIN)/pip install pyinstaller | |
| $(VENV_BIN)/pyinstaller picarones.spec --noconfirm | |
| @echo "$(GREEN)β ExΓ©cutable : dist/picarones/$(RESET)" | |
| build-exe-onefile: ## Génère un exécutable unique (plus lent au démarrage) | |
| $(VENV_BIN)/pip install pyinstaller | |
| $(VENV_BIN)/pyinstaller picarones.spec --noconfirm --onefile | |
| @echo "$(GREEN)β ExΓ©cutable : dist/picarones$(RESET)" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Docker | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Version dΓ©rivΓ©e du package (setuptools-scm), repli ``dev`` si le | |
| # paquet n'est pas installΓ© sur la machine de build. Plus de tag | |
| # ``1.0.0`` figΓ© qui ment sur la version rΓ©elle. | |
| DOCKER_VERSION := $(shell python -c "import importlib.metadata as m; print(m.version('picarones'))" 2>/dev/null || echo dev) | |
| docker-build: ## Construit l'image Docker Picarones | |
| docker build --build-arg PICARONES_VERSION=$(DOCKER_VERSION) \ | |
| -t picarones:latest -t picarones:$(DOCKER_VERSION) . | |
| @echo "$(GREEN)β Image Docker : picarones:latest (= picarones:$(DOCKER_VERSION))$(RESET)" | |
| docker-run: ## Lance Picarones dans Docker (http://localhost:7860) | |
| docker run --rm -p 7860:7860 \ | |
| -e OPENAI_API_KEY="$${OPENAI_API_KEY:-}" \ | |
| -e ANTHROPIC_API_KEY="$${ANTHROPIC_API_KEY:-}" \ | |
| -e MISTRAL_API_KEY="$${MISTRAL_API_KEY:-}" \ | |
| -v "$(PWD)/corpus:/app/corpus:ro" \ | |
| picarones:latest | |
| docker-compose-up: ## Lance Picarones + Ollama avec Docker Compose | |
| docker compose up -d | |
| @echo "$(GREEN)β Services dΓ©marrΓ©s$(RESET)" | |
| @echo " Picarones : http://localhost:7860" | |
| @echo " Ollama : http://localhost:11434" | |
| docker-compose-down: ## ArrΓͺte les services Docker Compose | |
| docker compose down | |
| docker-compose-logs: ## Affiche les logs Docker Compose | |
| docker compose logs -f picarones | |
| compose-check: ## Valide que docker-compose.yml seul + le merge avec prod.yml sont syntaxiquement corrects | |
| @# Sans cette validation, une incohΓ©rence dans le merge (variable | |
| @# non hΓ©ritΓ©e, port surchargΓ© mal, conflit de services) ne se | |
| @# voit qu'au dΓ©ploiement. Le secret CSRF est forcΓ© sur une | |
| @# valeur factice pour permettre l'Γ©valuation YAML (prod.yml | |
| @# exige ``${PICARONES_CSRF_SECRET:?...}``) β la valeur n'est | |
| @# jamais utilisΓ©e. | |
| @docker compose -f docker-compose.yml config > /dev/null | |
| @PICARONES_CSRF_SECRET=compose-check-not-a-real-secret \ | |
| docker compose -f docker-compose.yml -f docker-compose.prod.yml config > /dev/null | |
| @echo "$(GREEN)β compose merge (local + prod) syntaxiquement valide$(RESET)" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Nettoyage | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| clean: ## Supprime les fichiers gΓ©nΓ©rΓ©s (cache, build, dist) | |
| find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true | |
| find . -type f -name "*.pyc" -delete 2>/dev/null || true | |
| find . -type f -name "*.pyo" -delete 2>/dev/null || true | |
| find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true | |
| rm -rf dist/ build/ .eggs/ htmlcov/ .coverage .pytest_cache/ | |
| @echo "$(GREEN)β Nettoyage terminΓ©$(RESET)" | |
| clean-all: clean ## Supprime aussi l'environnement virtuel | |
| rm -rf $(VENV)/ | |
| @echo "$(GREEN)β Environnement virtuel supprimΓ©$(RESET)" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Utilitaires | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| info: ## Affiche les informations de version Picarones | |
| $(PICARONES) info | |
| engines: ## Liste les moteurs OCR disponibles | |
| $(PICARONES) engines | |
| history-demo: ## Affiche l'historique de dΓ©monstration | |
| $(PICARONES) history --demo --regression | |
| changelog: ## Affiche le CHANGELOG | |
| @cat CHANGELOG.md | head -80 | |
| version: ## Affiche la version courante | |
| @grep -m1 'version' pyproject.toml | awk '{print $$3}' | tr -d '"' | |