diff --git a/src/command/test.rs b/src/command/test.rs index adef1a48..0212988b 100644 --- a/src/command/test.rs +++ b/src/command/test.rs @@ -1,14 +1,15 @@ -use crate::compile::{front_cargo_process, server_cargo_process}; -use crate::config::{Config, Project}; +use crate::compile::{front_cargo_process_with_args, server_cargo_process_with_args}; +use crate::config::{Config, Project, TestSpecificOpts}; use crate::ext::Paint; use crate::internal_prelude::*; use crate::logger::GRAY; -pub async fn test_all(conf: &Config) -> Result<()> { +pub async fn test_all(conf: &Config, test_opts: &TestSpecificOpts) -> Result<()> { let mut first_failed_project = None; + let add_args = test_opts.to_args(); for proj in &conf.projects { - if !test_proj(proj).await? && first_failed_project.is_none() { + if !test_proj(proj, Some(&add_args)).await? && first_failed_project.is_none() { first_failed_project = Some(proj); } } @@ -20,14 +21,16 @@ pub async fn test_all(conf: &Config) -> Result<()> { } } -pub async fn test_proj(proj: &Project) -> Result { - let (envs, line, mut proc) = server_cargo_process("test", proj).dot()?; +pub async fn test_proj(proj: &Project, additional_args: Option<&[String]>) -> Result { + let (envs, line, mut proc) = + server_cargo_process_with_args("test", proj, additional_args).dot()?; let server_exit_status = proc.wait().await.dot()?; debug!("Cargo envs: {}", GRAY.paint(envs)); info!("Cargo server tests finished {}", GRAY.paint(line)); - let (envs, line, mut proc) = front_cargo_process("test", false, proj).dot()?; + let (envs, line, mut proc) = + front_cargo_process_with_args("test", false, proj, additional_args).dot()?; let front_exit_status = proc.wait().await.dot()?; debug!("Cargo envs: {}", GRAY.paint(envs)); diff --git a/src/compile/front.rs b/src/compile/front.rs index b18398f3..f4591a00 100644 --- a/src/compile/front.rs +++ b/src/compile/front.rs @@ -75,9 +75,18 @@ pub fn front_cargo_process( cmd: &str, wasm: bool, proj: &Project, +) -> Result<(String, String, Child)> { + front_cargo_process_with_args(cmd, wasm, proj, None) +} + +pub fn front_cargo_process_with_args( + cmd: &str, + wasm: bool, + proj: &Project, + additional_args: Option<&[String]>, ) -> Result<(String, String, Child)> { let mut command = Command::new("cargo"); - let (envs, line) = build_cargo_front_cmd(cmd, wasm, proj, &mut command); + let (envs, line) = build_cargo_front_cmd(cmd, wasm, proj, &mut command, additional_args); Ok((envs, line, command.spawn()?)) } @@ -86,6 +95,7 @@ pub fn build_cargo_front_cmd( wasm: bool, proj: &Project, command: &mut Command, + additional_args: Option<&[String]>, ) -> (String, String) { let mut args = vec![ cmd.to_string(), @@ -113,6 +123,10 @@ pub fn build_cargo_front_cmd( proj.lib.profile.add_to_args(&mut args); + if let Some(add_args) = additional_args { + args.extend_from_slice(add_args); + } + let envs = proj.to_envs(wasm); let envs_str = envs @@ -190,9 +204,7 @@ async fn bindgen(proj: &Project, all_wasm_files: &[Utf8PathBuf]) -> Result { - Ok(Outcome::Stopped) - }, + CommandResult::Interrupted => Ok(Outcome::Stopped), CommandResult::Failure(output) => { error!("wasm-bindgen failed with:"); println!("{}", output.stderr()); diff --git a/src/compile/mod.rs b/src/compile/mod.rs index b7f6d08a..ae1aeb3c 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -12,9 +12,9 @@ mod tailwind; pub use assets::assets; pub use change::{Change, ChangeSet}; -pub use front::{front, front_cargo_process}; +pub use front::{front, front_cargo_process, front_cargo_process_with_args}; pub use hash::add_hashes_to_site; -pub use server::{server, server_cargo_process}; +pub use server::{server, server_cargo_process, server_cargo_process_with_args}; pub use style::style; use itertools::Itertools; diff --git a/src/compile/server.rs b/src/compile/server.rs index 1b82a43e..acf1dd39 100644 --- a/src/compile/server.rs +++ b/src/compile/server.rs @@ -53,6 +53,14 @@ pub async fn server( } pub fn server_cargo_process(cmd: &str, proj: &Project) -> Result<(String, String, Child)> { + server_cargo_process_with_args(cmd, proj, None) +} + +pub fn server_cargo_process_with_args( + cmd: &str, + proj: &Project, + additional_args: Option<&[String]>, +) -> Result<(String, String, Child)> { let raw_command = proj.bin.cargo_command.as_deref().unwrap_or("cargo"); let mut command_iter = Shlex::new(raw_command); @@ -68,7 +76,7 @@ pub fn server_cargo_process(cmd: &str, proj: &Project) -> Result<(String, String let args: Vec = command_iter.collect(); command.args(args); - let (envs, line) = build_cargo_server_cmd(cmd, proj, &mut command); + let (envs, line) = build_cargo_server_cmd(cmd, proj, &mut command, additional_args); Ok((envs, line, command.spawn()?)) } @@ -76,6 +84,7 @@ pub fn build_cargo_server_cmd( cmd: &str, proj: &Project, command: &mut Command, + additional_args: Option<&[String]>, ) -> (String, String) { let mut args = vec![ cmd.to_string(), @@ -116,6 +125,10 @@ pub fn build_cargo_server_cmd( } proj.bin.profile.add_to_args(&mut args); + if let Some(add_args) = additional_args { + args.extend_from_slice(add_args); + } + let envs = proj.to_envs(false); let envs_str = envs diff --git a/src/compile/tests.rs b/src/compile/tests.rs index 139f4006..31476e29 100644 --- a/src/compile/tests.rs +++ b/src/compile/tests.rs @@ -2,7 +2,6 @@ use crate::{ compile::front::build_cargo_front_cmd, config::{Config, Opts}, }; -use insta::assert_snapshot; use tokio::process::Command; use super::server::build_cargo_server_cmd; @@ -54,7 +53,7 @@ fn test_project_dev() { let conf = Config::test_load(cli, "examples", "examples/project/Cargo.toml", true, None); let mut command = Command::new("cargo"); - let (envs, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command); + let (envs, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command, None); const ENV_REF: &str = "\ LEPTOS_OUTPUT_NAME=example \ @@ -74,10 +73,13 @@ fn test_project_dev() { RUSTFLAGS=--cfg erase_components"; assert_eq!(ENV_REF, envs); - assert_snapshot!(cargo, @"cargo build --package=example --bin=example --no-default-features --features=ssr"); + assert_eq!( + cargo, + "cargo build --package=example --bin=example --no-default-features --features=ssr" + ); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command); + let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command, None); assert!(cargo.starts_with("cargo build --package=example --lib --target-dir=")); // what's in the middle will vary by platform and cwd @@ -92,12 +94,12 @@ fn test_project_release() { let conf = Config::test_load(cli, "examples", "examples/project/Cargo.toml", true, None); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command); + let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command, None); - assert_snapshot!(cargo, @"cargo build --package=example --bin=example --no-default-features --features=ssr --release"); + assert_eq!(cargo, "cargo build --package=example --bin=example --no-default-features --features=ssr --release"); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command); + let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command, None); assert!(cargo.starts_with("cargo build --package=example --lib --target-dir=")); // what's in the middle will vary by platform and cwd @@ -146,14 +148,17 @@ fn test_workspace_project1() { let conf = Config::test_load(cli, "examples", "examples/workspace/Cargo.toml", true, None); let mut command = Command::new("cargo"); - let (envs, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command); + let (envs, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command, None); assert_eq!(ENV_REF, envs); - assert_snapshot!(cargo, @"cargo build --package=server-package --bin=server-package --no-default-features"); + assert_eq!( + cargo, + "cargo build --package=server-package --bin=server-package --no-default-features" + ); let mut command = Command::new("cargo"); - let (envs, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command); + let (envs, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command, None); assert_eq!(ENV_REF, envs); @@ -168,12 +173,15 @@ fn test_workspace_project2() { let conf = Config::test_load(cli, "examples", "examples/workspace/Cargo.toml", true, None); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[1], &mut command); + let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[1], &mut command, None); - assert_snapshot!(cargo, @"cargo build --package=project2 --bin=project2 --no-default-features --features=ssr"); + assert_eq!( + cargo, + "cargo build --package=project2 --bin=project2 --no-default-features --features=ssr" + ); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[1], &mut command); + let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[1], &mut command, None); assert!(cargo.starts_with("cargo build --package=project2 --lib --target-dir=")); // what's in the middle will vary by platform and cwd @@ -192,12 +200,15 @@ fn test_extra_cargo_args() { let conf = Config::test_load(cli, "examples", "examples/project/Cargo.toml", true, None); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command); + let (_, cargo) = build_cargo_server_cmd("build", &conf.projects[0], &mut command, None); - assert_snapshot!(cargo, @"cargo build --package=example --bin=example --no-default-features --features=ssr -j 16"); + assert_eq!( + cargo, + "cargo build --package=example --bin=example --no-default-features --features=ssr -j 16" + ); let mut command = Command::new("cargo"); - let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command); + let (_, cargo) = build_cargo_front_cmd("build", true, &conf.projects[0], &mut command, None); assert!(cargo.starts_with("cargo build --package=example --lib --target-dir=")); // what's in the middle will vary by platform and cwd @@ -205,3 +216,37 @@ fn test_extra_cargo_args() { "--target=wasm32-unknown-unknown --no-default-features --features=hydrate -j 8" )); } + +#[test] +fn test_extra_build_args() { + let cli = dev_opts(); + let conf = Config::test_load(cli, "examples", "examples/project/Cargo.toml", true, None); + + let mut command = Command::new("cargo"); + let additional_args = vec!["--no-run".to_string()]; + let (_, cargo) = build_cargo_server_cmd( + "test", + &conf.projects[0], + &mut command, + Some(&additional_args), + ); + + assert_eq!( + cargo, + "cargo test --package=example --no-default-features --features=ssr --no-run" + ); + + let mut command = Command::new("cargo"); + let (_, cargo) = build_cargo_front_cmd( + "build", + true, + &conf.projects[0], + &mut command, + Some(&additional_args), + ); + assert!(cargo.starts_with("cargo build --package=example --lib --target-dir=")); + // what's in the middle will vary by platform and cwd + assert!(cargo.ends_with( + "--target=wasm32-unknown-unknown --no-default-features --features=hydrate --no-run" + )); +} diff --git a/src/config/cli.rs b/src/config/cli.rs index 5ce54ffc..0de250d7 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -87,6 +87,32 @@ pub struct BinOpts { bin_args: Vec, } +#[derive(Debug, Clone, Parser, PartialEq, Default)] +pub struct TestSpecificOpts { + /// Do not run the tests, only build them. + #[arg(long)] + pub no_run: bool, +} + +impl TestSpecificOpts { + pub fn to_args(&self) -> Vec { + let mut args = Vec::new(); + if self.no_run { + args.push("--no-run".to_string()); + } + args + } +} + +#[derive(Debug, Clone, Parser, PartialEq, Default)] +pub struct TestOpts { + #[command(flatten)] + opts: Opts, + + #[command(flatten, next_help_heading = "Test-specific Options")] + pub opts_specific: TestSpecificOpts, +} + #[derive(Debug, Parser)] #[clap(version)] pub struct Cli { @@ -107,9 +133,8 @@ impl Cli { match &self.command { Commands::New(_) => None, Commands::Serve(bin_opts) | Commands::Watch(bin_opts) => Some(bin_opts.opts.clone()), - Commands::Build(opts) | Commands::Test(opts) | Commands::EndToEnd(opts) => { - Some(opts.clone()) - } + Commands::Test(test_opts) => Some(test_opts.opts.clone()), + Commands::Build(opts) | Commands::EndToEnd(opts) => Some(opts.clone()), _ => None, } } @@ -118,7 +143,8 @@ impl Cli { match &mut self.command { Commands::New(_) => None, Commands::Serve(bin_opts) | Commands::Watch(bin_opts) => Some(&mut bin_opts.opts), - Commands::Build(opts) | Commands::Test(opts) | Commands::EndToEnd(opts) => Some(opts), + Commands::Test(test_opts) => Some(&mut test_opts.opts), + Commands::Build(opts) | Commands::EndToEnd(opts) => Some(opts), _ => None, } } @@ -138,7 +164,7 @@ pub enum Commands { /// Build the server (feature ssr) and the client (wasm with feature hydrate). Build(Opts), /// Run the cargo tests for app, client and server. - Test(Opts), + Test(TestOpts), /// Start the server and end-2-end tests. EndToEnd(Opts), /// Serve. Defaults to hydrate mode. diff --git a/src/config/mod.rs b/src/config/mod.rs index f6f814de..a3a5dea3 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -16,7 +16,7 @@ mod version; use std::{fmt::Debug, sync::Arc}; -pub use self::cli::{Cli, Commands, Log, Opts}; +pub use self::cli::{Cli, Commands, Log, Opts, TestSpecificOpts}; use crate::ext::MetadataExt; use crate::internal_prelude::*; use camino::{Utf8Path, Utf8PathBuf}; diff --git a/src/lib.rs b/src/lib.rs index cdf75c99..5f9b6520 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,7 @@ pub async fn run(args: Cli) -> Result<()> { match args.command { Build(_) => command::build_all(&config).await, Serve(_) => command::serve(&config.current_project()?).await, - Test(_) => command::test_all(&config).await, + Test(opts) => command::test_all(&config, &opts.opts_specific).await, EndToEnd(_) => command::end2end_all(&config).await, Watch(_) => command::watch(&config.current_project()?).await, New(_) => unreachable!(r#""new" command should have already been run"#),