cargo_leptos/command/
end2end.rs1use std::sync::Arc;
2
3use camino::Utf8Path;
4use tokio::process::Command;
5
6use crate::config::{Config, Project};
7use crate::internal_prelude::*;
8use crate::service::serve;
9use crate::signal::Interrupt;
10
11pub async fn end2end_all(conf: &Config) -> Result<()> {
12 for proj in &conf.projects {
13 end2end_proj(proj).await?;
14 }
15 Ok(())
16}
17
18pub async fn end2end_proj(proj: &Arc<Project>) -> Result<()> {
19 if let Some(e2e) = &proj.end2end {
20 if !super::build::build_proj(proj).await.dot()? {
21 return Ok(());
22 }
23
24 let server = serve::spawn(proj).await;
25 try_run(&e2e.cmd, &e2e.dir)
26 .await
27 .wrap_err(format!("running: {}", &e2e.cmd))?;
28 Interrupt::request_shutdown().await;
29 server.await.dot()??;
30 } else {
31 info!("end2end the Crate.toml package.metadata.leptos.end2end-cmd parameter not set")
32 }
33 Ok(())
34}
35
36async fn try_run(cmd: &str, dir: &Utf8Path) -> Result<()> {
37 let mut parts = cmd.split(' ');
38 let exe = parts
39 .next()
40 .ok_or_else(|| eyre!("Invalid command {cmd:?}"))?;
41
42 let args = parts.collect::<Vec<_>>();
43
44 trace!("End2End running {cmd:?}");
45 let mut process = Command::new(which::which(exe)?)
46 .args(args)
47 .current_dir(dir)
48 .spawn()
49 .wrap_err(format!("Could not spawn command {cmd:?}"))?;
50
51 let mut int = Interrupt::subscribe_any();
52
53 tokio::select! {
54 _ = int.recv() => Ok(()),
55 result = process.wait() => {
56 let status = result?;
57 if !status.success() {
58 bail!("Command terminated with exit code {}", status)
59 }
60 Ok(())
61 }
62 }
63}