diff --git a/src/command/build.rs b/src/command/build.rs index 7eb11a55..9f5cc614 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -11,11 +11,11 @@ use crate::{ }, }; -pub async fn build_all(conf: &Config) -> Result<()> { +pub async fn build_all(conf: &Config, bin_skip: bool) -> Result<()> { let mut first_failed_project = None; for proj in &conf.projects { - if !build_proj(proj).await? && first_failed_project.is_none() { + if !build_proj(proj, bin_skip).await? && first_failed_project.is_none() { first_failed_project = Some(proj); } } @@ -28,7 +28,7 @@ pub async fn build_all(conf: &Config) -> Result<()> { } /// Build the project. Returns true if the build was successful -pub async fn build_proj(proj: &Arc) -> Result { +pub async fn build_proj(proj: &Arc, bin_skip: bool) -> Result { if proj.site.root_dir.exists() { fs::rm_dir_content(&proj.site.root_dir).await.dot()?; } @@ -48,19 +48,21 @@ pub async fn build_proj(proj: &Arc) -> Result { return Ok(false); } - // it is important to do the precompression of the static files before building the - // server to make it possible to include them as assets into the binary itself - if proj.release - && proj.precompress - && compress::compress_static_files(proj.site.root_dir.clone().into()) - .await - .is_err() - { - return Ok(false); - } + if !bin_skip { + // it is important to do the precompression of the static files before building the + // server to make it possible to include them as assets into the binary itself + if proj.release + && proj.precompress + && compress::compress_static_files(proj.site.root_dir.clone().into()) + .await + .is_err() + { + return Ok(false); + } - if !compile::server(proj, &changes).await.await??.is_success() { - return Ok(false); + if !compile::server(proj, &changes).await.await??.is_success() { + return Ok(false); + } } Ok(true) } diff --git a/src/command/end2end.rs b/src/command/end2end.rs index 837584f8..967b5c38 100644 --- a/src/command/end2end.rs +++ b/src/command/end2end.rs @@ -18,7 +18,7 @@ pub async fn end2end_all(conf: &Config) -> Result<()> { pub async fn end2end_proj(proj: &Arc) -> Result<()> { if let Some(e2e) = &proj.end2end { - if !super::build::build_proj(proj).await.dot()? { + if !super::build::build_proj(proj, false).await.dot()? { return Ok(()); } diff --git a/src/command/serve.rs b/src/command/serve.rs index 9a627e25..18f7268d 100644 --- a/src/command/serve.rs +++ b/src/command/serve.rs @@ -5,7 +5,7 @@ use crate::ext::anyhow::{Context, Result}; use crate::service::serve; pub async fn serve(proj: &Arc) -> Result<()> { - if !super::build::build_proj(proj).await.dot()? { + if !super::build::build_proj(proj, false).await.dot()? { return Ok(()); } let server = serve::spawn_oneshot(proj).await; diff --git a/src/command/watch.rs b/src/command/watch.rs index 3db16da7..839a7bb7 100644 --- a/src/command/watch.rs +++ b/src/command/watch.rs @@ -15,7 +15,7 @@ use super::build::build_proj; pub async fn watch(proj: &Arc) -> Result<()> { // even if the build fails, we continue - build_proj(proj).await?; + build_proj(proj, false).await?; // but if ctrl-c is pressed, we stop if Interrupt::is_shutdown_requested().await { diff --git a/src/config/cli.rs b/src/config/cli.rs index 93fb50c0..001c6637 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -53,6 +53,84 @@ pub struct Opts { pub verbose: u8, } +#[derive(Debug, Clone, Parser, PartialEq, Default)] +pub struct BuildOpts { + /// Build artifacts in release mode, with optimizations. + #[arg(short, long)] + pub release: bool, + + /// Precompress static assets with gzip and brotli. Applies to release builds only. + #[arg(short = 'P', long)] + pub precompress: bool, + + /// Turn on partial hot-reloading. Requires rust nightly [beta] + #[arg(long)] + pub hot_reload: bool, + + /// Which project to use, from a list of projects defined in a workspace + #[arg(short, long)] + pub project: Option, + + /// The features to use when compiling all targets + #[arg(long)] + pub features: Vec, + + /// The features to use when compiling the lib target + #[arg(long)] + pub lib_features: Vec, + + /// The cargo flags to pass to cargo when compiling the lib target + #[arg(long)] + pub lib_cargo_args: Option>, + + /// The features to use when compiling the bin target + #[arg(long)] + pub bin_features: Vec, + + /// The cargo flags to pass to cargo when compiling the bin target + #[arg(long)] + pub bin_cargo_args: Option>, + + /// Skip building the bin target + #[arg(long)] + pub bin_skip: bool, + + /// Verbosity (none: info, errors & warnings, -v: verbose, --vv: very verbose). + #[arg(short, action = clap::ArgAction::Count)] + pub verbose: u8, +} + +impl From for Opts { + fn from(value: BuildOpts) -> Self { + let BuildOpts { + release, + precompress, + hot_reload, + project, + features, + lib_features, + lib_cargo_args, + bin_features, + bin_cargo_args, + verbose, + .. + } = value; + + Self { + release, + precompress, + hot_reload, + project, + features, + lib_features, + lib_cargo_args, + bin_features, + bin_cargo_args, + verbose, + } + } +} + #[derive(Debug, Parser)] #[clap(version)] pub struct Cli { @@ -73,9 +151,8 @@ impl Cli { use Commands::{Build, EndToEnd, New, Serve, Test, Watch}; match &self.command { New(_) => None, - Build(opts) | Serve(opts) | Test(opts) | EndToEnd(opts) | Watch(opts) => { - Some(opts.clone()) - } + Build(build_opts) => Some(build_opts.clone().into()), + Serve(opts) | Test(opts) | EndToEnd(opts) | Watch(opts) => Some(opts.clone()), } } } @@ -83,7 +160,7 @@ impl Cli { #[derive(Debug, Subcommand, PartialEq)] pub enum Commands { /// Build the server (feature ssr) and the client (wasm with feature hydrate). - Build(Opts), + Build(BuildOpts), /// Run the cargo tests for app, client and server. Test(Opts), /// Start the server and end-2-end tests. diff --git a/src/config/mod.rs b/src/config/mod.rs index f2c002b8..aaef556c 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -14,7 +14,7 @@ mod tailwind; use std::{fmt::Debug, sync::Arc}; -pub use self::cli::{Cli, Commands, Log, Opts}; +pub use self::cli::{BuildOpts, Cli, Commands, Log, Opts}; use crate::ext::{ anyhow::{Context, Result}, MetadataExt, diff --git a/src/lib.rs b/src/lib.rs index 41683a8d..c9032b3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ mod logger; pub mod service; pub mod signal; -use crate::config::Commands; +use crate::config::{BuildOpts, Commands}; use crate::ext::anyhow::{Context, Result}; use crate::ext::PathBufExt; use crate::logger::GRAY; @@ -72,7 +72,7 @@ pub async fn run(args: Cli) -> Result<()> { use Commands::{Build, EndToEnd, New, Serve, Test, Watch}; match args.command { New(_) => panic!(), - Build(_) => command::build_all(&config).await, + Build(BuildOpts { bin_skip, .. }) => command::build_all(&config, bin_skip).await, Serve(_) => command::serve(&config.current_project()?).await, Test(_) => command::test_all(&config).await, EndToEnd(_) => command::end2end_all(&config).await, diff --git a/src/tests.rs b/src/tests.rs index f6a57db0..fca23c47 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,14 +1,14 @@ use camino::Utf8PathBuf; use crate::{ - config::{Cli, Commands, Opts}, + config::{BuildOpts, Cli, Commands}, ext::PathBufExt, run, }; #[tokio::test] async fn workspace_build() { - let command = Commands::Build(Opts::default()); + let command = Commands::Build(BuildOpts::default()); let cli = Cli { manifest_path: Some(Utf8PathBuf::from("examples/workspace/Cargo.toml")),