0.3.3-0-pre.3

This commit is contained in:
2026-09-21 10:32:31 +02:00
parent f770f99a4a
commit 5854ac3d07
16 changed files with 1004 additions and 107 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# file: scripts/audit_distribution_layout.py
# version: 14
# version: 16
"""Audit the static distribution layout expected by supported POCs."""
@@ -13,6 +13,10 @@ import sys
FORBIDDEN_PATHS = (
"builds",
"Android/gradlew",
"Android/gradlew.bat",
"Android/gradle/wrapper/gradle-wrapper.jar",
"Android/gradle/wrapper/gradle-wrapper.properties",
)
@@ -60,6 +64,8 @@ REQUIRED_PATHS = (
"Web/game-snake-poc/frontend/ts/provenance.ts",
"Android/game-reflex-poc/build.gradle",
"Android/game-snake-poc/build.gradle",
"Android/settings.gradle",
"Android/gradle/sasedev-rust-android.gradle",
"scripts/build_android_rust.py",
"scripts/build_reflex_tauri_wasm.py",
"assets/common",
@@ -302,6 +308,71 @@ def audit_snake_tauri_generated_android(root: pathlib.Path) -> list[str]:
return violations
def audit_android_native_gradle(root: pathlib.Path) -> list[str]:
"""Validate the minimum Gradle contract and multi-ABI native Rust consumers."""
violations: list[str] = []
settings_path = root / "Android/settings.gradle"
native_script_path = root / "Android/gradle/sasedev-rust-android.gradle"
snake_build_path = root / "Android/game-snake-poc/build.gradle"
reflex_build_path = root / "Android/game-reflex-poc/build.gradle"
required = (settings_path, native_script_path, snake_build_path, reflex_build_path)
if not all(path.exists() for path in required):
return violations
settings = settings_path.read_text(encoding="utf-8")
settings_fragments = (
'import org.gradle.util.GradleVersion',
'GradleVersion.version("9.6.0")',
'GradleVersion.current()',
'currentGradleVersion < minimumGradleVersion',
)
for fragment in settings_fragments:
if fragment not in settings:
violations.append(f"DIST-LAYOUT-072: Android settings missing minimum Gradle gate: {fragment}")
native_script = native_script_path.read_text(encoding="utf-8")
native_fragments = (
'spec.commandLine(',
'"cargo",',
'"ndk",',
'"--no-default-features",',
'variant.sources.jniLibs.addGeneratedSourceDirectory',
'generated/sasedevNative/',
'libgame_android_entrypoint.so',
'libSDL3.so',
)
for fragment in native_fragments:
if fragment not in native_script:
violations.append(f"DIST-LAYOUT-074: Gradle-owned Rust Android build missing contract: {fragment}")
if "build_android_rust.py" in native_script or "python" in native_script.lower():
violations.append("DIST-LAYOUT-075: Gradle-owned Rust Android build must not delegate orchestration to Python")
consumers = (
(
"Snake",
snake_build_path.read_text(encoding="utf-8"),
'ext.sasedevRustGameFeature = "snake"',
),
(
"Reflex",
reflex_build_path.read_text(encoding="utf-8"),
'ext.sasedevRustGameFeature = "reflex"',
),
)
shared_fragments = (
'ext.sasedevRustAndroidAbis = ["arm64-v8a", "x86_64"]',
"abiFilters 'arm64-v8a', 'x86_64'",
'apply from: rootProject.file("gradle/sasedev-rust-android.gradle")',
)
for label, content, feature_fragment in consumers:
for fragment in (feature_fragment, *shared_fragments):
if fragment not in content:
violations.append(f"DIST-LAYOUT-076: {label} Android multi-ABI consumer missing contract: {fragment}")
return violations
def main() -> int:
"""Validate that every static distribution boundary exists."""
@@ -322,6 +393,7 @@ def main() -> int:
contract_violations.extend(audit_snake_web_integration(root))
contract_violations.extend(audit_snake_tauri_android_integration(root))
contract_violations.extend(audit_snake_tauri_generated_android(root))
contract_violations.extend(audit_android_native_gradle(root))
if missing:
for relative in missing:
print(f"DIST-LAYOUT-001: missing required path: {relative}", file=sys.stderr)