Files
pgr/docs/templates/002-CARGO_MANIFESTS.md
2026-09-26 20:33:53 +02:00

56 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: docs/templates/002-CARGO_MANIFESTS.md -->
<!-- version: 4 -->
# Modèles de manifests Cargo workspace et crate membre
## Rôle des deux fichiers
Le [manifest racine](../../templates/rust-cargo/Cargo.toml) est celui d'un workspace virtuel à une unité de release ; le [manifest membre](../../templates/rust-cargo/crates/project-core-lib/Cargo.toml) montre une crate bibliothèque ordinaire. Les deux fichiers forment un exemple TOML syntaxiquement valide. Après copie dans un nouveau projet, il faut aussi fournir le code source de la crate avant de demander à Cargo de la compiler. Le dépôt PGR ne devient pas lui-même un workspace Cargo.
Ces modèles prolongent les trois configurations de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md). Le propriétaire des choix normatifs reste [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Les chemins `project-core-lib`, le nom du package et la version `0.1.0` sont des **valeurs d'exemple à remplacer** : cette version ne reflète pas `VERSION` de PGR et ne définit pas la version d'un autre projet.
Pour un projet existant, ne pas remplacer le manifest racine ou les manifests membres uniquement parce qu’ils diffèrent des exemples PGR. Les héritages, noms, membres, lints, métadonnées et dépendances sont d’abord comparés selon [`../rules/230-ADOPTION.md`](../rules/230-ADOPTION.md), puis classifiés `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER`. Le dry-run de [`../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md`](../validation/004-RUST_CARGO_BASELINE_DRY_RUN.md) exerce séparément ce chemin non destructif.
## Adopter le manifest racine
Copier `templates/rust-cargo/Cargo.toml` vers `Cargo.toml` du projet, corriger son header `# file:` et commencer sa propre révision de fichier à `1`. Adapter `members` aux répertoires qui existent effectivement, puis choisir la version canonique de l'unité de release. Lorsque toutes les crates partagent une seule release, aligner `[workspace.package].version` sur le `VERSION` de ce projet ; plusieurs unités de release indépendantes ne doivent pas hériter d'une version fictive commune.
L'édition `2024` et `resolver = "3"` sont cohérents avec l'exemple [`rustfmt.toml`](../../templates/rust-cargo/rustfmt.toml). Pour un workspace virtuel, fixer explicitement le resolver souhaité ; adapter ensemble l'édition, Rustfmt et la toolchain compatible si le projet prend d'autres valeurs. `publish = false` est un défaut prudent pour cet exemple ; définir la politique de publication réelle avant de publier une crate.
`license`, `repository` et `authors` ne sont volontairement pas renseignés avec des identités fictives. Si ces métadonnées ont une valeur vraie et commune, les déclarer dans `[workspace.package]` et les hériter explicitement dans chaque crate concernée, par exemple `license.workspace = true` seulement après avoir déclaré `license` à la racine. Ne pas imposer un auteur, une licence ou une URL propres à KSP/Games.
Le bloc `[workspace.dependencies]` est vide tant qu'aucune dépendance concrète ne sert plusieurs crates. Déclarer à la racine seulement les contraintes et features réellement communes ; les features propres à un membre sont activées sur sa dépendance locale. Cargo ajoute les features demandées au membre à celles déjà sélectionnées au workspace ; éviter d'activer globalement une feature de test ou de plateforme par facilité. Les dépendances de test appartiennent à `[dev-dependencies]` du membre qui les utilise.
Les trois lints Rust et les `18` niveaux Clippy reprennent la politique partagée observée dans KSP et Games. Les `allow` retiennent leurs choix de style explicite, notamment `needless_return` malgré `implicit_return = "deny"`, et évitent qu'un lint de suggestion réécrive systématiquement ce style. Réviser leur pertinence pour le projet avant adoption. Les seuils et réglages supplémentaires appartiennent au [`clippy.toml`](../../templates/rust-cargo/clippy.toml) distinct : ce fichier ne définit aucun niveau de lint.
## Adopter le manifest membre
Copier le membre vers `crates/<nom>/Cargo.toml`, adapter `name`, son chemin dans `members` et le header `# file:`. Pour un nouveau projet contrôlé, `<nom>` commence par le nom court ou l'abréviation canonique du projet et rend lisibles la responsabilité puis le rôle/cible utiles, conformément à [`510-RUST_CARGO.md`](../rules/510-RUST_CARGO.md). Ne pas conserver `project-core-lib` comme nom réel et ne pas ajouter un suffixe uniquement par symétrie. `version.workspace = true`, `edition.workspace = true` et `publish.workspace = true` rendent visibles les héritages choisis ; ajouter séparément `license.workspace = true`, `repository.workspace = true` ou `authors.workspace = true` si les valeurs existent à la racine et concernent cette crate. `[lints] workspace = true` est requis pour reprendre les niveaux du workspace : leur présence à la racine ne suffit pas à les appliquer automatiquement aux membres.
Le bloc `[dependencies]` vide se remplit selon les besoins de la crate. Pour une dépendance déjà déclarée sous `[workspace.dependencies]`, utiliser localement `nom = { workspace = true }`, avec `features = [...]` au besoin. Pour une dépendance strictement locale, choisir sa contrainte directement dans ce membre ; aucune liste tierce arbitraire n'est copiée par ce modèle.
Pour une nouvelle baseline contrôlée, une bibliothèque réutilisable et son exécutable sont normalement deux packages Cargo distincts. Le package binaire peut reprendre les mêmes héritages de workspace, mais son manifest est légitime parce qu'il exprime une frontière de packaging et de dépendances différente : il dépend des crates `-lib`, conserve un `main.rs` mince et porte un nom révélant son rôle (`-cli`, `-desk`, `-worker`, `-job`, `-server`, etc.) lorsque ce classificateur est réellement applicable. Ne pas fusionner `lib` + `bin` dans un seul package uniquement pour éviter un manifest membre supplémentaire.
Une paire `*-api` / `*-lib` n'est créée que si un vrai contrat séparé le justifie. Une crate `-api` purement déclarative ne reçoit normalement ni subscriber global ni dépendance vers la crate de logging. Une crate `-lib` unique suffit lorsqu'il n'existe qu'une implémentation utile et aucune frontière d'extension/backend/lifecycle.
Tauri est une exception framework documentée par [`710-TAURI.md`](../rules/710-TAURI.md) : son host peut être un package mixte `lib + bin`, mais les deux targets doivent alors posséder des noms distincts selon le contrat Tauri.
Une crate à version ou politique de publication réellement indépendante doit déclarer ses valeurs locales et ne plus hériter ces champs par automatisme.
## Exception locale de lints
Une frontière FFI peut avoir besoin de `unsafe_code = "allow"` dans une crate particulière, comme l'entrée Android observée dans Games. Cette exception demande justification, portée étroite et validation du code `unsafe` concerné. Cargo ne permet pas de combiner `workspace = true` avec des définitions de lints locaux dans le même manifest membre : retirer l'héritage `[lints]` pour cette crate et déclarer localement `[lints.rust]` ainsi que `[lints.clippy]`, en recopiant les niveaux partagés réellement conservés puis en ajustant seulement l'exception motivée. Les autres membres continuent d'hériter des lints racine.
## Vérification dans le projet destinataire
Après avoir ajouté le code source nécessaire, vérifier d'abord la résolution des manifests et les héritages, puis les contrôles réellement applicables :
```bash
cargo metadata --format-version 1 --no-deps
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
```
Vérifier séparément le cas d'une crate à lints locaux lorsque le projet comporte réellement une exception. `Cargo.lock` et les artefacts créés par ces commandes suivent la politique du projet et la configuration Cargo de [`001-RUST_CARGO_TOOLING.md`](001-RUST_CARGO_TOOLING.md).