302 lines
26 KiB
Markdown
302 lines
26 KiB
Markdown
<!-- file: docs/rules/510-RUST_CARGO.md -->
|
|
<!-- version: 7 -->
|
|
|
|
# Profil Rust / Cargo
|
|
|
|
## Scope
|
|
|
|
Ce profil s'applique aux projets qui utilisent Rust avec Cargo.
|
|
|
|
Il spécialise [`500-LANGUAGES.md`](500-LANGUAGES.md) pour les responsabilités propres à Rust et Cargo. Il ne possède pas les contraintes particulières d'une plateforme, d'un framework, d'une FFI, d'un protocole ou d'un domaine métier.
|
|
|
|
Une règle plus spécifique, par exemple Android, WASM, Tauri ou une frontière FFI, MAY raffiner ce profil dans son scope sans modifier la politique Rust générale.
|
|
|
|
Pour un **nouveau projet contrôlé** par l'organisation, PGR sélectionne par défaut le profil strict décrit ci-dessous : provenance des symboles visible, façade crate-root explicite, contrôle de flux explicite et noms de crates lisibles. Un projet existant ou imposé par un tiers MAY conserver des contraintes différentes via des règles project-specific ou des exceptions bornées ; cette adaptation ne rend pas le profil strict moins canonique pour les nouvelles baselines contrôlées.
|
|
|
|
## Toolchain et édition
|
|
|
|
Un nouveau projet Rust contrôlé MUST utiliser l'édition Rust 2024 avec une toolchain stable compatible avec ses dépendances et ses cibles, sauf contrainte externe explicitement documentée. Une toolchain nightly, beta ou autre prerelease nécessite une justification explicite.
|
|
|
|
`2024` est la baseline normative actuelle des projets contrôlés ; PGR ne bascule pas automatiquement vers une future édition au seul motif qu'elle existe. Une évolution de cette baseline demande une décision PGR explicite et une validation de compatibilité.
|
|
|
|
PGR MUST NOT imposer un pin exact de toolchain uniquement parce qu'un projet source historique utilisait cette version. Un fichier `rust-toolchain.toml` ou équivalent SHOULD être ajouté uniquement lorsqu'un besoin réel de reproductibilité, de composant ou de compatibilité l'exige.
|
|
|
|
Lorsqu'un workspace partage une politique d'édition unique, l'édition Rust SHOULD être déclarée une seule fois sous `[workspace.package]` et héritée par les membres. Une évolution d'édition est une décision de compatibilité/toolchain et non une modification opportuniste.
|
|
|
|
## Workspace et unités de release
|
|
|
|
Un projet Rust composé de plusieurs packages SHOULD utiliser un workspace Cargo lorsque les packages partagent réellement gouvernance, validation ou dépendances.
|
|
|
|
Pour un workspace à train de release unique :
|
|
|
|
- le fichier PGR `VERSION` reste la version canonique de l'unité de release ;
|
|
- `[workspace.package].version` MUST refléter cette version lorsque Cargo exige une version de package ;
|
|
- les crates membres SHOULD hériter de la version workspace plutôt que recopier la même valeur ;
|
|
- les métadonnées réellement communes comme `edition`, `license`, `repository` ou `authors` SHOULD être centralisées puis héritées lorsqu'elles ont le même propriétaire.
|
|
|
|
Un monorepo contenant plusieurs unités de release indépendantes MUST NOT fabriquer une fausse version Cargo globale uniquement pour appliquer ce modèle. Chaque unité conserve alors son propriétaire de version conformément aux règles générales PGR.
|
|
|
|
Le répertoire `crates/` est le placement PGR recommandé pour les packages Rust d'un workspace structuré, sauf layout imposé par un framework, une plateforme ou un projet existant.
|
|
|
|
|
|
### Nomenclature des crates dans un projet contrôlé
|
|
|
|
Une crate appartenant à un projet contrôlé MUST commencer par le nom court canonique du projet ou une abréviation documentée et stable. Le reste du nom SHOULD rendre immédiatement lisibles sa responsabilité principale puis, lorsqu'il apporte une information réelle, son rôle ou sa cible.
|
|
|
|
La forme recommandée est :
|
|
|
|
```text
|
|
<project>-<responsibility>-<role-or-target>
|
|
```
|
|
|
|
Exemples de classificateurs utiles selon le projet :
|
|
|
|
```text
|
|
lib
|
|
api
|
|
worker
|
|
job
|
|
cli
|
|
desk
|
|
desktop
|
|
tauri
|
|
wasm
|
|
server
|
|
```
|
|
|
|
Cette liste n'est ni exhaustive ni un vocabulaire imposé. Un suffixe ou classificateur ne doit pas être ajouté par symétrie : `api` suppose un vrai contrat/extensibility boundary, `worker` un service continu identifiable, `cli` une interface ligne de commande, etc. À l'inverse, un rôle important ne doit pas être masqué dans un nom générique comme `common`, `core` ou `utils` sans responsabilité suffisamment précise.
|
|
|
|
Un projet historique MAY conserver un ordre local déjà stable, par exemple un rôle placé avant la responsabilité, si sa nomenclature est documentée et cohérente. PGR n'impose aucune campagne de renommage rétroactive uniquement pour adopter la grammaire recommandée.
|
|
|
|
### Les suffixes portent un contrat architectural
|
|
|
|
Dans un projet contrôlé, les classificateurs de nom ne sont pas décoratifs. Lorsqu'ils sont utilisés, ils décrivent une responsabilité que l'architecture et le graphe de dépendances doivent respecter.
|
|
|
|
Une crate terminée par `-api` porte principalement des contrats réutilisables : traits, types, DTOs, identifiants et primitives nécessaires à des implémentations séparées. Elle SHOULD rester passive et sans runtime. Une crate `-api` purement déclarative MUST NOT dépendre d'une crate de logging/tracing uniquement pour satisfaire une convention transversale. Une instrumentation n'y est ajoutée que si la crate possède un comportement réel à observer.
|
|
|
|
Une crate `-api` MUST NOT être créée uniquement pour obtenir une paire de noms symétrique. Elle est justifiée lorsqu'au moins une frontière réelle existe : implémentations multiples ou remplaçables, implémentation externe, backend injectable, lifecycle partagé ou contrat public dont l'implémentation doit pouvoir vivre dans une autre crate. Lorsqu'une seule implémentation est réellement prévue et qu'aucune frontière de contrat séparée n'apporte de valeur, une seule crate `-lib` est préférée.
|
|
|
|
Une crate terminée par `-lib` porte une implémentation ou fonctionnalité réutilisable. Par défaut, elle est une crate bibliothèque sans cible binaire. Des familles comme `worker`, `job`, `store`, `transport` ou `scenario` MAY apparaître dans la responsabilité avant le suffixe `-lib` lorsqu'elles décrivent ce que la bibliothèque implémente ; le suffixe terminal `-lib` continue alors d'indiquer qu'il s'agit d'une unité réutilisable et non d'un launcher.
|
|
|
|
### Séparation bibliothèques / exécutables
|
|
|
|
Hors exception de framework ou plateforme explicitement documentée, un package contrôlé MUST NOT combiner une bibliothèque réutilisable et une cible binaire uniquement par commodité. La logique réutilisable appartient à une ou plusieurs crates `-lib`; l'exécutable appartient à un package distinct qui les consomme.
|
|
|
|
Le nom d'un package exécutable SHOULD rendre visible son rôle de processus ou d'interface, par exemple `-cli`, `-desk`, `-worker`, `-job` ou `-server` lorsque ces termes décrivent réellement le launcher. Le binaire SHOULD rester une couche de composition mince : initialisation du processus, verrou/single-instance lorsque nécessaire, arguments CLI, wiring des bibliothèques, lifecycle et arrêt. La logique métier ou technique réutilisable ne doit pas être dupliquée dans `main.rs`.
|
|
|
|
Tauri constitue l'exception framework actuellement reconnue par PGR à cette séparation par défaut : son profil peut demander un package mixte bibliothèque + binaire pour servir simultanément les entrées desktop/mobile. Cette exception est possédée par [`710-TAURI.md`](710-TAURI.md) et ne justifie pas de généraliser les packages mixtes aux workers, jobs ou autres exécutables. Toute autre exception mixte demande une règle locale et une raison technique identifiable.
|
|
|
|
## Diagnostics structurés et ownership du logging
|
|
|
|
Pour les nouveaux projets Rust contrôlés, `tracing` est le mécanisme recommandé de diagnostics structurés. La façade `log` MAY être conservée comme bridge de compatibilité lorsqu'une dépendance l'impose, mais elle SHOULD NOT devenir le mécanisme principal d'un nouveau projet lorsqu'aucune contrainte externe ne le requiert.
|
|
|
|
Lorsqu'un workspace possède plusieurs crates runtime partageant les mêmes règles de diagnostics, il SHOULD centraliser la configuration de logging/tracing dans une crate transverse dédiée, typiquement `<project>-logging-lib` ou un nom équivalent conforme à la nomenclature locale. Dès que plusieurs exécutables ou bibliothèques ont besoin du même subscriber, des mêmes filtres/sinks ou du même lifecycle de guard, cet owner commun SHOULD remplacer les initialisations dupliquées. Un petit projet à exécutable unique n'est pas obligé de créer une crate dédiée sans valeur de réutilisation.
|
|
|
|
Cette crate commune possède normalement la composition de `tracing-subscriber`, l'usage de `tracing-appender` lorsque nécessaire, les filtres/sinks/formats partagés et le lifecycle d'initialisation. Une bibliothèque métier ou technique MAY émettre des événements structurés, mais SHOULD NOT installer silencieusement un subscriber global. Les crates `-api` purement déclaratives restent normalement sans dépendance de logging.
|
|
|
|
## Manifests et dépendances Cargo
|
|
|
|
Dans un workspace, une dépendance tierce réellement partagée par plusieurs crates SHOULD posséder sa contrainte de version canonique sous `[workspace.dependencies]`.
|
|
|
|
Une crate membre SHOULD consommer cette dépendance avec `workspace = true` et activer localement uniquement les features nécessaires à son propre code. Une feature de plateforme ou de test MUST NOT être activée globalement par commodité lorsqu'un scope plus étroit suffit.
|
|
|
|
Une dépendance utilisée uniquement par les tests, benchmarks ou exemples SHOULD rester dans la section de dépendances de développement appropriée.
|
|
|
|
Les contraintes de version SHOULD exprimer l'intention de compatibilité réellement souhaitée. Un pin exact ou une version volontairement ancienne MUST avoir une raison identifiable : compatibilité, reproductibilité, sécurité, bug connu ou matrice imposée par un scope plus spécifique.
|
|
|
|
`cargo update` MUST NOT être exécuté opportunistement dans une tranche sans rapport avec les dépendances. Une mise à jour de résolution ou de dépendance appartient au scope courant uniquement lorsqu'elle est nécessaire et explicitement vérifiée.
|
|
|
|
## Politique de `Cargo.lock`
|
|
|
|
PGR ne généralise pas automatiquement la politique de lockfile d'un projet source à tous les projets Rust.
|
|
|
|
La décision de versionner ou non `Cargo.lock` MUST être explicite et cohérente avec le type de produit, le mode de publication et le besoin de reproductibilité du projet. Un profil plus spécifique MAY imposer une politique particulière.
|
|
|
|
Dans tous les cas, un lockfile ne remplace jamais les contraintes de version et décisions de compatibilité appartenant aux manifests et à la documentation normative.
|
|
|
|
## Lints communs
|
|
|
|
Un workspace structuré SHOULD déclarer les lints communs au niveau racine et les crates membres SHOULD les hériter plutôt que maintenir plusieurs copies divergentes.
|
|
|
|
Le profil strict PGR recommandé pour un nouveau workspace Rust comprend au minimum :
|
|
|
|
```toml
|
|
[workspace.lints.rust]
|
|
missing_docs = "warn"
|
|
unreachable_pub = "deny"
|
|
unsafe_code = "forbid"
|
|
|
|
[workspace.lints.clippy]
|
|
unwrap_used = "deny"
|
|
expect_used = "deny"
|
|
implicit_return = "deny"
|
|
question_mark = "deny"
|
|
question_mark_used = "deny"
|
|
```
|
|
|
|
Des `allow` nécessaires pour éviter qu'un lint de suggestion contredise intentionnellement le style retenu MAY être déclarés au workspace, mais la liste doit rester minimale et justifiée par une règle réelle.
|
|
|
|
## Safety et FFI
|
|
|
|
Le code `unsafe` est interdit par défaut dans un projet suivant le profil strict PGR.
|
|
|
|
Lorsqu'une FFI ou une plateforme impose réellement une opération `unsafe`, l'exception MUST appartenir au scope le plus étroit possible : crate, module, symbole ou attribut concerné. Elle MUST être documentée et ne doit pas affaiblir silencieusement le reste du workspace.
|
|
|
|
Une exception FFI locale n'autorise donc pas à remplacer globalement `unsafe_code = "forbid"` par une politique permissive pour toutes les crates.
|
|
|
|
## API, visibilité, imports et chemins
|
|
|
|
Dans le profil strict d'un projet contrôlé, tout élément `pub` ou `pub(crate)` MUST posséder une rustdoc utile au point de déclaration. Toute réexportation `pub use` ou `pub(crate) use` visible au crate-root MUST également porter une rustdoc adjacente utile. Une rustdoc qui répète seulement le nom du symbole ne satisfait pas ce contrat.
|
|
|
|
Les modules d'implémentation restent privés. `pub mod` MUST NOT être utilisé pour exposer paresseusement une arborescence interne ; `pub(super)` et `pub(in ...)` MUST NOT remplacer une façade crate-root explicite dans une baseline contrôlée.
|
|
|
|
Un élément `pub` d'un module fichier MUST être réexporté explicitement au crate-root. Un élément `pub(crate)` consommé hors de son module MUST de même posséder un réexport `pub(crate)` au crate-root. Un helper réellement local SHOULD rester privé plutôt qu'élargir artificiellement sa visibilité.
|
|
|
|
Les réexports d'éléments internes commencent par `self::` :
|
|
|
|
```rust
|
|
pub use self::foo::Foo;
|
|
pub(crate) use self::bar::InternalBar;
|
|
```
|
|
|
|
Un réexport de crate externe utilise son chemin public canonique. Les réexports groupés par accolades, les glob imports et les alias `as` servant à raccourcir ou masquer un nom MUST NOT être utilisés. Une collision durable se résout en donnant au symbole son nom canonique dans son module propriétaire.
|
|
|
|
### `use` réservé aux traits
|
|
|
|
Dans le profil strict, `use` MUST NOT importer une constante, fonction, structure, énumération, union, alias de type, module ou macro uniquement pour raccourcir son chemin. Les déclarations `use` sont réservées aux traits lorsqu'une résolution de méthode ou une contrainte du langage exige réellement leur mise en scope.
|
|
|
|
Un import de trait reste au niveau du module et ne mélange pas de symboles non-traits. Un projet MAY ajouter un marqueur de commentaire spécifique à son audit local, mais PGR n'impose pas un commentaire tel que `rust-rules: trait-import` : ce marqueur est un mécanisme d'enforcement, pas la règle sémantique elle-même.
|
|
|
|
Pour un élément fourni par une crate externe, le code utilise directement le **chemin public le plus court** exposé par cette crate, par exemple :
|
|
|
|
```rust
|
|
std::path::Path
|
|
serde_json::Value
|
|
other_crate::Item
|
|
```
|
|
|
|
et non un `use` non-trait destiné à raccourcir ce chemin. Un chemin interne plus long n'est pas préféré lorsque la crate externe expose déjà une façade publique plus courte.
|
|
|
|
### Façade crate-root et références intra-crate
|
|
|
|
Dès qu'un item partagé possède une identité crate-root, toute référence dans la même crate MUST utiliser `crate::Item`, y compris depuis son module de déclaration et depuis ses tests unitaires attachés. Les formes `Item`, `self::Item`, `super::Item`, `module::Item` et `crate::module::Item` ne sont pas des chemins de consommation canoniques pour cet item partagé.
|
|
|
|
Un élément strictement privé reste local au module et n'est pas réexporté. Dans un fichier de tests unitaires rattaché au module parent, un élément privé du parent peut être référencé via `super::PrivateItem`; un élément `pub` ou `pub(crate)` partagé continue d'être référencé via `crate::Item`.
|
|
|
|
Les autres crates consomment l'API publique du crate propriétaire via `owner_crate::Item`, jamais via ses modules internes. La visibilité d'un item MUST NOT être élargie uniquement pour permettre son test.
|
|
|
|
Ces conventions sont plus strictes que le Rust idiomatique minimal, mais elles sont retenues pour les projets contrôlés afin de rendre immédiatement visibles l'ownership et la provenance des symboles. Un projet externe contraint peut définir un override explicite ; l'exception ne devient pas la nouvelle règle PGR.
|
|
|
|
## Contrôle de flux et erreurs
|
|
|
|
Dans le code de production du profil strict PGR :
|
|
|
|
- `unwrap()` et `expect()` MUST NOT être utilisés ;
|
|
- `panic!` MUST NOT représenter une erreur métier récupérable ;
|
|
- les retours explicites sont obligatoires lorsque la fonction possède une valeur de retour ;
|
|
- l'opérateur `?` MUST NOT être utilisé ; les chemins `Ok`/`Err` et conversions d'erreur restent explicites.
|
|
|
|
Une règle plus spécifique MAY définir une politique d'erreur différente lorsqu'elle possède une justification architecturale explicite. PGR ne généralise pas l'interdiction d'une bibliothèque d'erreur particulière à partir d'un seul projet source.
|
|
|
|
## Formatage
|
|
|
|
`rustfmt.toml` à la racine SHOULD être le propriétaire canonique du formatage Rust d'un workspace.
|
|
|
|
Le profil PGR issu des corpus actuellement éprouvés utilise notamment :
|
|
|
|
```toml
|
|
edition = "2024"
|
|
newline_style = "Unix"
|
|
hard_tabs = false
|
|
tab_spaces = 4
|
|
max_width = 160
|
|
reorder_imports = true
|
|
reorder_modules = true
|
|
use_try_shorthand = false
|
|
force_explicit_abi = true
|
|
```
|
|
|
|
L'édition de ce fichier MUST rester cohérente avec l'édition réellement utilisée par le workspace ; l'exemple `2024` décrit la baseline actuelle et ne constitue pas un pin éternel pour les futures éditions Rust.
|
|
|
|
Après une modification Rust, `cargo fmt --all` applique le formatage canonique puis `cargo fmt --all -- --check` vérifie l'état livré. Une modification produite uniquement par le formatter officiel ne crée pas artificiellement une nouvelle révision documentaire d'un fichier si aucun contenu réel n'a changé.
|
|
|
|
Le profil structurel strict fait partie du défaut des nouvelles baselines Rust contrôlées. Un projet externe, historique ou imposé peut documenter un override borné ; cet override ne réduit pas le profil canonique des nouveaux projets. L'owner reste partagé entre `rustfmt` pour ce qu'il sait réécrire de manière fiable et des audits read-only monotâches pour les propriétés de structure qu'il ne possède pas.
|
|
|
|
Les lignes vides consécutives MUST être supprimées. Aucune ligne vide n'est conservée à l'intérieur du corps d'une fonction ou méthode, ni à l'intérieur d'une définition `struct` ou `enum`. `scripts/audit_rust_blank_lines.py` contrôle ces deux propriétés sur les fichiers Rust sélectionnés.
|
|
|
|
Deux items Rust distincts et voisins d'un même scope — fonctions/méthodes, `struct`, `enum`, `union`, `trait`, blocs `impl` ou changements de catégorie/visibilité — MUST être séparés par exactement une ligne vide lorsqu'aucune syntaxe intermédiaire ne possède elle-même l'espacement. `scripts/audit_rust_item_spacing.py` contrôle cette séparation sans tenter d'interpréter les macros ou de posséder les blocs compacts `const`/`static`/`type`.
|
|
|
|
Les déclarations compactes d'un même type et d'une même visibilité SHOULD former un bloc sans ligne vide lorsque l'ordre n'a pas de signification sémantique. Pour les constantes de module sélectionnées, l'ordre canonique est `pub`, `pub(crate)`, privé, puis le nom dans chaque visibilité ; exactement une ligne vide sépare deux niveaux de visibilité. `scripts/audit_rust_const_blocks.py` possède uniquement ce contrat `const` au niveau racine. Il MUST NOT être appliqué aveuglément à une table de protocole, une séquence de migrations, un schéma, une table de dispatch ou toute autre série dont l'ordre est contractuel. Les blocs `static`/`type` peuvent suivre la même présentation par convention locale, mais PGR ne leur ajoute pas encore un audit dédié uniquement pour atteindre une symétrie théorique.
|
|
|
|
Les déclarations `mod` de production d'un même fichier MUST précéder les modules de tests conditionnels ; les deux groupes sont ordonnés alphabétiquement lorsque l'ordre ne porte aucune sémantique locale. `scripts/audit_rust_module_order.py` contrôle cette propriété. `rustfmt` reste propriétaire de l'ordre qu'il réécrit déjà à l'intérieur d'un bloc contigu.
|
|
|
|
Les `use` non exportés autorisés par le profil strict — donc normalement des imports de traits — restent au niveau du module, avant les déclarations Rust métier et dans un bloc contigu sans ligne vide interne. `scripts/audit_rust_trait_import_blocks.py` contrôle uniquement cette disposition ; il ne prétend pas déterminer lexicalement si le symbole importé est effectivement un trait. L'ordre intra-bloc reste celui de `cargo fmt --all`.
|
|
|
|
Au crate-root, les réexports `pub use` constituent un bloc avant les `pub(crate) use`. Aucune ligne vide n'est admise à l'intérieur d'un bloc de même visibilité et exactement une ligne vide sépare les deux niveaux lorsqu'ils existent tous deux. `scripts/audit_rust_reexport_blocks.py` contrôle cette structure sans imposer un second tri : l'ordre intra-bloc reste celui produit par Rustfmt. Les rustdocs adjacentes restent possédées par les règles d'API, pas par cet audit de forme.
|
|
|
|
Lorsqu'un `struct` et ses `impl` forment une unité locale, les `impl` SHOULD suivre la structure ; de même, les éléments visibles SHOULD généralement précéder les helpers privés lorsque cela rend l'API plus lisible. PGR n'impose toutefois pas un ordre global automatique `enum → struct → impl → fn` : un ordre métier, protocolaire ou pédagogique peut être plus important. Cette propriété reste une revue tant qu'un audit fiable ne peut pas distinguer la structure informative d'un ordre sémantique.
|
|
|
|
Les scripts PGR restent des analyseurs lexicaux ciblés, pas un parser Rust général. Une macro complexe, un item généré ou une syntaxe nouvelle peut nécessiter une revue humaine ou l'owner Rust officiel. Une règle déjà possédée par `rustfmt`, rustc ou Clippy MUST NOT être réimplémentée uniquement pour multiplier les gates.
|
|
## Configuration Cargo et artefacts générés
|
|
|
|
`.cargo/config.toml` est le propriétaire naturel d'une configuration Cargo partagée par le projet lorsqu'une telle configuration est nécessaire.
|
|
|
|
Si un projet choisit de placer les artefacts Cargo hors de l'arborescence source, `target-dir` et les autres paramètres correspondants SHOULD être définis dans cette configuration plutôt que répétés dans chaque commande. Le chemin exact reste une décision de projet ou de skeleton et n'est pas figé par ce profil.
|
|
|
|
Les sorties `target/`, caches et artefacts de compilation MUST rester hors des livraisons source sauf contrat de packaging explicite.
|
|
|
|
## Tests Rust
|
|
|
|
Les tests MUST NOT élargir artificiellement la visibilité de l'API de production.
|
|
|
|
Les tests d'intégration Cargo résident sous `tests/` de la crate concernée et consomment son API publique.
|
|
|
|
Les tests unitaires restent sous la responsabilité de la crate ou du module testé. Un workspace MAY adopter une arborescence `unit_tests/` séparée et miroir de `src/` lorsqu'elle améliore la lisibilité ; cette convention doit alors être appliquée de manière cohérente sans transformer `tests/` en tests internes.
|
|
|
|
Une dépendance ou feature exclusivement nécessaire aux tests SHOULD rester dans le scope de développement/test approprié.
|
|
|
|
## Validation Rust / Cargo
|
|
|
|
Les catégories, l'autorité du gate et la proportionnalité restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md). Ce profil ajoute seulement les commandes propres à Rust/Cargo.
|
|
|
|
Lorsqu'un delta modifie du code Rust, un manifeste Cargo, une feature ou une dépendance Rust, la séquence normale SHOULD inclure :
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo fmt --all -- --check
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
|
```
|
|
|
|
Les audits structurels read-only réellement applicables s'insèrent après le formatage et avant ou autour des contrôles Cargo selon leur responsabilité.
|
|
|
|
Les tests ciblés constituent la stratégie normale d'une tranche :
|
|
|
|
```bash
|
|
cargo test -p <crate> --all-targets --all-features
|
|
```
|
|
|
|
`cargo test --workspace --all-targets --all-features` est une gate plus large réservée aux changements transverses ou aux phases où une validation globale apporte une preuve supplémentaire réelle.
|
|
|
|
`cargo build` SHOULD être exécuté lorsqu'un artefact est nécessaire ; il ne doit pas être ajouté systématiquement à `cargo check` sans besoin de build ou packaging.
|
|
|
|
`cargo tree` et ses variantes SHOULD être utilisés lors d'une modification de dépendances/features ou d'un diagnostic de graphe, pas comme cérémonie de chaque delta.
|
|
|
|
`cargo clean` est une opération de maintenance et MUST NOT être exécuté automatiquement à chaque tranche.
|
|
|
|
La validation Cargo finale appartient à l'environnement autoritaire du projet. Une prévalidation par générateur ou CI supplémentaire ne remplace pas le gate opérateur défini par le projet.
|
|
|
|
## Audits PGR pour Rust
|
|
|
|
Les audits Rust historiques de projets sources peuvent combiner de nombreuses responsabilités. PGR ne doit pas recopier cette complexité comme point de départ.
|
|
|
|
Lorsqu'une règle Rust devient objectivement automatisable dans un projet ou skeleton concret, PGR SHOULD préférer plusieurs audits monotâches et lisibles, par exemple un contrôle de manifests/workspace distinct d'un contrôle de headers ou de façade publique.
|
|
|
|
Un éventuel wrapper d'orchestration MAY appeler plusieurs audits, mais chaque audit propriétaire doit conserver une responsabilité identifiable et rester read-only.
|
|
|
|
Les deux audits de style disponibles sont documentés dans [`../validation/002-RUST_STYLE_AUDITS.md`](../validation/002-RUST_STYLE_AUDITS.md). Ils restent optionnels et prennent un corpus Rust explicitement sélectionné.
|
|
|
|
[`../validation/003-RUST_EXPORT_COMPLETENESS.md`](../validation/003-RUST_EXPORT_COMPLETENESS.md) documente séparément l'audit facultatif qui matérialise ce contrat strict. `RUST-API-201` vérifie la présence de la façade pour les items partagés ; `RUST-IMPORT-201` vérifie que les références intra-crate détectées passent réellement par `crate::Item`, y compris dans le module propriétaire, et pas seulement qu'un chemin interne long a été évité.
|
|
|
|
Cet audit ne rend pas le contrat strict obligatoire pour tous les projets Rust et ne remplace pas le compilateur. Il contrôle au contraire une convention architecturale que `rustc` et Clippy ne possèdent pas. Le dépôt PGR lui-même ne contient pas de workspace Rust sur lequel une telle gate fournirait une preuve runtime ou Cargo réelle.
|