Claude commited on
Commit
a76711b
·
unverified ·
1 Parent(s): b20a7dc

Centraliser la config ruff et rendre le lint bloquant (vrai fix)

Browse files

Les deux corrections précédentes (de4ff68 sur picarones/, b20a7dc sur
tests/) étaient du rafistolage — elles enlevaient les symptômes sans
traiter la cause. La cause réelle : **trois configurations ruff
divergentes** sur le projet, et **aucun filet local** avant le push.

État de départ problématique :

1. `.github/workflows/ci.yml` : appelait ruff avec des flags
`--select=E,W,F --ignore=E501,E402`, ET avait `continue-on-error:
true` (donc le lint était décoratif).
2. `Makefile::lint` : appelait `ruff check $(PACKAGE)/ tests/` SANS
flags — prenait la config ruff par défaut, DIFFÉRENTE du CI.
3. `pyproject.toml` : aucune section `[tool.ruff]`.

Résultat : `make lint` pouvait dire "OK" localement pendant que le CI
trouvait des erreurs. Et même si le CI trouvait des erreurs, le lint
ne bloquait pas la PR. D'où l'accumulation de 10 erreurs F401/E741 sur
les sprints 16-21, découvertes par vagues successives.

Correctif de fond :

- `pyproject.toml` : ajout de `[tool.ruff]` (line-length=100,
target=py311) et `[tool.ruff.lint]` (select=E,W,F, ignore=E501,E402).
Les règles retenues sont celles du CI d'origine — aucune rupture de
contrat, juste une centralisation.
- `.github/workflows/ci.yml` : la commande passe de
`ruff check picarones/ --select=... && ruff check tests/ --select=...`
à simplement `ruff check picarones/ tests/`. La config vient du
pyproject.toml. **Suppression de `continue-on-error: true`** — le
lint devient bloquant, cohérent avec les jobs tests/build/demo.
- `Makefile::lint` : passe à `ruff check $(PACKAGE)/ tests/` (identique
au CI). Le fallback flake8 est retiré (ruff est la seule voie
officielle, moins de chemins à maintenir). Si ruff n'est pas installé,
on sort avec code 1 et un message explicite au lieu d'un silence qui
laissait croire que c'était vert.
- `CLAUDE.md` : nouvelle règle explicite — `make lint` avant tout push,
le job `lint` du CI est bloquant par design.

Vérifications :
- `ruff check picarones/ tests/` : All checks passed!
- `make lint` : All checks passed!
- `ruff check --show-settings` : line_length=100, py311, select
correctement chargé depuis pyproject.toml
- Suite complète : 1241 passed, 2 skipped (inchangée)

Conséquence : toute future erreur lint sera attrapée localement avant
le push. Plus d'allers-retours CI pour des imports oubliés.

https://claude.ai/code/session_0162FdNNJyNvBuYzkgtsr9VB

Files changed (4) hide show
  1. .github/workflows/ci.yml +5 -5
  2. CLAUDE.md +5 -0
  3. Makefile +6 -4
  4. pyproject.toml +13 -0
.github/workflows/ci.yml CHANGED
@@ -175,12 +175,14 @@ jobs:
175
  retention-days: 30
176
 
177
  # ──────────────────────────────────────────────────────────────────
178
- # Job 4 : Vérification de la qualité du code (optionnel)
 
 
 
179
  # ──────────────────────────────────────────────────────────────────
180
  lint:
181
  name: Code quality
182
  runs-on: ubuntu-latest
183
- continue-on-error: true # Ne bloque pas le CI si le lint échoue
184
 
185
  steps:
186
  - name: Checkout
@@ -196,9 +198,7 @@ jobs:
196
  run: pip install ruff
197
 
198
  - name: Run ruff
199
- run: |
200
- ruff check picarones/ --select=E,W,F --ignore=E501,E402
201
- ruff check tests/ --select=E,W,F --ignore=E501,E402
202
 
203
  # ──────────────────────────────────────────────────────────────────
204
  # Job 5 : CI/CD — Détection de régression CER (optionnel)
 
175
  retention-days: 30
176
 
177
  # ──────────────────────────────────────────────────────────────────
178
+ # Job 4 : Vérification de la qualité du code
179
+ # La config ruff est centralisée dans pyproject.toml ([tool.ruff]),
180
+ # donc CI, Makefile et invocations locales produisent exactement les
181
+ # mêmes résultats — pas de divergence possible entre flags.
182
  # ──────────────────────────────────────────────────────────────────
183
  lint:
184
  name: Code quality
185
  runs-on: ubuntu-latest
 
186
 
187
  steps:
188
  - name: Checkout
 
198
  run: pip install ruff
199
 
200
  - name: Run ruff
201
+ run: ruff check picarones/ tests/
 
 
202
 
