manifest.py
file-level
1
files
1
commits
0
hotspots
0
🧊 dead
0
💥 blast risk
| 1 | """Validate the cross-platform Tauri desktop packaging manifest.""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | from dataclasses import dataclass |
| 6 | from pathlib import Path |
| 7 | |
| 8 | from tools.desktop.constants import ( |
| 9 | CANONICAL_LAUNCHER, |
| 10 | CANONICAL_SUBCOMMAND, |
| 11 | DESKTOP_IDENTIFIER, |
| 12 | DESKTOP_PRODUCT_NAME, |
| 13 | ) |
| 14 | |
| 15 | |
| 16 | @dataclass(frozen=True) |
| 17 | class DesktopManifest: |
| 18 | """Paths required for Track Q / Q3 desktop packaging.""" |
| 19 | |
| 20 | root: Path |
| 21 | tauri_conf: Path |
| 22 | cargo_toml: Path |
| 23 | lib_rs: Path |
| 24 | launcher_rs: Path |
| 25 | package_json: Path |
| 26 | ok_shim: Path |
| 27 | bundle_script: Path |
| 28 | |
| 29 | @classmethod |
| 30 | def from_kit_root(cls, kit_root: Path) -> DesktopManifest: |
| 31 | desktop = kit_root / "desktop" |
| 32 | return cls( |
| 33 | root=desktop, |
| 34 | tauri_conf=desktop / "src-tauri" / "tauri.conf.json", |
| 35 | cargo_toml=desktop / "src-tauri" / "Cargo.toml", |
| 36 | lib_rs=desktop / "src-tauri" / "src" / "lib.rs", |
| 37 | launcher_rs=desktop / "src-tauri" / "src" / "launcher.rs", |
| 38 | package_json=desktop / "package.json", |
| 39 | ok_shim=kit_root / "cli" / CANONICAL_LAUNCHER, |
| 40 | bundle_script=kit_root / "scripts" / "bundle-desktop-kit.sh", |
| 41 | ) |
| 42 | |
| 43 | |
| 44 | def validate_desktop_manifest(manifest: DesktopManifest) -> list[str]: |
| 45 | """Return human-readable errors when packaging files are missing or misconfigured.""" |
| 46 | errors: list[str] = [] |
| 47 | for label, path in ( |
| 48 | ("tauri.conf.json", manifest.tauri_conf), |
| 49 | ("Cargo.toml", manifest.cargo_toml), |
| 50 | ("lib.rs", manifest.lib_rs), |
| 51 | ("launcher.rs", manifest.launcher_rs), |
| 52 | ("package.json", manifest.package_json), |
| 53 | ("ok shim", manifest.ok_shim), |
| 54 | ("bundle script", manifest.bundle_script), |
| 55 | ): |
| 56 | if not path.is_file(): |
| 57 | errors.append(f"missing {label}: {path}") |
| 58 | |
| 59 | if manifest.tauri_conf.is_file(): |
| 60 | text = manifest.tauri_conf.read_text(encoding="utf-8") |
| 61 | if DESKTOP_PRODUCT_NAME not in text: |
| 62 | errors.append(f"tauri.conf.json must name product {DESKTOP_PRODUCT_NAME!r}") |
| 63 | if DESKTOP_IDENTIFIER not in text: |
| 64 | errors.append(f"tauri.conf.json must use identifier {DESKTOP_IDENTIFIER!r}") |
| 65 | |
| 66 | if manifest.lib_rs.is_file(): |
| 67 | lib = manifest.lib_rs.read_text(encoding="utf-8") |
| 68 | if "mod launcher" not in lib: |
| 69 | errors.append("lib.rs must wire the desktop launcher module") |
| 70 | if "WebviewUrl::External" not in lib: |
| 71 | errors.append("lib.rs must load the loopback UI in an external webview") |
| 72 | |
| 73 | if manifest.launcher_rs.is_file(): |
| 74 | launcher = manifest.launcher_rs.read_text(encoding="utf-8") |
| 75 | if CANONICAL_LAUNCHER not in launcher or CANONICAL_SUBCOMMAND not in launcher: |
| 76 | errors.append("launcher.rs must invoke canonical ok app launcher") |
| 77 | if "127.0.0.1" not in launcher: |
| 78 | errors.append("launcher.rs must keep loopback-only packaging defaults") |
| 79 | |
| 80 | if manifest.bundle_script.is_file(): |
| 81 | script = manifest.bundle_script.read_text(encoding="utf-8") |
| 82 | for needle in ("cli", "adapters", "tools"): |
| 83 | if needle not in script: |
| 84 | errors.append(f"bundle script must copy {needle}") |
| 85 | |
| 86 | return errors |