1use crate::cli;
2use crate::config::{load_config, resolve_session};
3use crate::protocol::{Request, Response};
4
5pub async fn execute(
6 cli_session: Option<&str>,
7 only: Option<&str>,
8 config_path: Option<&str>,
9) -> i32 {
10 let (path, config) = match load_config(config_path) {
11 Ok(c) => c,
12 Err(e) => {
13 eprintln!("error: {}", e);
14 return 1;
15 }
16 };
17
18 let session = resolve_session(cli_session, config.session.as_deref());
19
20 let only_set: Option<Vec<&str>> = only.map(|s| s.split(',').collect());
21
22 let groups = match config.startup_order() {
23 Ok(g) => g,
24 Err(e) => {
25 eprintln!("error: {}", e);
26 return 1;
27 }
28 };
29
30 for group in &groups {
31 for name in group {
32 if let Some(ref only) = only_set {
33 if !only.contains(&name.as_str()) {
34 continue;
35 }
36 }
37
38 let def = &config.processes[name];
39
40 let resolved_cwd = def.cwd.as_ref().map(|c| {
42 let p = std::path::Path::new(c);
43 if p.is_relative() {
44 path.parent()
45 .unwrap_or(std::path::Path::new("."))
46 .join(p)
47 .to_string_lossy()
48 .to_string()
49 } else {
50 c.clone()
51 }
52 });
53
54 let env = if def.env.is_empty() {
56 None
57 } else {
58 Some(def.env.clone())
59 };
60
61 let req = Request::Run {
63 command: def.cmd.clone(),
64 name: Some(name.clone()),
65 cwd: resolved_cwd,
66 env,
67 };
68 match cli::request(session, &req, true).await {
69 Ok(Response::RunOk { name, id, pid }) => {
70 println!("started {} (id: {}, pid: {})", name, id, pid);
71 }
72 Ok(Response::Error { code, message }) => {
73 eprintln!("error starting {}: {}", name, message);
74 return code;
75 }
76 _ => return 1,
77 }
78
79 if let Some(ref ready) = def.ready {
81 let req = Request::Wait {
82 target: name.clone(),
83 until: Some(ready.clone()),
84 regex: false,
85 exit: false,
86 timeout_secs: Some(30),
87 };
88 match cli::request(session, &req, false).await {
89 Ok(Response::WaitMatch { .. }) => println!("{} is ready", name),
90 Ok(Response::WaitTimeout) => {
91 eprintln!("warning: {} did not become ready within 30s", name);
92 }
93 Ok(Response::Error { message, .. }) => {
94 eprintln!("error waiting for {}: {}", name, message);
95 return 1;
96 }
97 _ => {}
98 }
99 }
100 }
101 }
102
103 println!("all processes started");
104 0
105}