Skip to content

Commit

Permalink
Lookup PackageId in resolved metadata
Browse files Browse the repository at this point in the history
instead of trying to create ourselves using information available:
internal representation is not stable.

Sadly tests had to go
  • Loading branch information
pacak authored and kolloch committed Apr 6, 2024
1 parent 218d0f7 commit 640584d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 93 deletions.
9 changes: 6 additions & 3 deletions crate2nix/src/lib.rs
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -176,10 +177,11 @@ fn cargo_metadata(config: &GenerateConfig, cargo_toml: &Path) -> Result<Metadata
/// Prefetch hashes when necessary.
fn prefetch_and_fill_crates_sha256(
config: &GenerateConfig,
merged: &MergedMetadata,
default_nix: &mut BuildInfo,
) -> Result<(), Error> {
let mut from_lock_file: HashMap<PackageId, String> =
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))?;
Expand Down Expand Up @@ -215,6 +217,7 @@ fn prefetch_and_fill_crates_sha256(

fn extract_hashes_from_lockfile(
config: &GenerateConfig,
merged: &MergedMetadata,
default_nix: &mut BuildInfo,
) -> Result<HashMap<PackageId, String>, Error> {
if !config.use_cargo_lock_checksums {
Expand All @@ -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()
Expand Down
113 changes: 24 additions & 89 deletions crate2nix/src/lock.rs
Expand Up @@ -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<EncodableResolve, Error> {
let config = &std::fs::read_to_string(path)
Expand All @@ -27,8 +29,19 @@ impl EncodableResolve {

pub fn get_hashes_by_package_id(
&self,
metadata: &MergedMetadata,
hashes: &mut HashMap<PackageId, String>,
) -> 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,
Expand All @@ -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 != "<none>" {
hashes.insert(package_id, checksum.clone());
}
let Some((source, checksum)) = Option::zip(source.as_ref(), checksum.as_ref()) else {
continue;
};
if checksum == "<none>" {
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());
}
}

Expand All @@ -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::<HashMap<_, _>>()
);
}

#[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::<HashMap<_, _>>()
);
}

//
// The code below was copied/adjusted from Cargo.
//
Expand Down
2 changes: 1 addition & 1 deletion crate2nix/src/metadata.rs
Expand Up @@ -22,7 +22,7 @@ use serde::Serialize;
#[derive(Debug)]
pub struct MergedMetadata {
workspace_members: Vec<PackageId>,
packages: Vec<Package>,
pub(crate) packages: Vec<Package>,
root: Option<PackageId>,
nodes: Vec<Node>,
}
Expand Down

0 comments on commit 640584d

Please sign in to comment.