0.1.0-0-pre.9-fix.1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: Android/README.md -->
|
<!-- file: Android/README.md -->
|
||||||
<!-- version: 6 -->
|
<!-- version: 7 -->
|
||||||
|
|
||||||
# Android
|
# Android
|
||||||
|
|
||||||
@@ -79,15 +79,15 @@ Les touch events standards restent traités via SDL3 et ne transitent pas par JN
|
|||||||
|
|
||||||
## Packaging des assets
|
## Packaging des assets
|
||||||
|
|
||||||
Les modules applications exécutent `stageSasedevAssets` avant `preBuild`.
|
Chaque variante Android enregistre une tâche `stage<Variant>SasedevAssets` via la Variant API AGP.
|
||||||
|
|
||||||
La tâche compose les sources :
|
La tâche générée compose les sources :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
assets/common/ -> assets/common/
|
assets/common/ -> assets/common/
|
||||||
assets/<game>/ -> assets/game/
|
assets/<game>/ -> assets/game/
|
||||||
```
|
```
|
||||||
|
|
||||||
dans un répertoire généré sous `Android/<module>/build/generated/sasedevAssets/main/`.
|
dans un répertoire généré sous `Android/<module>/build/generated/sasedevAssets/<variant>/`.
|
||||||
|
|
||||||
Aucune ressource source n'est copiée durablement dans un module Android ou une crate Rust.
|
Aucune ressource source n'est copiée durablement dans un module Android ou une crate Rust.
|
||||||
|
|||||||
@@ -1,22 +1,44 @@
|
|||||||
// file: Android/gradle/sasedev-assets.gradle
|
// file: Android/gradle/sasedev-assets.gradle
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
def generatedAssetsDirectory = layout.buildDirectory.dir("generated/sasedevAssets/main")
|
abstract class StageSasedevAssetsTask extends DefaultTask {
|
||||||
def sourceCommonAssets = rootProject.file("../assets/common")
|
@InputDirectory
|
||||||
def sourceGameAssets = rootProject.file("../assets/${project.ext.sasedevGameAssetDirectory}")
|
abstract DirectoryProperty getCommonAssetsDirectory()
|
||||||
|
|
||||||
tasks.register("stageSasedevAssets", Sync) {
|
@InputDirectory
|
||||||
into(generatedAssetsDirectory)
|
abstract DirectoryProperty getGameAssetsDirectory()
|
||||||
from(sourceCommonAssets) {
|
|
||||||
into("common")
|
@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"))
|
||||||
}
|
}
|
||||||
from(sourceGameAssets) {
|
|
||||||
into("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 {
|
variant.sources.assets.addGeneratedSourceDirectory(stageTask) { task ->
|
||||||
dependsOn(tasks.named("stageSasedevAssets"))
|
task.outputDirectory
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 17
|
# version: 18
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
@@ -17,7 +17,7 @@ members = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.0-0-pre.9"
|
version = "0.1.0-0-pre.9.fix.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/games"
|
repository = "https://git.sasedev.com/Sasedev/games"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// file: crates/common/game-assets-lib/unit_tests/resolver.rs
|
// file: crates/common/game-assets-lib/unit_tests/resolver.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn logical_namespaces_resolve_to_separate_roots() {
|
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");
|
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("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")));
|
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]
|
#[test]
|
||||||
fn traversal_and_unknown_schemes_are_rejected() {
|
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");
|
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("game://../secret"), Err(crate::AssetError::InvalidPath));
|
||||||
assert_eq!(resolver.resolve("file://data/game.json"), Err(crate::AssetError::UnsupportedScheme));
|
assert_eq!(resolver.resolve("file://data/game.json"), Err(crate::AssetError::UnsupportedScheme));
|
||||||
|
|||||||
116
deltas/0.1.0/0-pre.9.fix.1.md
Normal file
116
deltas/0.1.0/0-pre.9.fix.1.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<!-- file: deltas/0.1.0/0-pre.9.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# 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<Directory>` 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
|
||||||
|
stage<Variant>SasedevAssets
|
||||||
|
```
|
||||||
|
|
||||||
|
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`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/architecture/005-ASSET_ARCHITECTURE.md -->
|
<!-- file: docs/architecture/005-ASSET_ARCHITECTURE.md -->
|
||||||
<!-- version: 2 -->
|
<!-- version: 3 -->
|
||||||
|
|
||||||
# Architecture des assets
|
# Architecture des assets
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ Le développement peut aussi résoudre directement les deux racines source sans
|
|||||||
|
|
||||||
## Android
|
## Android
|
||||||
|
|
||||||
Une tâche Gradle `stageSasedevAssets` compose les assets sous `build/generated/` avant `preBuild`.
|
Chaque variante Gradle enregistre une tâche `stage<Variant>SasedevAssets` et l'attache à `variant.sources.assets` avec `addGeneratedSourceDirectory`.
|
||||||
|
|
||||||
Le contenu final de l'APK conserve les namespaces :
|
Le contenu final de l'APK conserve les namespaces :
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user