diff --git a/crate2nix/src/lib.rs b/crate2nix/src/lib.rs index 6f0d7679..28ed18e0 100644 --- a/crate2nix/src/lib.rs +++ b/crate2nix/src/lib.rs @@ -20,6 +20,7 @@ use anyhow::Context; use anyhow::Error; use cargo_metadata::Metadata; use cargo_metadata::PackageId; +use metadata::MergedMetadata; use serde::Deserialize; use serde::Serialize; @@ -84,7 +85,7 @@ impl BuildInfo { default_nix.prune_unneeded_crates(); - prefetch_and_fill_crates_sha256(config, &mut default_nix)?; + prefetch_and_fill_crates_sha256(config, &merged, &mut default_nix)?; Ok(default_nix) } @@ -176,10 +177,11 @@ fn cargo_metadata(config: &GenerateConfig, cargo_toml: &Path) -> Result Result<(), Error> { let mut from_lock_file: HashMap = - extract_hashes_from_lockfile(config, default_nix)?; + extract_hashes_from_lockfile(config, merged, default_nix)?; for (_package_id, hash) in from_lock_file.iter_mut() { let bytes = hex::decode(&hash).map_err(|e| format_err!("while decoding '{}': {}", hash, e))?; @@ -215,6 +217,7 @@ fn prefetch_and_fill_crates_sha256( fn extract_hashes_from_lockfile( config: &GenerateConfig, + merged: &MergedMetadata, default_nix: &mut BuildInfo, ) -> Result, Error> { if !config.use_cargo_lock_checksums { @@ -227,7 +230,7 @@ fn extract_hashes_from_lockfile( let lock_file_path = cargo_toml.parent().unwrap().join("Cargo.lock"); let lock_file = crate::lock::EncodableResolve::load_lock_file(&lock_file_path)?; lock_file - .get_hashes_by_package_id(&mut hashes) + .get_hashes_by_package_id(merged, &mut hashes) .context(format!( "while parsing checksums from Lockfile {}", &lock_file_path.to_string_lossy() diff --git a/crate2nix/src/lock.rs b/crate2nix/src/lock.rs index b55c3fea..b0aab37d 100644 --- a/crate2nix/src/lock.rs +++ b/crate2nix/src/lock.rs @@ -8,6 +8,8 @@ use std::fmt; use std::path::Path; use std::str::FromStr; +use crate::metadata::MergedMetadata; + impl EncodableResolve { pub fn load_lock_file(path: &Path) -> Result { let config = &std::fs::read_to_string(path) @@ -27,8 +29,19 @@ impl EncodableResolve { pub fn get_hashes_by_package_id( &self, + metadata: &MergedMetadata, hashes: &mut HashMap, ) -> Result<(), Error> { + let mut package_id_by_source = HashMap::new(); + for p in &metadata.packages { + let Some(ref source) = p.source else { + // local crate + continue; + }; + let key = (p.name.as_str(), source.repr.as_str(), p.version.to_string()); + package_id_by_source.insert(key, &p.id); + } + for EncodableDependency { name, version, @@ -37,13 +50,17 @@ impl EncodableResolve { .. } in self.package.iter() { - if let (Some(source), Some(checksum)) = (source, checksum) { - let package_id = PackageId { - repr: format!("{} {} ({})", name, version, source), - }; - if checksum != "" { - hashes.insert(package_id, checksum.clone()); - } + let Some((source, checksum)) = Option::zip(source.as_ref(), checksum.as_ref()) else { + continue; + }; + if checksum == "" { + continue; + } + + if let Some(package_id) = + package_id_by_source.get(&(name.as_str(), source.as_str(), version.clone())) + { + hashes.insert((*package_id).clone(), checksum.clone()); } } @@ -66,88 +83,6 @@ impl EncodableResolve { } } -#[test] -fn test_no_legacy_checksums() { - let config = r#" -[[package]] -name = "aho-corasick" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - ] -"#; - let resolve = EncodableResolve::load_lock_string(Path::new("dummy"), config).unwrap(); - let mut hashes = HashMap::new(); - resolve.get_hashes_by_package_id(&mut hashes).unwrap(); - assert_eq!(hashes, HashMap::new()); -} - -#[test] -fn test_some_legacy_checksums() { - let config = r#" -[[package]] -name = "aho-corasick" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" -"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" - -"#; - let resolve = EncodableResolve::load_lock_string(Path::new("dummy"), config).unwrap(); - let mut hashes = HashMap::new(); - resolve.get_hashes_by_package_id(&mut hashes).unwrap(); - assert_eq!( - hashes, - [( - PackageId { repr: "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)".to_string() }, - "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" - ), - ( - PackageId { repr: "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)".to_string()}, - "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" - )] - .iter() - .map(|(package_id, hash)| (package_id.clone(), hash.to_string())) - .collect::>() - ); -} - -#[test] -fn test_some_inline_checksums() { - let config = r#" -[[package]] -name = "aho-corasick" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] -checksum = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" -"#; - let resolve = EncodableResolve::load_lock_string(Path::new("dummy"), config).unwrap(); - let mut hashes = HashMap::new(); - resolve.get_hashes_by_package_id(&mut hashes).unwrap(); - assert_eq!( - hashes, - [( - PackageId { - repr: "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" - .to_string() - }, - "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" - )] - .iter() - .map(|(package_id, hash)| (package_id.clone(), hash.to_string())) - .collect::>() - ); -} - // // The code below was copied/adjusted from Cargo. // diff --git a/crate2nix/src/metadata.rs b/crate2nix/src/metadata.rs index 1cf3ce90..30d3a74c 100644 --- a/crate2nix/src/metadata.rs +++ b/crate2nix/src/metadata.rs @@ -22,7 +22,7 @@ use serde::Serialize; #[derive(Debug)] pub struct MergedMetadata { workspace_members: Vec, - packages: Vec, + pub(crate) packages: Vec, root: Option, nodes: Vec, }