From 9df7503e4d329131c1bad18d4b9c7a84804580a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dj8yf0=CE=BCl?= Date: Fri, 13 Dec 2024 23:57:27 +0200 Subject: [PATCH] fix: running `compile_project` concurrently in tests --- cargo-near-build/src/fs.rs | 34 +++++++++++++++- cargo-near-build/src/near/build/mod.rs | 56 ++++++++++++++++++++------ 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/cargo-near-build/src/fs.rs b/cargo-near-build/src/fs.rs index 87a111f6..fb32d5e3 100644 --- a/cargo-near-build/src/fs.rs +++ b/cargo-near-build/src/fs.rs @@ -4,8 +4,12 @@ use eyre::WrapErr; /// Copy a file to a destination. /// /// Does nothing if the destination is the same as the source to avoid truncating the file. -pub fn copy(from: &Utf8Path, to: &Utf8Path) -> eyre::Result { - let out_path = to.join(from.file_name().unwrap()); +pub fn copy(from: &Utf8Path, out_dir: &Utf8Path) -> eyre::Result { + if !out_dir.is_dir() { + return Err(eyre::eyre!("`{}` should be a directory", out_dir)); + } + let out_path = out_dir.join(from.file_name().unwrap()); + tracing::debug!("Copying file `{}` -> `{}`", from, out_path,); if from != out_path { std::fs::copy(from, &out_path) .wrap_err_with(|| format!("failed to copy `{}` to `{}`", from, out_path))?; @@ -13,6 +17,32 @@ pub fn copy(from: &Utf8Path, to: &Utf8Path) -> eyre::Result { Ok(out_path) } +/// Copy a file to a file destination. +/// +/// Does nothing if the destination is the same as the source to avoid truncating the file. +pub fn copy_to_file(from: &Utf8Path, to: &Utf8Path) -> eyre::Result { + tracing::debug!("Copying file `{}` -> `{}`", from, to,); + + if from != to && to.is_file() { + let from_content = std::fs::read(from)?; + let to_content = std::fs::read(to)?; + + if from_content == to_content { + tracing::debug!( + "skipped copying file `{}` -> `{}` on identical contents", + from, + to, + ); + return Ok(to.to_path_buf()); + } + } + if from != to { + std::fs::copy(from, to) + .wrap_err_with(|| format!("failed to copy `{}` to `{}`", from, to))?; + } + Ok(to.to_path_buf()) +} + /// Create the directory if it doesn't exist, and return the absolute path to it. pub fn force_canonicalize_dir(dir: &Utf8Path) -> eyre::Result { std::fs::create_dir_all(dir) diff --git a/cargo-near-build/src/near/build/mod.rs b/cargo-near-build/src/near/build/mod.rs index 585671d4..e46934dd 100644 --- a/cargo-near-build/src/near/build/mod.rs +++ b/cargo-near-build/src/near/build/mod.rs @@ -4,6 +4,7 @@ use crate::types::near::build::buildtime_env; use camino::Utf8PathBuf; use colored::Colorize; use near_abi::BuildInfo; +use tempfile::NamedTempFile; use crate::types::near::build::output::CompilationArtifact; use crate::types::near::build::side_effects::ArtifactMessages; @@ -162,19 +163,14 @@ pub fn run(args: Opts) -> eyre::Result { color, )?; - wasm_artifact.path = crate::fs::copy(&wasm_artifact.path, &out_dir)?; - - if !args.no_wasmopt { - println!(); - pretty_print::handle_step( - "Running an optimize for size post-step with wasm-opt...", - || { - wasm_opt::OptimizationOptions::new_optimize_for_size() - .run(&wasm_artifact.path, &wasm_artifact.path)?; - Ok(()) - }, - )?; - } + wasm_artifact.path = { + let (from_path, _maybe_tmpfile) = + maybe_wasm_opt_step(&wasm_artifact.path, args.no_wasmopt)?; + crate::fs::copy_to_file( + &from_path, + &out_dir.join(wasm_artifact.path.file_name().expect("has filename")), + )? + }; wasm_artifact.builder_version_info = Some(builder_version_info); @@ -206,3 +202,37 @@ pub fn run(args: Opts) -> eyre::Result { pretty_print::duration(start, "cargo near build"); Ok(wasm_artifact) } + +fn maybe_wasm_opt_step( + input_path: &Utf8PathBuf, + no_wasmopt: bool, +) -> eyre::Result<(Utf8PathBuf, Option)> { + let result = if !no_wasmopt { + let opt_destination = tempfile::Builder::new() + .prefix("optimized-") + .suffix(".wasm") + .tempfile()?; + println!(); + pretty_print::handle_step( + "Running an optimize for size post-step with wasm-opt...", + || { + println!( + "{} -> {}", + format!("{}", input_path).cyan(), + format!("{}", opt_destination.path().to_string_lossy()).cyan() + ); + wasm_opt::OptimizationOptions::new_optimize_for_size() + .run(input_path, &opt_destination.path())?; + Ok(()) + }, + )?; + + ( + Utf8PathBuf::try_from(opt_destination.path().to_path_buf())?, + Some(opt_destination), + ) + } else { + (input_path.clone(), None) + }; + Ok(result) +}