Prune commentary and stale Rust port notes

This commit is contained in:
iris committed 2026-09-10 00:44:13 -04:00
1 parent 5428cd75c9
commit 25370731d0
193 files changed
+693 -16219

No files matched your search

+1 -8
View File
@@ -3,14 +3,7 @@ name = "xtask"
version = "0.1.0"
edition = "2024"
# E5 (RUST.md): packages app/shellApp into a signed, installable APK without
# Gradle driving the assembly (cargo ndk -> javac -> d8 -> aapt2 -> zipalign
# -> apksigner). No dependencies beyond the standard library: every step
# below is "run this SDK tool with these arguments and check its exit
# status," which needs nothing a crate would help with, and every tool
# invoked is one this project already requires (the NDK, the SDK
# build-tools, the JDK, `cargo ndk`) -- see AGENTS.md's "new dependencies
# need a reason."
# Packages the Compose shell APK directly with existing SDK/JDK tools.
[[bin]]
name = "xtask"
path = "src/main.rs"
-52
View File
@@ -1,26 +1,3 @@
//! The pipeline itself: `cargo ndk` -> `javac`/`d8` -> `aapt2` ->
//! `zipalign` -> `apksigner`, with no Gradle driving *this* file's steps.
//!
//! **One disclosed exception**, recorded here rather than left to be
//! rediscovered: step 3 below still runs `./gradlew
//! :shellApp:printRuntimeClasspathJars` once, because `app/shellApp`
//! depends on the `:link` submodule (Kotlin: `ServerStore`/`ServerSettings`,
//! the Keystore-sealed enrollment, RUST.md's E3 entry explains why that
//! code is reused rather than re-derived in Rust) and on
//! `androidx.core:core-ktx` (used at runtime through JNI by
//! the shell bridge's `notify.rs`, for `NotificationCompat` and friends).
//! Both are ordinary Maven/AAR dependency graphs, and reimplementing a
//! dependency resolver to avoid one Gradle invocation was not a good trade
//! against "smallest honest route" (RUST.md's E5 box) -- especially since
//! that one call also compiles `:link`'s Kotlin as a side effect, using
//! Gradle's own embedded Kotlin compiler. This machine has no standalone
//! `kotlinc` (checked: not on PATH, not under any SDK), so that side
//! effect is what answers E3's open question about `kotlinc` -- see
//! RUST.md's E5 entry for the full account. Nothing past this one call
//! touches Gradle: `javac`, `d8`, `aapt2`, `zipalign` and `apksigner` are
//! invoked directly, and the jars this call resolves are consumed as
//! plain binary inputs to `d8`, exactly like any other pre-built `.jar`.
use std::path::{Path, PathBuf};
use std::process::Command;
@@ -43,10 +20,6 @@ pub fn build(variant: Variant, abis: &[String]) -> Result<PathBuf, Fail> {
sdk::require_ndk_installed(&sdk.root)?;
require_cargo_ndk()?;
// xtask's own intermediate files, in its own crate's target/ rather
// than a `target/` at the repo root -- there is no workspace there and
// a build directory in the root is not something anybody was looking
// for (Iris, 2026-09-09).
let out_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("target")
.join("apk");
@@ -98,16 +71,6 @@ pub fn build(variant: Variant, abis: &[String]) -> Result<PathBuf, Fail> {
let signed_apk = out_dir.join(format!("ai-app-shell-{variant_name}.apk"));
align_and_sign(&sdk, &merged_apk, &signed_apk, &signer)?;
// Copied into a Gradle-shaped path (`build/outputs/apk/<mode>/*.apk`
// under this xtask's own directory) as the final step, purely so Dev
// Updater's fixed-pattern APK discovery (`discover.rs`'s
// `APK_PATTERNS`, which has no per-component path override) finds it
// without needing a change on that side -- `.dev-updater.ron`'s
// `shell` component points its `cwd` here. The working files above
// stay under `scripts/xtask/target/apk/`, an ordinary build-cache location.
// `scripts/build/...`, not `scripts/xtask/build/...`: Dev Updater
// discovers APKs with `*/build/outputs/apk/*/*.apk` from the checkout
// root, which is exactly one directory deep. See `.dev-updater.ron`.
let published_dir = repo_root
.join("scripts/build/outputs/apk")
.join(variant_name);
@@ -131,8 +94,6 @@ pub fn build(variant: Variant, abis: &[String]) -> Result<PathBuf, Fail> {
}
fn repo_root() -> Result<PathBuf, Fail> {
// xtask's own Cargo.toml is at <repo_root>/scripts/xtask/Cargo.toml,
// so the root is two levels up (2026-09-09: it used to be one).
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
manifest_dir
.parent()
@@ -156,9 +117,6 @@ fn require_cargo_ndk() -> Result<(), Fail> {
.map(|_| ())
}
/// `cargo ndk`'s `-t` target name for each ABI, and `-P 26` -- the API
/// level every other cross-compile in this repo uses (RUST.md: E0, E1, E3,
/// I2), kept consistent here rather than picked fresh.
fn build_native_libs(
crate_dir: &Path,
shell_app_dir: &Path,
@@ -173,11 +131,6 @@ fn build_native_libs(
cmd.args(["-t", abi]);
}
cmd.args(["-P", "26", "-o"]).arg(&jni_libs);
// Always the release profile for the native library, independent of
// the APK's signing variant -- a debug build's Vulkan object-labelling
// segfaults this emulator's driver (RUST.md's E1 entry), and there is
// no reason for this crate's debug build to be bigger or slower for a
// signing choice that has nothing to do with it.
cmd.args([
"build",
"--release",
@@ -270,11 +223,6 @@ fn compile_java(
"check permissions under scripts/xtask/target/",
)
})?;
// Same shape as shellApp's Gradle `generatePinnedCa` task: the text
// block must start immediately after the opening `"""`, or
// CertificateFactory stops recognising the "-----BEGIN" preamble (a
// real bug this project hit once -- see AGENTS.md's "Things that have
// bitten").
let pinned_ca_java = format!(
"package com.example.aiapp.shell;\n\npublic final class PinnedCa {{\n private PinnedCa() {{}}\n public static final String PINNED_CA_PEM = \"\"\"\n{ca_pem}\"\"\";\n}}\n"
);
-13
View File
@@ -1,9 +1,3 @@
//! The signing key. Mirrors `app/build-apk.sh`'s exact logic for the
//! release key -- same env vars, same path, same generation recipe -- so
//! the two tools sign with the *same* key and their outputs can
//! `adb install -r` over each other. That is the whole point of E5's pass
//! condition: the key has to be identical, not merely present.
use std::path::PathBuf;
use std::process::Command;
@@ -15,10 +9,6 @@ pub struct Signer {
pub alias: String,
}
/// The release key at `$AI_APP_KEYSTORE` or
/// `$XDG_CONFIG_HOME/ai-app/release.jks` (`~/.config/ai-app/release.jks` by
/// default) -- generated with `keytool` if it doesn't exist yet, exactly as
/// `build-apk.sh` does, so either tool can run first on a fresh machine.
pub fn release_signer() -> Result<Signer, Fail> {
let keystore = std::env::var_os("AI_APP_KEYSTORE")
.map(PathBuf::from)
@@ -188,9 +178,6 @@ fn which_keytool() -> Result<PathBuf, Fail> {
}
fn random_password() -> String {
// No dependency on `rand`: /dev/urandom is what build-apk.sh's `head -c
// 24 /dev/urandom | base64` reads too, so this reproduces exactly the
// same recipe without shelling out to head/base64/tr for it.
let mut bytes = [0u8; 24];
std::fs::File::open("/dev/urandom")
.and_then(|mut f| std::io::Read::read_exact(&mut f, &mut bytes))
-22
View File
@@ -1,14 +1,3 @@
//! `cargo xtask apk` -- E5 (RUST.md): packages `app/shellApp` into a
//! signed, installable APK with no Gradle in the packaging step itself.
//! `cargo ndk` cross-compiles the app crate's `shell` feature; `javac`/`d8` turn its two
//! Java stub classes (plus the generated pinned-CA constant) into dex;
//! `aapt2` compiles the manifest into `resources.arsc`; the dex and native
//! libraries are merged into that base APK with `jar`; `zipalign` and
//! `apksigner` finish it. See `apk.rs`'s module doc for what "no Gradle in
//! the packaging step" does and does not cover -- one disclosed exception.
//!
//! Usage: `cargo xtask apk [--release|--debug] [--abi ABI]...`
mod apk;
mod keystore;
mod sdk;
@@ -16,9 +5,6 @@ mod sdk;
use std::fmt;
use std::process::ExitCode;
/// A failure a person acts on: what went wrong, what this process actually
/// saw, and the next thing to try. Matches CODE_RULES's "a failure message
/// names the thing, the cause, and the fix."
pub struct Fail {
what: String,
cause: String,
@@ -71,11 +57,6 @@ fn main() -> ExitCode {
let mut i = 0;
while i < rest.len() {
match rest[i].as_str() {
// Bare "release"/"debug" is `.dev-updater.ron`'s interface
// (`ByMode::One` appends the chosen mode as the build
// command's last argument -- the same convention
// `app/build-apk.sh`'s `${1:-release}` uses); the `--`-prefixed
// spellings are for typing this by hand.
"release" | "--release" => variant = Variant::Release,
"debug" | "--debug" => variant = Variant::Debug,
"--abi" => {
@@ -96,9 +77,6 @@ fn main() -> ExitCode {
i += 1;
}
if abis.is_empty() {
// arm64-v8a for a real phone, x86_64 for this machine's emulator --
// the two ABIs every other experiment in RUST.md has actually run
// on. `--abi` overrides either way.
abis = vec!["arm64-v8a".to_string(), "x86_64".to_string()];
}