git log --oneline shows only the subject, and it read in whichever language the author was thinking in. The subject and the body under it are now in English, then --- FR --- opens the French section, which starts with the subject translated under the same tag. The hook refuses a --- EN --- marker and a French section without that title, and checks the title like a subject; it does not count against the body budget. Whether the subject is really English is not checked. /commit and /git_prepare_merge follow. Checked: 55 hook tests, 7 of them new; i18n tests pass. --- FR --- [UPD] règle de commit : sujet anglais d'abord, titre FR sous --- FR --- git log --oneline ne montre que le sujet, et il se lisait dans la langue où l'auteur pensait. Le sujet et le corps qui le suit sont désormais en anglais, puis --- FR --- ouvre la section française, qui commence par le sujet traduit sous le même tag. Le hook refuse un marqueur --- EN --- et une section française sans ce titre, et juge ce titre comme un sujet ; il ne compte pas dans le budget du corps. Que le sujet soit vraiment en anglais ne se vérifie pas. /commit et /git_prepare_merge suivent. Vérifié : 55 tests du hook, dont 7 nouveaux ; tests i18n au vert. Assisted-by: Claude Opus 5.5
165 lines
8.7 KiB
Markdown
165 lines
8.7 KiB
Markdown
# Conventions de code
|
||
|
||
Le formatage et le lint sont entièrement décrits par les fichiers de
|
||
configuration du dépôt — les lire plutôt que de supposer : `.flake8`,
|
||
`.editorconfig`, et les sections `[tool.black]` / `[tool.isort]` de
|
||
`pyproject.toml`. `make format` applique l'ensemble.
|
||
|
||
Prettier (via npm) formate XML/JSON/YAML ; `.editorconfig` donne les
|
||
indentations par type de fichier.
|
||
|
||
## Commentaires
|
||
|
||
Un commentaire dit COMMENT le code fonctionne : ce que la fonction prend, ce
|
||
qu'elle rend, l'invariant qu'elle tient, ses effets de bord, la contrainte
|
||
technique qu'on ne devine pas en lisant la ligne d'à côté. Il doit se lire
|
||
dans dix ans sans rien savoir de la semaine où il a été écrit. La règle vaut
|
||
pour les docstrings autant que pour les lignes `#`.
|
||
|
||
**L'épreuve : le sujet et le temps.** Chaque phrase a le CODE pour sujet, au
|
||
présent de ce qu'il fait. Une phrase dont le sujet est un incident, une
|
||
machine, une date ou une personne est à couper, où qu'elle se trouve dans le
|
||
paragraphe. Le MODE DE DÉFAILLANCE que le code empêche est du fonctionnement
|
||
et reste — « une VM renommée se voit attribuer la passerelle ». L'INCIDENT où
|
||
on l'a observé est du récit et part — « vécu sur telle VM, annoncée à telle
|
||
adresse ».
|
||
|
||
**Les chiffres.** Une mesure qui établit un fait durable reste, dépouillée de
|
||
sa date, de son lieu et de son opérateur : une limite, un seuil, une valeur
|
||
que documente l'éditeur. Un relevé de ce qui répondait ce jour-là part.
|
||
|
||
**Rien d'identifiant, jamais** : nom d'un client ou d'une organisation tierce,
|
||
nom de base de données réelle, nom de VM ou d'hôte, adresse IP, courriel,
|
||
chemin portant un nom d'utilisateur, libellé ou chiffre tiré des données d'un
|
||
client. La seule exception est l'en-tête de copyright : le dépôt nomme son
|
||
propriétaire, pas ses clients. Généraliser plutôt que censurer — « sur une
|
||
base de production », « sur un hôte qui exige une authentification sudo
|
||
interactive » — dit la CLASSE de situation, qui est ce qui sert au lecteur.
|
||
|
||
**L'exemple qui illustre un interdit s'invente.** La règle a d'abord été
|
||
violée par ses propres tests : pour démontrer qu'une adresse et un chemin de
|
||
compte sont refusés, ils en portaient de vrais, pris dans le parc. Choisir un
|
||
cas réel « parce qu'il est parlant » est exactement le réflexe que la règle
|
||
combat, et un test le fige pour toujours. Une valeur inventée démontre aussi
|
||
bien ; vérifier qu'elle n'existe nulle part ailleurs dans le dépôt.
|
||
|
||
Le récit n'est pas perdu, il change de place : l'enquête, les mesures datées
|
||
et les impasses vivent dans `tasks/`, qui n'est pas versionné. Ni le fichier
|
||
ni le corps du commit ne les portent.
|
||
|
||
Cela vaut aussi pour l'existant, mais **au fur et à mesure** : on corrige les
|
||
commentaires du fichier qu'on touche, au moment où on le touche, et non en une
|
||
passe qui réécrirait le dépôt. Le hook `pre-commit` liste ce qui est à relire
|
||
dans les fichiers indexés, sans jamais bloquer le commit ; le même outil se
|
||
lance à la main :
|
||
|
||
```bash
|
||
python3 script/analyse/check_comment_hygiene.py script/todo/todo.py
|
||
python3 script/analyse/check_comment_hygiene.py --staged
|
||
```
|
||
|
||
🔴 `identifiant` est une trouvaille, à retirer. 🟡 `récit` est un signal à
|
||
relire : l'outil ne sait pas si la phrase énonce un fait durable ou raconte
|
||
une journée, et ne tranche pas à votre place. 🟡 `nom` en est un autre, et sa
|
||
limite est plus dure : un nom d'hôte NU ne se distingue mécaniquement ni d'un
|
||
mot ordinaire ni du nom d'un logiciel, donc l'outil ne voit que la forme
|
||
pleinement qualifiée. Un miroir de paquets nommé dans un commentaire y
|
||
répond, et se confirme d'un coup d'œil ; l'absence de signal ne prouve rien
|
||
sur les noms.
|
||
|
||
Trois exemples pris dans ce dépôt, leurs noms propres masqués — une règle qui
|
||
interdit de nommer ne se cite pas elle-même en clair.
|
||
|
||
`qemu_manage.py` — la dernière phrase, « Vécu sur « <VM> », annoncée en
|
||
<adresse> au lieu de <adresse> », part en entier. Les deux qui la précèdent
|
||
disent déjà tout, une fois l'imparfait du récit passé au présent : « une VM
|
||
renommée, dont le bail porte encore l'ancien nom d'hôte, SE VOIT attribuer la
|
||
passerelle ».
|
||
|
||
`todo.py` — « recopier « <base_client>_neutralize_upgrade_18 » oblige à
|
||
regarder ce qu'on détruit » devient « recopier un nom long oblige à regarder
|
||
ce qu'on détruit, là où « o » se tape par réflexe ». L'exemple ne servait qu'à
|
||
illustrer « long ».
|
||
|
||
`qemu_install.py` — le relevé daté des miroirs, qui répondait et qui non tel
|
||
jour, part : c'est l'état d'une journée. « Aucun miroir ne réplique tout,
|
||
d'où plusieurs entrées plutôt qu'une » reste : c'est la raison d'être de la
|
||
liste, et elle est vraie demain.
|
||
|
||
## Git
|
||
- Branches : `develop` (développement), `master` (production)
|
||
- Pas de submodules Git — utilise **Google Repo** pour les addons
|
||
- Manifests XML dans `manifest/` pour chaque version Odoo
|
||
- Format de commit : `[TYPE] scope: subject`, sujet **en anglais**, à
|
||
l'impératif, 72 caractères au plus. Tags réellement utilisés : `[UPD]`,
|
||
`[FIX]`, `[ADD]`, `[IMP]`, `[REF]`.
|
||
- **Nommer les fichiers à l'indexation, jamais `git add -A`** : `private/` et
|
||
`tasks/` ne sont pas suivis EXPRÈS, et un ratissage les commit. Il emporte
|
||
aussi ce qui est en cours ailleurs dans le checkout, sous un sujet qui ne le
|
||
couvre pas. `git add -p` quand un fichier porte deux sujets.
|
||
|
||
### Le sujet
|
||
|
||
Le sujet est lu cent fois pour une fois que le corps l'est — `git log
|
||
--oneline`, un blame, une note de version, un bisect. Il a une seule tâche :
|
||
dire **sur quoi porte le code**.
|
||
|
||
L'épreuve : le lire seul, sans diff ni corps. Sait-on quelle partie du système
|
||
est en jeu, et ce qui y est désormais différent ? Sinon il n'est pas fini.
|
||
|
||
Nommer la chose, puis ce qui change pour elle. Le symptôme, le message d'erreur
|
||
cité et la métaphore sont des PREUVES, et une preuve va dans le corps — un
|
||
sujet bâti sur elles se lit bien et n'apprend rien. La portée dit OÙ, les mots
|
||
après le deux-points doivent dire QUOI.
|
||
|
||
Le sujet résume le commit ENTIER, pas sa plus grosse pièce. S'il lui faut un
|
||
« et » entre deux choses sans rapport, c'étaient deux commits.
|
||
|
||
Si le travail n'entre décidément pas dans une phrase de 72 caractères, ne pas
|
||
en écrire une amputée : des **mots-clés qui résument**, séparés par des
|
||
virgules, en disent plus dans la même place — `[FIX] proxmox: pmxcfs down,
|
||
pvesm silent, diagnosis at the source`. C'est un repli, pas un défaut : la
|
||
phrase reste préférable quand elle tient.
|
||
|
||
Un garde-fou refuse le mécanique. Sur le sujet : tag absent, plus de 72
|
||
caractères, ouverture sur une citation. Sur le corps : plus de 10 lignes pour
|
||
une langue, une adresse IP, un courriel, un chemin de compte. Sur l'ordre des
|
||
langues : un marqueur `--- EN ---`, une section française qui ne s'ouvre pas
|
||
sur le sujet traduit sous le même tag. Que le sujet soit bien en anglais
|
||
reste à l'auteur. Ce qui reste un jugement — « ce corps raconte-t-il
|
||
l'enquête » — n'est vérifié par personne.
|
||
|
||
```bash
|
||
git config core.hooksPath script/git/hooks # une fois par clone
|
||
git commit --no-verify # exception légitime
|
||
```
|
||
|
||
Le mode d'emploi complet, avec des exemples avant/après pris dans l'historique
|
||
de ce dépôt, est dans `conf/template_claude_commands_commit.md`.
|
||
|
||
### Tout commit assisté par IA
|
||
|
||
Trois exigences, sans exception — `AI_POLICY.md` en donne la raison :
|
||
|
||
- Trailer `Assisted-by: <modèle>`, une ligne par modèle. C'est **binaire** :
|
||
il y a eu IA ou non, aucun seuil à apprécier.
|
||
- **Jamais** d'IA dans `Co-authored-by:` — ce champ est réservé aux humains.
|
||
- Message **bilingue, l'anglais d'abord** : le sujet et le corps en anglais,
|
||
puis `--- FR ---`, puis le sujet traduit en français sous le même tag, puis
|
||
le corps traduit. `--- EN ---` n'existe plus : l'ordre ne varie jamais.
|
||
|
||
Court et direct : **8 lignes par langue**, 10 est un plafond. Le corps dit
|
||
pourquoi c'était nécessaire, puis s'arrête. Rien de ce que le diff montre
|
||
déjà ; on garde le mode de défaillance, le chiffre qui borne et la
|
||
vérification. Le bilinguisme achète la concision, il ne l'excuse pas.
|
||
|
||
Le corps obéit aux mêmes deux règles que les commentaires : **rien
|
||
d'identifiant**, et **le fonctionnement plutôt que l'enquête**. Le corps dit
|
||
ce que le code fait ou refuse DÉSORMAIS ; il ne raconte ni la séance, ni les
|
||
hypothèses écartées, ni qui s'est trompé. Une mesure se généralise à sa classe
|
||
de situation — « sur une base de production », jamais son nom.
|
||
|
||
Le mode d'emploi complet — résolution dynamique du modèle, gabarit, identité
|
||
git, taille des correctifs — est dans
|
||
`conf/template_claude_commands_commit.md`, déployable en `/commit` par
|
||
`TODO › Execute › GPT code › Claude configs`.
|