diff --git a/Cargo.lock b/Cargo.lock index 6235fbf4f8..050c70a0f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1697,16 +1697,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "file-lock" -version = "2.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "040b48f80a749da50292d0f47a1e2d5bf1d772f52836c07f64bfccc62ba6e664" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "filetime" version = "0.2.25" @@ -1780,6 +1770,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -2999,8 +2999,8 @@ dependencies = [ "criterion", "dap", "dirs", - "file-lock", "fm", + "fs2", "fxhash", "iai", "iter-extended", diff --git a/Cargo.toml b/Cargo.toml index 8d48a84645..567f1db085 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,8 +83,6 @@ noir_lsp = { path = "tooling/lsp" } noir_debugger = { path = "tooling/debugger" } noirc_abi = { path = "tooling/noirc_abi" } noirc_artifacts = { path = "tooling/noirc_artifacts" } -bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" } -acvm_cli = { path = "tooling/acvm_cli" } # Arkworks ark-bn254 = { version = "^0.5.0", default-features = false, features = [ diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index 742c397a0d..001306bb16 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -75,6 +75,7 @@ tracing.workspace = true tracing-subscriber.workspace = true tracing-appender = "0.2.3" clap_complete = "4.5.36" +fs2 = "0.4.3" [target.'cfg(not(unix))'.dependencies] tokio-util = { version = "0.7.8", features = ["compat"] } @@ -86,7 +87,6 @@ dirs.workspace = true assert_cmd = "2.0.8" assert_fs = "1.0.10" predicates = "2.1.5" -file-lock = "2.1.11" fm.workspace = true criterion.workspace = true pprof.workspace = true @@ -102,7 +102,7 @@ light-poseidon = "0.2.0" ark-bn254-v04 = { package = "ark-bn254", version = "^0.4.0", default-features = false, features = [ "curve", ] } -ark-ff-v04 = { package = "ark-ff", version = "^0.4.0", default-features = false } +ark-ff-v04 = { package = "ark-ff", version = "^0.4.0", default-features = false } [[bench]] name = "criterion" diff --git a/tooling/nargo_cli/build.rs b/tooling/nargo_cli/build.rs index d041cf3e53..04cc463f6b 100644 --- a/tooling/nargo_cli/build.rs +++ b/tooling/nargo_cli/build.rs @@ -177,33 +177,13 @@ fn generate_test_cases( } let test_cases = test_cases.join("\n"); - // We need to isolate test cases in the same group, otherwise they overwrite each other's artifacts. - // On CI we use `cargo nextest`, which runs tests in different processes; for this we use a file lock. - // Locally we might be using `cargo test`, which run tests in the same process; in this case the file lock - // wouldn't work, becuase the process itself has the lock, and it looks like it can have N instances without - // any problems; for this reason we also use a `Mutex`. - let mutex_name = format! {"TEST_MUTEX_{}", test_name.to_uppercase()}; write!( test_file, r#" -lazy_static::lazy_static! {{ - /// Prevent concurrent tests in the matrix from overwriting the compilation artifacts in {test_dir} - static ref {mutex_name}: std::sync::Mutex<()> = std::sync::Mutex::new(()); -}} - {test_cases} fn test_{test_name}(force_brillig: ForceBrillig, inliner_aggressiveness: Inliner) {{ let test_program_dir = PathBuf::from("{test_dir}"); - // Ignore poisoning errors if some of the matrix cases failed. - let mutex_guard = {mutex_name}.lock().unwrap_or_else(|e| e.into_inner()); - - let file_guard = file_lock::FileLock::lock( - test_program_dir.join("Nargo.toml"), - true, - file_lock::FileOptions::new().read(true).write(true).append(true) - ).expect("failed to lock Nargo.toml"); - let mut nargo = Command::cargo_bin("nargo").unwrap(); nargo.arg("--program-dir").arg(test_program_dir); nargo.arg("{test_command}").arg("--force"); @@ -221,9 +201,6 @@ fn test_{test_name}(force_brillig: ForceBrillig, inliner_aggressiveness: Inliner }} {test_content} - - drop(file_guard); - drop(mutex_guard); }} "# ) diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index 43e3de9c6d..0b725afcf4 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -118,6 +118,11 @@ enum NargoCommand { #[cfg(not(feature = "codegen-docs"))] #[tracing::instrument(level = "trace")] pub(crate) fn start_cli() -> eyre::Result<()> { + use std::fs::File; + + use fs2::FileExt as _; + use nargo_toml::get_package_manifest; + let NargoCli { command, mut config } = NargoCli::parse(); // If the provided `program_dir` is relative, make it absolute by joining it to the current directory. @@ -130,6 +135,28 @@ pub(crate) fn start_cli() -> eyre::Result<()> { config.program_dir = program_dir; } + let lock_file = match needs_lock(&command) { + Some(exclusive) => { + let toml_path = get_package_manifest(&config.program_dir)?; + let file = File::open(toml_path).expect("Expected Nargo.toml to exist"); + if exclusive { + if file.try_lock_exclusive().is_err() { + eprintln!("Waiting for lock on Nargo.toml..."); + } + + file.lock_exclusive().expect("Failed to lock Nargo.toml"); + } else { + if file.try_lock_shared().is_err() { + eprintln!("Waiting for lock on Nargo.toml..."); + } + + file.lock_shared().expect("Failed to lock Nargo.toml"); + } + Some(file) + } + None => None, + }; + match command { NargoCommand::New(args) => new_cmd::run(args, config), NargoCommand::Init(args) => init_cmd::run(args, config), @@ -146,6 +173,10 @@ pub(crate) fn start_cli() -> eyre::Result<()> { NargoCommand::GenerateCompletionScript(args) => generate_completion_script_cmd::run(args), }?; + if let Some(lock_file) = lock_file { + lock_file.unlock().expect("Failed to unlock Nargo.toml"); + } + Ok(()) } @@ -193,6 +224,23 @@ fn command_dir(cmd: &NargoCommand, program_dir: &Path) -> Result Ok(Some(nargo_toml::find_root(program_dir, workspace)?)) } +fn needs_lock(cmd: &NargoCommand) -> Option { + match cmd { + NargoCommand::Check(..) + | NargoCommand::Compile(..) + | NargoCommand::Execute(..) + | NargoCommand::Export(..) + | NargoCommand::Info(..) => Some(true), + NargoCommand::Debug(..) | NargoCommand::Test(..) => Some(false), + NargoCommand::Fmt(..) + | NargoCommand::New(..) + | NargoCommand::Init(..) + | NargoCommand::Lsp(..) + | NargoCommand::Dap(..) + | NargoCommand::GenerateCompletionScript(..) => None, + } +} + #[cfg(test)] mod tests { use clap::Parser;