diff --git a/src/build.rs b/src/build.rs index d42339c..dfc3f02 100644 --- a/src/build.rs +++ b/src/build.rs @@ -124,8 +124,8 @@ impl Builder { }) } - /// Awaits the command runner thread finishing - pub fn await_runner_thread(self) -> Result<(), AppError> { + /// Finishes all builds and returns the targets build + pub fn await_runner_thread(self) -> Result, Result>, AppError> { // Drop the sender // Note: We do this so the runner thread exits mem::drop(self.cmd_tx); @@ -133,7 +133,15 @@ impl Builder { // Then join the thread self.cmd_runner .join() - .map_err(|err| AppError::Other(anyhow::anyhow!("Unable to join command runner thread: {err:?}"))) + .map_err(|err| AppError::Other(anyhow::anyhow!("Unable to join command runner thread: {err:?}")))?; + + let targets = self + .rules_lock + .into_iter() + .flat_map(|(_, lock)| lock.into_res()) + .collect(); + + Ok(targets) } /// Sends an event, if any are subscribers @@ -153,21 +161,6 @@ impl Builder { self.event_tx.new_receiver() } - /// Returns all targets built. - /// - /// Waits for targets being built - pub async fn targets(&self) -> HashMap, Result> { - self.rules_lock - .iter() - .map(async move |entry| entry.value().all_res().await) - .collect::>() - .collect::>() - .await - .into_iter() - .flatten() - .collect() - } - /// Finds a target's rule fn target_rule( &self, diff --git a/src/build/lock.rs b/src/build/lock.rs index abf23d5..cc282d3 100644 --- a/src/build/lock.rs +++ b/src/build/lock.rs @@ -55,16 +55,15 @@ impl BuildLock { } } - /// Retrieves all targets' result - /// - /// Waits for any builders to finish - pub async fn all_res(&self) -> Vec<(Target, Result)> { - self.state - .read() - .await + /// Retrieves all targets' result by consuming the lock + pub fn into_res(self) -> Vec<(Target, Result)> { + // TODO: Not panic here + Arc::try_unwrap(self.state) + .expect("Leftover references when unwrapping build lock") + .into_inner() .targets_res - .iter() - .map(|(target, res)| (target.clone(), res.clone().map_err(AppError::Shared))) + .into_iter() + .map(|(target, build)| (target, build.map_err(AppError::Shared))) .collect() } } diff --git a/src/main.rs b/src/main.rs index 15fc616..51d9f34 100644 --- a/src/main.rs +++ b/src/main.rs @@ -81,8 +81,8 @@ use { self::{ast::Ast, build::Builder, error::AppError, expand::Expander, rules::Rules}, args::Args, clap::StructOpt, - futures::{stream::FuturesUnordered, TryStreamExt}, - std::{collections::HashMap, env, path::PathBuf}, + futures::{stream::FuturesUnordered, StreamExt}, + std::{collections::HashMap, env, path::PathBuf, time::SystemTime}, tokio::fs, watcher::Watcher, }; @@ -171,21 +171,32 @@ async fn main() -> Result<(), anyhow::Error> { .transpose()?; // Finally build all targets + let build_start_time = SystemTime::now(); targets_to_build .iter() .map(|target| { let builder = &builder; let rules = &rules; async move { - builder + let res = builder .build_expr(target, rules, args.ignore_missing) .await - .map_err(AppError::build_target(target)) + .map_err(AppError::build_target(target)); + (target, res) } }) .collect::>() - .try_collect::>() - .await?; + .for_each(async move |(target, res)| match res { + Ok((build_res, _)) => { + let build_duration = build_res + .build_time + .duration_since(build_start_time) + .expect("Build time was negative"); + tracing::info!("Built {target} in {build_duration:.2?}"); + }, + Err(err) => tracing::error!("Unable to build {target}: {err}"), + }) + .await; // Then, if we have a watcher, watch all the dependencies if let Some(watcher) = watcher { @@ -193,7 +204,8 @@ async fn main() -> Result<(), anyhow::Error> { watcher.watch_rebuild(&builder, &rules, args.ignore_missing).await?; } - let targets = builder.targets().await; + // Finally wait for the runner thread to finish + let targets = builder.await_runner_thread()?; let total_targets = targets.len(); let built_targets = targets .iter() @@ -202,9 +214,6 @@ async fn main() -> Result<(), anyhow::Error> { tracing::info!("Built {built_targets} targets"); tracing::info!("Checked {total_targets} targets"); - // Finally wait for the runner thread to finish - builder.await_runner_thread()?; - Ok(()) }