tools: un garde-fou à l'écriture pour le piège d'insertion doxygen
Le même geste — un bloc glissé entre un commentaire et sa déclaration, si bien que la voisine hérite de \param qu'elle n'a pas — a été commis quatre fois en une semaine, à attention soutenue, et rattrapé quatre fois par le même contrôle. Un outil qui attrape quatre fois la même erreur chez quelqu'un d'attentif ne signale pas un défaut d'attention : il signale que le geste est piégeux. Le contrôle rattrape après coup ; celui-ci agit à l'écriture. inserer-doc.py localise la déclaration, REMONTE au-dessus du bloc de documentation qui lui est déjà attaché, et insère là — le bloc existant reste collé à sa propre déclaration. Éprouvé sur le cas réel : il a détecté la doc de qualifierRefus, prévenu qu'il insérait au-dessus d'elle, et l'a laissée attachée. L'erreur devient inexprimable au lieu d'être rattrapée. La règle générale est dans AGENTS.md : compter les récidives d'un même contrôle. Une fois est une inattention, quatre fois est une conception à revoir — et la question n'est plus « comment mieux faire attention ? » mais « comment rendre l'erreur impossible à commettre ? ». Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
parent
a0e75da0ac
commit
fc844ab5d1
75
tools/inserer-doc.py
Executable file
75
tools/inserer-doc.py
Executable file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python3
|
||||
r"""Insère un bloc Doxygen DEVANT une déclaration, sans voler la doc de sa voisine.
|
||||
|
||||
POURQUOI CET OUTIL EXISTE
|
||||
-------------------------
|
||||
La même erreur a été commise QUATRE FOIS en une semaine, par attention soutenue, et rattrapée
|
||||
quatre fois par `ci-quality` :
|
||||
|
||||
/*! doc de A */ ← on insère ici, croyant précéder B…
|
||||
void A(); …et le bloc de A se retrouve accolé à B,
|
||||
void B(); qui hérite de `\param` qu'il n'a pas.
|
||||
|
||||
Un outil qui attrape quatre fois la même erreur chez quelqu'un d'attentif ne signale pas un
|
||||
défaut d'attention : il signale que **le geste lui-même est piégeux**. Le contrôle rattrape
|
||||
après coup ; ce garde-fou-ci agit à l'écriture.
|
||||
|
||||
CE QU'IL FAIT
|
||||
-------------
|
||||
Il localise la déclaration, REMONTE au-dessus de son éventuel bloc `/*! … */` ou de ses lignes
|
||||
`//!`, et insère là. Le bloc existant reste donc collé à sa propre déclaration.
|
||||
|
||||
python3 tools/inserer-doc.py <fichier> <ancre> <fichier-du-bloc>
|
||||
|
||||
`<ancre>` est une sous-chaîne unique de la ligne de déclaration visée.
|
||||
"""
|
||||
import re, sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def debut_du_bloc_doc(lignes, i):
|
||||
"""Remonte au-dessus du bloc de documentation attaché à la ligne i, s'il existe."""
|
||||
j = i - 1
|
||||
# lignes `//!` empilées
|
||||
while j >= 0 and lignes[j].lstrip().startswith('//!'):
|
||||
j -= 1
|
||||
if j >= 0 and lignes[j].rstrip().endswith('*/'):
|
||||
# remonter jusqu'à l'ouverture du bloc
|
||||
k = j
|
||||
while k >= 0 and '/*!' not in lignes[k] and '/**' not in lignes[k]:
|
||||
k -= 1
|
||||
if k >= 0:
|
||||
return k
|
||||
return j + 1
|
||||
|
||||
|
||||
def principal():
|
||||
if len(sys.argv) != 4:
|
||||
print(__doc__)
|
||||
return 2
|
||||
fichier, ancre, bloc_f = Path(sys.argv[1]), sys.argv[2], Path(sys.argv[3])
|
||||
lignes = fichier.read_text(encoding='utf-8').split('\n')
|
||||
|
||||
cibles = [i for i, l in enumerate(lignes) if ancre in l]
|
||||
if len(cibles) != 1:
|
||||
print("✗ l'ancre doit désigner UNE ligne, trouvée %d fois" % len(cibles))
|
||||
for i in cibles[:5]:
|
||||
print(" %s:%d %s" % (fichier, i + 1, lignes[i].strip()[:76]))
|
||||
return 1
|
||||
|
||||
i = cibles[0]
|
||||
pos = debut_du_bloc_doc(lignes, i)
|
||||
if pos != i:
|
||||
print(" note : une documentation existe déjà en %s:%d — insertion AU-DESSUS d'elle,"
|
||||
% (fichier, pos + 1))
|
||||
print(" pour qu'elle reste attachée à sa propre déclaration.")
|
||||
|
||||
bloc = bloc_f.read_text(encoding='utf-8').rstrip('\n').split('\n')
|
||||
lignes[pos:pos] = bloc
|
||||
fichier.write_text('\n'.join(lignes), encoding='utf-8')
|
||||
print("✓ bloc inséré en %s:%d (%d lignes)" % (fichier, pos + 1, len(bloc)))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(principal())
|
||||
Loading…
x
Reference in New Issue
Block a user