From a3d5572c37896b4db2ca901ef1ac3ba0962610d1 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Wed, 16 Sep 2026 10:04:59 +0200 Subject: [PATCH] 0.1.0-0-pre.9-fix.1 --- Android/README.md | 8 +- Android/gradle/sasedev-assets.gradle | 50 +++++--- Cargo.toml | 4 +- .../game-assets-lib/unit_tests/resolver.rs | 6 +- deltas/0.1.0/0-pre.9.fix.1.md | 116 ++++++++++++++++++ docs/architecture/005-ASSET_ARCHITECTURE.md | 4 +- 6 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 deltas/0.1.0/0-pre.9.fix.1.md diff --git a/Android/README.md b/Android/README.md index ac85ac5..b38d484 100644 --- a/Android/README.md +++ b/Android/README.md @@ -1,5 +1,5 @@ - + # Android @@ -79,15 +79,15 @@ Les touch events standards restent traités via SDL3 et ne transitent pas par JN ## Packaging des assets -Les modules applications exécutent `stageSasedevAssets` avant `preBuild`. +Chaque variante Android enregistre une tâche `stageSasedevAssets` via la Variant API AGP. -La tâche compose les sources : +La tâche générée compose les sources : ```text assets/common/ -> assets/common/ assets// -> assets/game/ ``` -dans un répertoire généré sous `Android//build/generated/sasedevAssets/main/`. +dans un répertoire généré sous `Android//build/generated/sasedevAssets//`. Aucune ressource source n'est copiée durablement dans un module Android ou une crate Rust. diff --git a/Android/gradle/sasedev-assets.gradle b/Android/gradle/sasedev-assets.gradle index b191233..043c7b9 100644 --- a/Android/gradle/sasedev-assets.gradle +++ b/Android/gradle/sasedev-assets.gradle @@ -1,22 +1,44 @@ // file: Android/gradle/sasedev-assets.gradle -// version: 1 +// version: 2 -def generatedAssetsDirectory = layout.buildDirectory.dir("generated/sasedevAssets/main") -def sourceCommonAssets = rootProject.file("../assets/common") -def sourceGameAssets = rootProject.file("../assets/${project.ext.sasedevGameAssetDirectory}") +abstract class StageSasedevAssetsTask extends DefaultTask { + @InputDirectory + abstract DirectoryProperty getCommonAssetsDirectory() -tasks.register("stageSasedevAssets", Sync) { - into(generatedAssetsDirectory) - from(sourceCommonAssets) { - into("common") - } - from(sourceGameAssets) { - into("game") + @InputDirectory + abstract DirectoryProperty getGameAssetsDirectory() + + @OutputDirectory + abstract DirectoryProperty getOutputDirectory() + + @TaskAction + void stageAssets() { + def output = outputDirectory.get().asFile + project.delete(output) + + project.copy { + from(commonAssetsDirectory) + into(new File(output, "common")) + } + + project.copy { + from(gameAssetsDirectory) + into(new File(output, "game")) + } } } -android.sourceSets.main.assets.srcDir(generatedAssetsDirectory) +androidComponents { + onVariants(selector().all()) { variant -> + def capitalizedVariantName = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) + def stageTask = tasks.register("stage${capitalizedVariantName}SasedevAssets", StageSasedevAssetsTask) { + commonAssetsDirectory.set(rootProject.layout.projectDirectory.dir("../assets/common")) + gameAssetsDirectory.set(rootProject.layout.projectDirectory.dir("../assets/${project.ext.sasedevGameAssetDirectory}")) + outputDirectory.set(layout.buildDirectory.dir("generated/sasedevAssets/${variant.name}")) + } -tasks.named("preBuild").configure { - dependsOn(tasks.named("stageSasedevAssets")) + variant.sources.assets.addGeneratedSourceDirectory(stageTask) { task -> + task.outputDirectory + } + } } diff --git a/Cargo.toml b/Cargo.toml index 5da9746..08abeab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ # file: Cargo.toml -# version: 17 +# version: 18 [workspace] resolver = "3" @@ -17,7 +17,7 @@ members = [ ] [workspace.package] -version = "0.1.0-0-pre.9" +version = "0.1.0-0-pre.9.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/games" diff --git a/crates/common/game-assets-lib/unit_tests/resolver.rs b/crates/common/game-assets-lib/unit_tests/resolver.rs index 3ca5256..1170b5a 100644 --- a/crates/common/game-assets-lib/unit_tests/resolver.rs +++ b/crates/common/game-assets-lib/unit_tests/resolver.rs @@ -1,9 +1,9 @@ // file: crates/common/game-assets-lib/unit_tests/resolver.rs -// version: 1 +// version: 2 #[test] fn logical_namespaces_resolve_to_separate_roots() { - game_logging_lib::with_test_tracing(|| { + game_logging_lib::with_test_tracing("logical_namespaces_resolve_to_separate_roots", || { let resolver = crate::AssetResolver::new("assets/common", "assets/game-reflex-poc"); assert_eq!(resolver.resolve("common://data/runtime.json"), Ok(std::path::PathBuf::from("assets/common/data/runtime.json"))); assert_eq!(resolver.resolve("game://data/game.json"), Ok(std::path::PathBuf::from("assets/game-reflex-poc/data/game.json"))); @@ -12,7 +12,7 @@ fn logical_namespaces_resolve_to_separate_roots() { #[test] fn traversal_and_unknown_schemes_are_rejected() { - game_logging_lib::with_test_tracing(|| { + game_logging_lib::with_test_tracing("traversal_and_unknown_schemes_are_rejected", || { let resolver = crate::AssetResolver::new("assets/common", "assets/game-reflex-poc"); assert_eq!(resolver.resolve("game://../secret"), Err(crate::AssetError::InvalidPath)); assert_eq!(resolver.resolve("file://data/game.json"), Err(crate::AssetError::UnsupportedScheme)); diff --git a/deltas/0.1.0/0-pre.9.fix.1.md b/deltas/0.1.0/0-pre.9.fix.1.md new file mode 100644 index 0000000..eca4bd5 --- /dev/null +++ b/deltas/0.1.0/0-pre.9.fix.1.md @@ -0,0 +1,116 @@ + + + +# Delta 0.1.0-0-pre.9.fix.1 + +## Base + +Base déclarée : `0.1.0-0-pre.9`, non validée. + +## Échecs observés + +La validation de `0-pre.9` a mis en évidence deux défauts du delta. + +### Tests `game-assets-lib` + +`game_logging_lib::with_test_tracing` attend deux arguments : + +```text +test_name: &str +operation: FnOnce() +``` + +Les deux tests du resolver ne passaient que la closure. + +### Android Gradle + +AGP 9.4 refuse l'ajout d'un `Provider` via l'ancienne API : + +```text +android.sourceSets.main.assets.srcDir(...) +``` + +pour un répertoire généré. + +Le message AGP demande explicitement l'utilisation de la Variant API et de `SourceDirectories.addGeneratedSourceDirectory`. + +## Correctif + +### Tests + +Chaque test passe désormais son nom explicite à `with_test_tracing`. + +### Gradle + +Le staging Android utilise maintenant une tâche Gradle dédiée avec : + +```text +@InputDirectory commonAssetsDirectory +@InputDirectory gameAssetsDirectory +@OutputDirectory outputDirectory +``` + +Pour chaque variante, `androidComponents.onVariants` enregistre : + +```text +stageSasedevAssets +``` + +puis relie sa sortie à : + +```text +variant.sources.assets.addGeneratedSourceDirectory(...) +``` + +Aucun fallback `android.sourceset.disallowProvider=false` n'est ajouté. + +## Validation à exécuter + +```bash +cargo fmt --all +cargo fmt --all -- --check + +python3 scripts/audit_rust_workspace_rules.py +python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android deltas history + +cargo check --workspace +cargo clippy --workspace --all-targets --all-features -- -D warnings + +cargo test -p game-assets-lib --all-targets --all-features +``` + +Le staging Desktop de `0-pre.9` était déjà propre et n'a pas changé. + +Validation Android : + +```bash +cd Android + +gradle :game-reflex-poc:assembleDebug +gradle :game-snake-poc:assembleDebug + +cd .. +``` + +Puis vérifier : + +```bash +unzip -l Android/game-reflex-poc/build/outputs/apk/debug/game-reflex-poc-debug.apk | grep 'assets/common/data/runtime.json' +unzip -l Android/game-reflex-poc/build/outputs/apk/debug/game-reflex-poc-debug.apk | grep 'assets/game/data/game.json' + +unzip -l Android/game-snake-poc/build/outputs/apk/debug/game-snake-poc-debug.apk | grep 'assets/common/data/runtime.json' +unzip -l Android/game-snake-poc/build/outputs/apk/debug/game-snake-poc-debug.apk | grep 'assets/game/data/game.json' +``` + +Et vérifier l'absence d'assets de l'autre jeu : + +```bash +! unzip -l Android/game-reflex-poc/build/outputs/apk/debug/game-reflex-poc-debug.apk | grep -q 'game-snake-poc' +! unzip -l Android/game-snake-poc/build/outputs/apk/debug/game-snake-poc-debug.apk | grep -q 'game-reflex-poc' +``` + +## Transition + +Si ces gates sont propres, `0.1.0-0-pre.9.fix.1` est validé et le travail passe automatiquement à `0.1.0-0-pre.10`. + +En cas d'échec imputable au projet, produire `0.1.0-0-pre.9.fix.2`. diff --git a/docs/architecture/005-ASSET_ARCHITECTURE.md b/docs/architecture/005-ASSET_ARCHITECTURE.md index 4f986ae..cb5a842 100644 --- a/docs/architecture/005-ASSET_ARCHITECTURE.md +++ b/docs/architecture/005-ASSET_ARCHITECTURE.md @@ -1,5 +1,5 @@ - + # Architecture des assets @@ -82,7 +82,7 @@ Le développement peut aussi résoudre directement les deux racines source sans ## Android -Une tâche Gradle `stageSasedevAssets` compose les assets sous `build/generated/` avant `preBuild`. +Chaque variante Gradle enregistre une tâche `stageSasedevAssets` et l'attache à `variant.sources.assets` avec `addGeneratedSourceDirectory`. Le contenu final de l'APK conserve les namespaces :