From 32c75ab1f5b7b07ecbf44aba25ab344fb27235e8 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 5 Sep 2021 12:19:08 +0200 Subject: [PATCH] fix: cleanup lock file after exec cargo metadata (#431) * fix: cleanup lock file after exec cargo metadata * fix typos --- .../ethers-contract-abigen/src/util.rs | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/ethers-contract/ethers-contract-abigen/src/util.rs b/ethers-contract/ethers-contract-abigen/src/util.rs index 33b61a31..14b84b68 100644 --- a/ethers-contract/ethers-contract-abigen/src/util.rs +++ b/ethers-contract/ethers-contract-abigen/src/util.rs @@ -38,26 +38,47 @@ pub fn ethers_providers_crate() -> Path { /// | ethers_contract`, we need to use the fitting crate ident when expand the /// macros This will attempt to parse the current `Cargo.toml` and check the /// ethers related dependencies. +/// +/// This process is a bit hacky, we run `cargo metadata` internally which +/// resolves the current package but creates a new `Cargo.lock` file in the +/// process. This is not a problem for regular workspaces but becomes an issue +/// during publishing with `cargo publish` if the project does not ignore +/// `Cargo.lock` in `.gitignore`, because then cargo can't proceed with +/// publishing the crate because the created `Cargo.lock` leads to a modified +/// workspace, not the `CARGO_MANIFEST_DIR` but the workspace `cargo publish` +/// created in `./target/package/..`. Therefore we check prior to executing +/// `cargo metadata` if a `Cargo.lock` file exists and delete it afterwards if +/// it was created by `cargo metadata`. pub fn determine_ethers_crates() -> (&'static str, &'static str, &'static str) { + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("No Manifest found"); + + // check if the lock file exists, if it's missing we need to clean up afterward + let lock_file = format!("{}/Cargo.lock", manifest_dir); + let needs_lock_file_cleanup = !std::path::Path::new(&lock_file).exists(); + let res = MetadataCommand::new() - .manifest_path(&format!( - "{}/Cargo.toml", - std::env::var("CARGO_MANIFEST_DIR").expect("No Manifest found") - )) - .no_deps() + .manifest_path(&format!("{}/Cargo.toml", manifest_dir)) .exec() .ok() .and_then(|metadata| { - metadata.packages[0] - .dependencies - .iter() - .filter(|dep| dep.kind == DependencyKind::Normal) - .find_map(|dep| { - (dep.name == "ethers") - .then(|| ("ethers::core", "ethers::contract", "ethers::providers")) - }) + metadata.root_package().and_then(|pkg| { + pkg.dependencies + .iter() + .filter(|dep| dep.kind == DependencyKind::Normal) + .find_map(|dep| { + (dep.name == "ethers") + .then(|| ("ethers::core", "ethers::contract", "ethers::providers")) + }) + }) }) .unwrap_or(("ethers_core", "ethers_contract", "ethers_providers")); + + if needs_lock_file_cleanup { + // delete the `Cargo.lock` file that was created by `cargo metadata` + // if the package is not part of a workspace + let _ = std::fs::remove_file(lock_file); + } + res }