Skip to content

Commit

Permalink
If there's a version in the lock file only use that exact version
Browse files Browse the repository at this point in the history
  • Loading branch information
Eh2406 committed Oct 4, 2023
1 parent d74bc47 commit 2961584
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 49 deletions.
21 changes: 13 additions & 8 deletions src/cargo/sources/registry/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,11 +437,13 @@ impl<'cfg> RegistryIndex<'cfg> {
/// checking the integrity of a downloaded package matching the checksum in
/// the index file, aka [`IndexSummary`].
pub fn hash(&mut self, pkg: PackageId, load: &mut dyn RegistryData) -> Poll<CargoResult<&str>> {
let req = OptVersionReq::exact(pkg.version());
let mut req = OptVersionReq::exact(pkg.version());
// Since crates.io allows crate versions to differ only by build metadata,
// a query using OptVersionReq::exact + next() can return nondeterministic results.
// So we `lock_to` the exact version were interested in
req.lock_to(pkg.version());
let summary = self.summaries(pkg.name(), &req, load)?;
let summary = ready!(summary)
.filter(|s| s.package_id().version() == pkg.version())
.next();
let summary = ready!(summary).next();
Poll::Ready(Ok(summary
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
.as_summary()
Expand Down Expand Up @@ -698,10 +700,13 @@ impl<'cfg> RegistryIndex<'cfg> {
pkg: PackageId,
load: &mut dyn RegistryData,
) -> Poll<CargoResult<bool>> {
let req = OptVersionReq::exact(pkg.version());
let found = ready!(self.summaries(pkg.name(), &req, load))?
.filter(|s| s.package_id().version() == pkg.version())
.any(|s| s.is_yanked());
let mut req = OptVersionReq::exact(pkg.version());

// Since crates.io allows crate versions to differ only by build metadata,
// a query using OptVersionReq::exact + next() can return nondeterministic results.
// So we `lock_to` the exact version were interested in
req.lock_to(pkg.version());
let found = ready!(self.summaries(pkg.name(), &req, load))?.any(|s| s.is_yanked());
Poll::Ready(Ok(found))
}
}
Expand Down
49 changes: 8 additions & 41 deletions src/cargo/util/semver_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,14 @@ impl OptVersionReq {
OptVersionReq::Any => true,
OptVersionReq::Req(req) => req.matches(version),
OptVersionReq::Locked(v, _) => {
v.major == version.major
&& v.minor == version.minor
&& v.patch == version.patch
&& v.pre == version.pre
// Generally, cargo is of the opinion that semver metadata should be ignored.
// If your registry has two versions that only differing metadata you get the bugs you deserve.
// We also believe that lock files should ensure reproducibility
// and protect against mutations from the registry.
// In this circumstance these two goals are in conflict, and we pick reproducibility.
// If the lock file tells us that there is a version called `1.0.0+bar` then
// we should not silently use `1.0.0+foo` even though they have the same version.
v == version
}
}
}
Expand Down Expand Up @@ -311,40 +315,3 @@ fn is_req(value: &str) -> bool {
};
"<>=^~".contains(first) || value.contains('*') || value.contains(',')
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn locked_has_the_same_with_exact() {
fn test_versions(target_ver: &str, vers: &[&str]) {
let ver = Version::parse(target_ver).unwrap();
let exact = OptVersionReq::exact(&ver);
let mut locked = exact.clone();
locked.lock_to(&ver);
for v in vers {
let v = Version::parse(v).unwrap();
assert_eq!(exact.matches(&v), locked.matches(&v));
}
}

test_versions(
"1.0.0",
&["1.0.0", "1.0.1", "0.9.9", "0.10.0", "0.1.0", "1.0.0-pre"],
);
test_versions("0.9.0", &["0.9.0", "0.9.1", "1.9.0", "0.0.9", "0.9.0-pre"]);
test_versions("0.0.2", &["0.0.2", "0.0.1", "0.0.3", "0.0.2-pre"]);
test_versions(
"0.1.0-beta2.a",
&[
"0.1.0-beta2.a",
"0.9.1",
"0.1.0",
"0.1.1-beta2.a",
"0.1.0-beta2",
],
);
test_versions("0.1.0+meta", &["0.1.0", "0.1.0+meta", "0.1.0+any"]);
}
}

0 comments on commit 2961584

Please sign in to comment.