203
  # ──────────────────────────────────────────────────────────────────
204
  # Job 5 : CI/CD — Détection de régression CER (optionnel)
CLAUDE.md CHANGED
@@ -128,6 +128,11 @@ correspondants (`test_sprint15_llm_pipeline_bugs.py`, `test_sprint8_escriptorium
128
  `logger.warning("[module] fonctionnalité dégradée : %s", e)`.
129
  - **Toujours utiliser `logger.warning` avec message explicite** quand une fonctionnalité optionnelle
130
  échoue (confusion, taxonomy, structure, image_quality, etc.).
 
 
 
 
 
131
  - **Les profils de normalisation** sont dans `picarones/core/normalization.py` — l'endpoint
132
  `/api/normalization/profiles` doit les lire dynamiquement depuis ce fichier, pas depuis une
133
  liste statique.
 
128
  `logger.warning("[module] fonctionnalité dégradée : %s", e)`.
129
  - **Toujours utiliser `logger.warning` avec message explicite** quand une fonctionnalité optionnelle
130
  échoue (confusion, taxonomy, structure, image_quality, etc.).
131
+ - **Avant tout push, lancer `make lint`** (ou `ruff check picarones/ tests/`).
132
+ La config est centralisée dans `pyproject.toml` sous `[tool.ruff]`, donc
133
+ CI, Makefile et invocation directe produisent le même résultat. Le job
134
+ `lint` du CI est bloquant — un F401 (import inutilisé) ou un E741
135
+ (variable ambiguë) fait échouer la PR, par design.
136
  - **Les profils de normalisation** sont dans `picarones/core/normalization.py` — l'endpoint
137
  `/api/normalization/profiles` doit les lire dynamiquement depuis ce fichier, pas depuis une
138
  liste statique.
Makefile CHANGED
@@ -84,15 +84,17 @@ test-sprint9: ## Tests Sprint 9 uniquement
84
  # Qualité du code
85
  # ──────────────────────────────────────────────────────────────────
86
 
87
- lint: ## Vérifie le style du code (ruff si disponible, sinon flake8)
 
 
 
88
  @if command -v ruff > /dev/null 2>&1; then \
89
  ruff check $(PACKAGE)/ tests/; \
90
  elif $(VENV_BIN)/python -m ruff --version > /dev/null 2>&1; then \
91
  $(VENV_BIN)/python -m ruff check $(PACKAGE)/ tests/; \
92
- elif command -v flake8 > /dev/null 2>&1; then \
93
- flake8 $(PACKAGE)/ tests/ --max-line-length=100 --ignore=E501,W503; \
94
  else \
95
- echo "Aucun linter disponible (installez ruff : pip install ruff)"; \
 
96
  fi
97
 
98
  typecheck: ## Vérification de types avec mypy (si installé)
 
84
  # Qualité du code
85
  # ──────────────────────────────────────────────────────────────────
86
 
87
+ lint: ## Vérifie le style du code (configuration lue depuis pyproject.toml)
88
+ @# La config ruff vit dans [tool.ruff] de pyproject.toml : cette cible,
89
+ @# le job CI et une invocation directe `ruff check` produisent le même
90
+ @# résultat. Lancez avant tout push pour éviter un échec en PR.
91
  @if command -v ruff > /dev/null 2>&1; then \
92
  ruff check $(PACKAGE)/ tests/; \
93
  elif $(VENV_BIN)/python -m ruff --version > /dev/null 2>&1; then \
94
  $(VENV_BIN)/python -m ruff check $(PACKAGE)/ tests/; \
 
 
95
  else \
96
+ echo "ruff non installé installation : pip install ruff"; \
97
+ exit 1; \
98
  fi
99
 
100
  typecheck: ## Vérification de types avec mypy (si installé)
pyproject.toml CHANGED
@@ -94,3 +94,16 @@ picarones = [
94
  [tool.pytest.ini_options]
95
  testpaths = ["tests"]
96
  addopts = "-v --tb=short"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  [tool.pytest.ini_options]
95
  testpaths = ["tests"]
96
  addopts = "-v --tb=short"
97
+
98
+ [tool.ruff]
99
+ # Configuration centralisée pour que `ruff check`, `make lint` et le job CI
100
+ # produisent exactement les mêmes résultats sans flags en ligne de commande.
101
+ line-length = 100
102
+ target-version = "py311"
103
+
104
+ [tool.ruff.lint]
105
+ # E/W = pycodestyle, F = pyflakes. On conserve les mêmes règles que le CI
106
+ # d'origine (avant Sprint 22), qui excluait les lignes longues (E501) et les
107
+ # imports non-top (E402, parfois utiles pour imports conditionnels).
108
+ select = ["E", "W", "F"]
109
+ ignore = ["E501", "E402"]