RFC 0034 — Cleanup du drift rustfmt suite à la migration édition 2021 → 2024
- Auteur : EBO (gitrust)
- Date : 2026-05-18
- Statut : Implemented (2026-10-01) —
cargo fmt --allappliqué sur le workspace. Pas de commit dans ce train (le versioning reste manuel). - Apps consommatrices concernées : gitrust (immédiat — blocage CI sur
cargo fmt --all -- --check), tout futur consommateur qui pose une CI stricte sur le formatage du workspace. - Crate cible :
rustwarden-core,rustwarden-fediverse,rustwarden-fediverse-guard(les 3 crates upstream vendorées dans le workspace gitrust)
Cette RFC vit dans le dépôt gitrust pour tracking. À pousser dans le dépôt upstream du framework (
docs/rfcs/) après revue par l'utilisateur.
Summary
Demander aux mainteneurs des crates rustwarden-* d'exécuter un passage cargo fmt --all sur l'ensemble des fichiers de chaque crate avec le rustfmt courant et l'édition Rust 2024 active. Le code source actuel a été écrit sous l'édition 2021 (ou avec un rustfmt antérieur) et ne passe plus le check fmt strict des consommateurs en édition 2024. Pas de changement d'API, pas de changement sémantique : opération de pure cosmétique pour aligner le baseline avec les versions courantes de rustfmt/édition.
Motivation
Problème concret
Le consommateur gitrust met en place une CI Dagger (docs/plans/dagger-ci-gitrust.md, lot L0/L1) qui invoque cargo fmt --all -- --check sur le workspace. La commande échoue systématiquement avec des diffs uniquement sur les crates upstream, exemple sur crates/rustwarden-fediverse-guard/tests/integration_pipeline.rs:15 :
// État actuel (édition 2021 / rustfmt antérieur) use rustwarden_fediverse_guard::{ default_detectors, BanDecision, BanManager, GuardConfig, GuardObserver, GuardStore, MemoryStore, }; // Ce que rustfmt courant + édition 2024 veulent produire use rustwarden_fediverse_guard::{ BanDecision, BanManager, GuardConfig, GuardObserver, GuardStore, MemoryStore, default_detectors, };
Différences observées dans plusieurs fichiers (résumé non-exhaustif) :
- Tri alphabétique des imports groupés (rule par défaut de l'édition 2024).
- Compactage de chaînes d'appels multi-lignes que rustfmt courant juge inférieures à
max_width=100. - Style des macros (
assert!,panic!) — argument placement sur une ligne quand ça tient.
Qui est impacté aujourd'hui
- gitrust (consommateur principal) : sa CI fmt restera rouge tant que la drift existe dans les crates upstream qu'il vendore mais n'a pas le droit de modifier (cf. règle "Never modify files under
crates/rustwarden-*/" dansCLAUDE.md). - Tout futur consommateur rustwarden-* qui adoptera l'édition 2024 et activera un check fmt strict en CI rencontrera le même blocage.
- Les mainteneurs upstream eux-mêmes lorsqu'ils basculeront leur propre CI sur l'édition 2024 (incontournable à court terme : édition 2021 marquée comme stable mais l'écosystème migre).
Conséquences si on ne fait rien
- Chaque consommateur duplique un workaround local (
cargo fmt --workspace --exclude rustwarden-*), ce qui :- Crée un trou aveugle : la drift upstream n'est jamais détectée côté consommateur, alors qu'elle se propage à chaque rebase.
- Multiplie le mainteance burden de la liste d'exclusion à chaque ajout de crate upstream.
- Empêche tout audit fmt cross-workspace cohérent.
- À terme, lorsque les mainteneurs upstream migreront leur propre CI sur l'édition 2024, ils découvriront la drift par accident et devront résorber des centaines de fichiers d'un coup. Un cleanup planifié maintenant évite cette dette.
Urgence
Non bloquant techniquement (workaround --exclude faisable côté consommateur), mais bloque la finalisation propre du lot L0 de la CI Dagger gitrust. Idéalement livré dans la prochaine patch release rustwarden-* (le changement est non-breaking).
Non-goals
- Pas de changement d'API publique. Aucune signature
pub, aucun trait, aucun module ne bouge. Pur reformatting du source disque. - Pas de bump d'édition. Cette RFC ne demande pas la migration des crates vers l'édition 2024 — uniquement l'alignement du formatage tel que rustfmt courant le veut, quelle que soit l'édition active dans
Cargo.toml. - Pas de changement de
rustfmt.tomlcôté upstream. Le rustfmt.toml de chaque crate reste la source de vérité ; la RFC demande juste un passagecargo fmtcohérent avec ce fichier + version rustfmt stable courante. - Pas de modification des doctests. Les blocs
```rustdans les rustdocs sont laissés tels quels (rustfmt ne les touche pas par défaut, et certains servent d'illustration "non-idiomatique"). - Pas de refactor. Pas de renommage, pas d'extraction de helpers, pas de réorganisation de modules — le diff doit pouvoir être entièrement produit par
cargo fmt --allsans intervention humaine.
Action demandée upstream
Pour chacune des 3 crates concernées (rustwarden-core, rustwarden-fediverse, rustwarden-fediverse-guard) :
# Sur une branche dédiée cd <framework>/crates/rustwarden-core # puis idem pour les deux autres rustup component add rustfmt cargo fmt --all # applique sans --check, génère le diff git diff --stat # vérifier que c'est purement cosmétique cargo test --all # non-régression : aucun test ne bouge git commit -m "chore: cargo fmt --all on edition 2024 baseline"
Pour valider la non-régression :
cargo build --all cargo test --all cargo clippy --all -- -D warnings # doit rester vert
Idéalement consolidé dans un seul commit par crate (un "format-only commit") taggé clairement dans le CHANGELOG pour rendre les futurs git blame lisibles (les outils Git modernes — git blame --ignore-rev — savent sauter ce commit).
Analyse de compatibilité
- API existante non modifiée → non-breaking (patch possible).
- API existante étendue avec défaut → N/A (rien d'étendu).
- API existante modifiée ou supprimée → N/A.
- Nouveau behavior par défaut → N/A (purement cosmétique).
- Changement de schéma DB → N/A.
- Changement de format sérialisé → N/A.
Risque résiduel : un git blame sur les fichiers reformatés perd l'info du dernier auteur fonctionnel. Atténué par l'usage de git blame --ignore-rev <fmt-commit-sha> ou en consignant le SHA du commit fmt dans un fichier .git-blame-ignore-revs versionné (convention GitHub native).
Alternatives considérées
Alternative A (recommandée) : cargo fmt --all upstream, commit unique par crate
Pros :
- Résout le problème à la racine pour tous les consommateurs, présents et futurs.
- Zéro maintenance ensuite : la CI fmt upstream gardera le baseline aligné.
git blame --ignore-revneutralise le coût d'historique.- Effort upstream : ~10 minutes par crate.
Cons :
- Diff initial bruyant (probablement des centaines de lignes touchées).
- Si un autre branch en cours dépend du formatage actuel, conflits de merge ; à coordonner avec les autres mainteneurs.
Alternative B : Chaque consommateur exclut les crates upstream du check fmt
Implémentation côté gitrust :
cargo fmt --workspace --exclude rustwarden-core --exclude rustwarden-fediverse \ --exclude rustwarden-fediverse-guard -- --check
Pros :
- Aucun changement upstream nécessaire.
- Débloque immédiatement la CI consommateur.
Cons :
- Trou aveugle permanent dans la CI consommateur.
- Liste
--excludeà maintenir à chaque ajout de crate upstream. - Si plusieurs consommateurs émergent, chacun duplique l'exclusion (dette × N).
- Ne résout pas le problème quand les mainteneurs upstream migreront eux-mêmes sur édition 2024.
Statut côté gitrust : adoptée temporairement dans le module Dagger en attendant que la RFC 0034 soit livrée upstream (cf. lot L0 du plan CI). Le cargo fmt du module est explicitement scopé aux crates gitrust-*.
Alternative C : Ajouter ignore = ["crates/rustwarden-*"] dans le rustfmt.toml du workspace gitrust
Pros :
- Local au consommateur, n'impose rien upstream.
Cons :
- L'option
ignorede rustfmt est unstable sur le canal stable (silencieusement ignorée). Nécessite nightly ou bricolage de wrapper. - Cache la drift au lieu de la résoudre.
- Inutilisable comme stratégie générique.
Verdict : non retenue.
Alternative D (ne rien faire / garder la drift) : laisser le job fmt CI rouge
Pros : zéro coût, zéro risque immédiat.
Cons :
- Always-red rend le signal du job inutile : on s'habitue au rouge et on rate les vraies dérives de code gitrust.
- Casse la promesse "parité dev/CI" — les consommateurs développeurs locaux n'ont plus d'incentive à
cargo fmtavant push si la CI est rouge de toute façon. - Dette accumulée qui sera coûteuse à résorber plus tard.
Verdict : non retenue.
Testing plan
Tests obligatoires côté upstream après application du cargo fmt --all :
cargo build --all→ compile sans warning.cargo test --all→ 100 % des tests existants passent (aucun test ne dépend du formatage source).cargo clippy --all -- -D warnings→ reste vert.cargo fmt --all -- --check→ exit 0 (preuve que la drift est résolue).cargo doc --workspace --no-depsavecRUSTDOCFLAGS="-D warnings"→ reste vert (rustdoc ne dépend pas du formatage).
Non-régression côté consommateur (gitrust) :
- Rebase le repo gitrust sur la version upstream contenant le commit fmt.
- Lancer
dagger call fmt --src=.(avec la fonction Dagger restaurée àcargo fmt --all -- --checkglobal, sans--exclude). - Doit retourner exit 0.
Migration guide
Aucune migration côté API. À copier dans le CHANGELOG upstream au moment du merge :
### Internal - `chore: cargo fmt --all` baseline aligned with stable rustfmt + Rust edition 2024. No API change, no behavioral change. Commit SHAs added to `.git-blame-ignore-revs` for `git blame` continuity.
Côté gitrust, retirer le workaround --exclude dans .dagger/src/gitrust_ci/main.py (lot L0) une fois la version upstream contenant ce cleanup intégrée au workspace.
Open questions
-
Le mainteneur upstream préfère-t-il un commit fmt cross-crate ou un commit fmt par crate ? Influence la lisibilité de
.git-blame-ignore-revs. -
Faut-il bump rustfmt à la version exacte du
rust-toolchain.tomldu repo upstream avant l'application, pour garantir la reproductibilité du diff ? -
Une CI nightly upstream qui ferait tourner
cargo fmt --all -- --checkest-elle envisageable pour empêcher le drift de revenir ? Si oui, c'est l'objet d'une RFC suivante (out of scope ici).
Tracking issue
À créer sur le repo framework après revue gitrust : label rfc + label chore + corps = Summary + lien vers ce fichier.
Évaluation
| Critère | Note | Justification |
|---|---|---|
| Généralité | 4 / 5 | Sert immédiatement gitrust, anticipe tout futur consommateur en édition 2024 + CI fmt stricte. |
| Stabilité API | 5 / 5 | Zéro changement d'API publique. Purement cosmétique. |
| Performance | 3 / 5 | Neutre : aucun impact runtime, aucun impact compile time mesurable. |
| Sécurité | 3 / 5 | Neutre vs l'existant. Pas de hardening, pas de régression possible. |
| Complexité impl | 5 / 5 | < 5 lignes : cargo fmt --all. Trivial. |
| Charge maintenance | 5 / 5 | One-shot. Aucune dette ajoutée si l'upstream pose un check fmt nightly (optionnel). |
| Documentation | 4 / 5 | Entry CHANGELOG explicite + .git-blame-ignore-revs documenté. Pas de rustdoc à ajouter (rien de neuf). |
Total : 29 / 35 → passage en Accepted recommandé sans second avis (seuil > 25 atteint, >= 30 sans atteindre le fast-track).
GitRust