// Desktop and web launch flows for `moui run`. Native desktop targets are
// built (unless --no-build) and launched as child processes with the parent
// environment; the web target delegates to the dev runner, which serves the
// built wasm with refresh and error overlays. Mobile run pipelines are
// untouched.
///|
fn run_run_desktop(
parsed : ParsedRun,
cwd : String,
host : HostPlatform,
) -> CliOutcome {
guard parsed.options is Some(options) else {
return failed_outcome(
"run command options are unavailable",
parsed.json,
run_usage(),
)
}
let flow = match
resolve_desktop_flow(
cwd,
parsed.app,
parsed.platform,
renderer=options.renderer.unwrap_or("auto"),
) {
Ok(value) => value
Err(message) => return failed_outcome(message, parsed.json, run_usage())
}
if parsed.platform == "web" {
return run_run_desktop_web(parsed, flow)
}
if options.prepare_only || options.build_only {
let artifact = match desktop_build_once(flow, host) {
Ok(value) => value
Err(message) => return failed_outcome(message, parsed.json, run_usage())
}
return stdout_outcome(
"[run] " +
parsed.platform +
" app=" +
parsed.app +
"\n artifact: " +
artifact +
"\n status: build-only\n",
)
}
let artifact = if options.no_build {
desktop_artifact_path(
flow.build_base,
flow.package_path,
flow.target.target,
)
} else {
match desktop_build_once(flow, host) {
Ok(value) => value
Err(message) => return failed_outcome(message, parsed.json, run_usage())
}
}
if !path_is_file(artifact) {
return failed_outcome(
"build artifact not found: " +
artifact +
" (remove --no-build or build first with `moui build " +
parsed.platform +
" " +
parsed.app +
"`)",
parsed.json,
run_usage(),
)
}
if options.verify {
return failed_outcome(
"--verify is only available for mobile platforms (android / ios / harmonyos)",
parsed.json,
run_usage(),
)
}
let argv = [artifact]
for argument in options.custom_args {
argv.push(argument)
}
// The child inherits the parent environment: desktop runtime does not
// need the MSVC toolchain, and user shell settings (renderer overrides,
// font dirs) flow through.
let result = match process_exec_argv(argv, cwd=flow.app_root, capture=false) {
Ok(value) => value
Err(message) => return failed_outcome(message, parsed.json, run_usage())
}
if parsed.json {
let value : Json = {
"schemaVersion": 1,
"ok": result.exit_code == 0,
"command": "run",
"platform": parsed.platform,
"app": parsed.app,
"artifact": artifact,
"exitCode": result.exit_code,
}
if result.exit_code == 0 {
stdout_outcome(value.stringify(indent=2) + "\n")
} else {
{
exit_code: result.exit_code,
stdout: value.stringify(indent=2) + "\n",
stderr: "",
}
}
} else {
let mut text = "[run] " + parsed.platform + " app=" + parsed.app + "\n"
text += " artifact: " + artifact + "\n"
text += " exit_code: " + result.exit_code.to_string() + "\n"
if result.exit_code == 0 {
stdout_outcome(text)
} else {
{ exit_code: result.exit_code, stdout: text, stderr: "", }
}
}
}
///|
/// `moui run web ` delegates to the dev runner: the web target is a
/// serve-and-refresh loop rather than a single process launch.
fn run_run_desktop_web(parsed : ParsedRun, flow : DesktopFlow) -> CliOutcome {
guard parsed.options is Some(options) else {
return failed_outcome(
"run command options are unavailable",
parsed.json,
run_usage(),
)
}
let parsed_dev : ParsedDev = {
help: false,
json: parsed.json,
project_root: flow.app_root,
runner: None,
runner_args: ["--package=" + flow.package_path, "--web", "--target=wasm-gc"],
}
if options.no_build {
parsed_dev.runner_args.push("--once")
}
run_dev(parsed_dev)
}