Skip to main content

cargo_leptos/command/
end2end.rs

1use 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}