Skip to content

Commit b09267f

Browse files
authored
feat(rmp-cli): add devices start command (#154)
1 parent e413bea commit b09267f

4 files changed

Lines changed: 119 additions & 3 deletions

File tree

crates/rmp-cli/src/cli.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,45 @@ pub struct InitArgs {
8686
pub enum DevicesCmd {
8787
/// List devices/simulators/emulators.
8888
List,
89+
90+
/// Start a simulator/emulator target and wait until ready.
91+
Start(DevicesStartArgs),
92+
}
93+
94+
#[derive(clap::Args, Debug)]
95+
pub struct DevicesStartArgs {
96+
#[arg(value_enum)]
97+
pub platform: DeviceStartPlatform,
98+
99+
#[command(flatten)]
100+
pub ios: DevicesStartIosArgs,
101+
102+
#[command(flatten)]
103+
pub android: DevicesStartAndroidArgs,
104+
}
105+
106+
#[derive(ValueEnum, Debug, Clone, Copy)]
107+
pub enum DeviceStartPlatform {
108+
Ios,
109+
Android,
110+
}
111+
112+
#[derive(clap::Args, Debug, Default)]
113+
pub struct DevicesStartIosArgs {
114+
/// iOS simulator UDID to target.
115+
#[arg(long)]
116+
pub udid: Option<String>,
117+
}
118+
119+
#[derive(clap::Args, Debug, Default)]
120+
pub struct DevicesStartAndroidArgs {
121+
/// Android emulator serial to target.
122+
#[arg(long)]
123+
pub serial: Option<String>,
124+
125+
/// Android AVD name to start if no emulator is running.
126+
#[arg(long)]
127+
pub avd: Option<String>,
89128
}
90129

91130
#[derive(clap::Args, Debug)]

crates/rmp-cli/src/devices.rs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use std::process::Command;
33

44
use serde::Serialize;
55

6-
use crate::cli::{human_log, json_print, CliError, JsonOk};
6+
use crate::cli::{human_log, json_print, CliError, DeviceStartPlatform, DevicesStartArgs, JsonOk};
77
use crate::config::load_rmp_toml;
8+
use crate::run::{ensure_android_emulator, ensure_ios_simulator};
89
use crate::util::{discover_xcode_dev_dir, run_capture};
910

1011
#[derive(Serialize)]
@@ -23,6 +24,15 @@ struct DeviceItem {
2324
connection_state: Option<String>, // connected|... (devices)
2425
}
2526

27+
#[derive(Serialize)]
28+
struct DeviceStartJson {
29+
platform: String,
30+
kind: String,
31+
id: String,
32+
#[serde(skip_serializing_if = "Option::is_none")]
33+
avd: Option<String>,
34+
}
35+
2636
#[derive(Debug)]
2737
struct IosDev {
2838
udid: String,
@@ -320,3 +330,67 @@ pub fn devices_list(root: &Path, json: bool, verbose: bool) -> Result<(), CliErr
320330

321331
Ok(())
322332
}
333+
334+
pub fn devices_start(
335+
root: &Path,
336+
json: bool,
337+
verbose: bool,
338+
args: DevicesStartArgs,
339+
) -> Result<(), CliError> {
340+
let cfg = load_rmp_toml(root)?;
341+
match args.platform {
342+
DeviceStartPlatform::Android => {
343+
let android = cfg
344+
.android
345+
.ok_or_else(|| CliError::user("rmp.toml missing [android] section"))?;
346+
let avd = args
347+
.android
348+
.avd
349+
.or(android.avd_name)
350+
.unwrap_or_else(|| "pika_api35".into());
351+
let serial =
352+
ensure_android_emulator(root, &avd, args.android.serial.as_deref(), verbose)?;
353+
354+
if json {
355+
json_print(&JsonOk {
356+
ok: true,
357+
data: DeviceStartJson {
358+
platform: "android".into(),
359+
kind: if serial.starts_with("emulator-") {
360+
"emulator".into()
361+
} else {
362+
"device".into()
363+
},
364+
id: serial,
365+
avd: Some(avd),
366+
},
367+
});
368+
} else {
369+
eprintln!("ok: android target ready");
370+
}
371+
}
372+
DeviceStartPlatform::Ios => {
373+
let _ios = cfg
374+
.ios
375+
.ok_or_else(|| CliError::user("rmp.toml missing [ios] section"))?;
376+
let dev_dir = discover_xcode_dev_dir()?;
377+
let udid = ensure_ios_simulator(&dev_dir, args.ios.udid.as_deref(), verbose)?;
378+
let _ = Command::new("open").arg("-a").arg("Simulator").status();
379+
380+
if json {
381+
json_print(&JsonOk {
382+
ok: true,
383+
data: DeviceStartJson {
384+
platform: "ios".into(),
385+
kind: "simulator".into(),
386+
id: udid,
387+
avd: None,
388+
},
389+
});
390+
} else {
391+
eprintln!("ok: ios simulator ready");
392+
}
393+
}
394+
}
395+
Ok(())
396+
}

crates/rmp-cli/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ fn main() -> ExitCode {
2828
cli::Cmd::Devices {
2929
cmd: cli::DevicesCmd::List,
3030
} => devices::devices_list(&root, args.json, args.verbose),
31+
cli::Cmd::Devices {
32+
cmd: cli::DevicesCmd::Start(s),
33+
} => devices::devices_start(&root, args.json, args.verbose, s),
3134
cli::Cmd::Bindings(b) => bindings::bindings(&root, args.json, args.verbose, b),
3235
cli::Cmd::Run(r) => run::run(&root, args.json, args.verbose, r),
3336
cli::Cmd::Init(_) => unreachable!(),

crates/rmp-cli/src/run.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ fn run_ios(
174174
Ok(())
175175
}
176176

177-
fn ensure_ios_simulator(
177+
pub(crate) fn ensure_ios_simulator(
178178
dev_dir: &Path,
179179
explicit_udid: Option<&str>,
180180
verbose: bool,
@@ -557,7 +557,7 @@ fn run_android(
557557
Ok(())
558558
}
559559

560-
fn ensure_android_emulator(
560+
pub(crate) fn ensure_android_emulator(
561561
root: &Path,
562562
avd: &str,
563563
explicit_serial: Option<&str>,

0 commit comments

Comments
 (0)