fix(xtask): give mobile starters app-owned commands
Make app new --mobile write hemx-app with HEMX_APP_* release settings, app-scoped release output, and docs that name Workout only as the concrete starter flow instead of leaking Workout command identity. req: ceremony/006
This commit is contained in:
@@ -14,8 +14,8 @@ this path outside the repository:
|
|||||||
cargo run -p hemx-xtask -- app new --mobile PATH
|
cargo run -p hemx-xtask -- app new --mobile PATH
|
||||||
```
|
```
|
||||||
|
|
||||||
The created app includes the same `hemx-workout mobile-release` and
|
The created app includes app-owned `hemx-app mobile-release` and
|
||||||
`hemx-workout mobile-verify` commands, plus `MOBILE_STARTER.md` naming the host,
|
`hemx-app mobile-verify` commands, plus `MOBILE_STARTER.md` naming the host,
|
||||||
recovery, and release-kit boundary. req: ceremony/006
|
recovery, and release-kit boundary. req: ceremony/006
|
||||||
|
|
||||||
## When to use this path
|
## When to use this path
|
||||||
|
|||||||
+32
-4
@@ -91,7 +91,7 @@ fn run_app_new(operands: &[String]) -> ExitCode {
|
|||||||
);
|
);
|
||||||
if mobile {
|
if mobile {
|
||||||
println!(
|
println!(
|
||||||
"next\tHEMX_WORKOUT_ORIGIN=https://app.example.com {}/hemx-workout mobile-release",
|
"next\tHEMX_APP_ORIGIN=https://app.example.com {}/hemx-app mobile-release",
|
||||||
destination.display()
|
destination.display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -217,9 +217,31 @@ fn create_app_scaffold(destination: &Path) -> std::io::Result<()> {
|
|||||||
fn create_mobile_app_scaffold(destination: &Path) -> std::io::Result<()> {
|
fn create_mobile_app_scaffold(destination: &Path) -> std::io::Result<()> {
|
||||||
// req: ceremony/006 req: examples/006
|
// req: ceremony/006 req: examples/006
|
||||||
create_workout_app(destination)?;
|
create_workout_app(destination)?;
|
||||||
|
fs::rename(
|
||||||
|
destination.join("hemx-workout"),
|
||||||
|
destination.join("hemx-app"),
|
||||||
|
)?;
|
||||||
|
for (from, to) in [
|
||||||
|
("hemx_workout_app", "hemx_app"),
|
||||||
|
("hemx-workout-app", "hemx-app"),
|
||||||
|
("workout-app", "hemx-app"),
|
||||||
|
("./hemx-workout", "./hemx-app"),
|
||||||
|
("hemx-workout", "hemx-app"),
|
||||||
|
("HEMX_WORKOUT_", "HEMX_APP_"),
|
||||||
|
("target/hemx-mobile/workout", "target/hemx-mobile/app"),
|
||||||
|
("com.hemx.workout", "com.hemx.app"),
|
||||||
|
("hemx Workout Copilot", "hemx App"),
|
||||||
|
(
|
||||||
|
"# Workout mobile external blockers",
|
||||||
|
"# hemx app mobile external blockers",
|
||||||
|
),
|
||||||
|
("workout-mobile", "app-mobile"),
|
||||||
|
] {
|
||||||
|
replace_in_tree(destination, from, to)?;
|
||||||
|
}
|
||||||
fs::write(
|
fs::write(
|
||||||
destination.join("MOBILE_STARTER.md"),
|
destination.join("MOBILE_STARTER.md"),
|
||||||
"# Mobile hemx starter\n\nThis starter is the phone-first Workout path exposed through `app new --mobile`: it has a real page/form/keyed partial/notice flow, typed host haptics/share calls returning through Rust handlers, app-owned command/event/projection recovery truth, and the same `hemx-workout mobile-release` / `hemx-workout mobile-verify` release-kit commands.\n\nIt deliberately does not add a hemx mobile framework, client store, signing secret owner, or store submission bot. req: ceremony/006 req: examples/006\n",
|
"# Mobile hemx starter\n\nThis starter is the phone-first path exposed through `app new --mobile`: it has a real page/form/keyed partial/notice flow, typed host haptics/share calls returning through Rust handlers, app-owned command/event/projection recovery truth, and app-owned `hemx-app mobile-release` / `hemx-app mobile-verify` release-kit commands.\n\nThe starter uses the Workout product flow as a concrete first app, but its command surface, crate name, binary name, release output, and environment variables are owned by the created app. It deliberately does not add a hemx mobile framework, client store, signing secret owner, or store submission bot. req: ceremony/006 req: examples/006\n",
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1250,17 +1272,21 @@ mod tests {
|
|||||||
create_mobile_app_scaffold(&destination).expect("create mobile app scaffold");
|
create_mobile_app_scaffold(&destination).expect("create mobile app scaffold");
|
||||||
let mobile_readme =
|
let mobile_readme =
|
||||||
fs::read_to_string(destination.join("MOBILE_STARTER.md")).expect("mobile docs");
|
fs::read_to_string(destination.join("MOBILE_STARTER.md")).expect("mobile docs");
|
||||||
let command = fs::read_to_string(destination.join("hemx-workout")).expect("command");
|
let command = fs::read_to_string(destination.join("hemx-app")).expect("command");
|
||||||
let lib_rs = fs::read_to_string(destination.join("src/lib.rs")).expect("lib rs");
|
let lib_rs = fs::read_to_string(destination.join("src/lib.rs")).expect("lib rs");
|
||||||
let template =
|
let template =
|
||||||
fs::read_to_string(destination.join("templates/workout.heml")).expect("template");
|
fs::read_to_string(destination.join("templates/workout.heml")).expect("template");
|
||||||
|
|
||||||
assert!(mobile_readme.contains("phone-first Workout path"));
|
assert!(mobile_readme.contains("phone-first path"));
|
||||||
assert!(mobile_readme.contains("typed host haptics/share calls"));
|
assert!(mobile_readme.contains("typed host haptics/share calls"));
|
||||||
assert!(mobile_readme.contains("command/event/projection recovery truth"));
|
assert!(mobile_readme.contains("command/event/projection recovery truth"));
|
||||||
|
assert!(mobile_readme.contains("app-owned `hemx-app mobile-release`"));
|
||||||
assert!(mobile_readme.contains("does not add a hemx mobile framework"));
|
assert!(mobile_readme.contains("does not add a hemx mobile framework"));
|
||||||
assert!(command.contains("mobile-release"));
|
assert!(command.contains("mobile-release"));
|
||||||
assert!(command.contains("mobile-verify"));
|
assert!(command.contains("mobile-verify"));
|
||||||
|
assert!(command.contains("HEMX_APP_ORIGIN"));
|
||||||
|
assert!(command.contains("target/hemx-mobile/app"));
|
||||||
|
assert!(!command.contains("HEMX_WORKOUT_"));
|
||||||
assert!(command.contains("app-owned command/event/projection records"));
|
assert!(command.contains("app-owned command/event/projection records"));
|
||||||
assert!(command.contains("external_blockers"));
|
assert!(command.contains("external_blockers"));
|
||||||
assert!(lib_rs.contains("HostCall::Share"));
|
assert!(lib_rs.contains("HostCall::Share"));
|
||||||
@@ -1269,6 +1295,8 @@ mod tests {
|
|||||||
assert!(template.contains("<form"));
|
assert!(template.contains("<form"));
|
||||||
assert!(template.contains("data-hemx-slot"));
|
assert!(template.contains("data-hemx-slot"));
|
||||||
assert!(destination.join("tests/e2e.rs").exists());
|
assert!(destination.join("tests/e2e.rs").exists());
|
||||||
|
assert!(destination.join("hemx-app").exists());
|
||||||
|
assert!(!destination.join("hemx-workout").exists());
|
||||||
let _ = fs::remove_dir_all(&destination);
|
let _ = fs::remove_dir_all(&destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user