From eb6e1b34a40ecf856a36b0111dfe2948b53a1e60 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 20 Apr 2021 13:23:06 -0700 Subject: [PATCH] Fix disagreement about lockfile ordering on stable/nightly This commit fixes an issue where the order of packages serialized into a lock file differs on stable vs nightly. This is due to a bug introduced in #9133 where a manual `Ord` implementation was replaced with a `#[derive]`'d one. This was an unintended consequence of #9133 and means that the same lock file produced by two different versions of Cargo only differs in what order items are serialized. With #9133 being reverted soon on the current beta channel this is intended to be the nightly fix for #9334. This will hopefully mean that those projects which don't build with beta/nightly will remain unaffected, and those affected on beta/nightly will need to switch to the new nightly ordering when it's published (which matches the current stable). The reverted beta will match this ordering as well. Closes #9334 --- src/cargo/core/source/source_id.rs | 7 ++- tests/testsuite/lockfile_compat.rs | 72 ++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 6061a9cf7db..bdd4e67a98f 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -44,8 +44,9 @@ struct SourceIdInner { /// source. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] enum SourceKind { - /// A git repository. - Git(GitReference), + // Note that the ordering here is important for how it affects the `Ord` + // implementation, notably how this affects the ordering of serialized + // packages into lock files. /// A local path.. Path, /// A remote registry. @@ -54,6 +55,8 @@ enum SourceKind { LocalRegistry, /// A directory-based registry. Directory, + /// A git repository. + Git(GitReference), } /// Information to find a specific commit in a Git repository. diff --git a/tests/testsuite/lockfile_compat.rs b/tests/testsuite/lockfile_compat.rs index 8a16b5454d7..77d874c5aac 100644 --- a/tests/testsuite/lockfile_compat.rs +++ b/tests/testsuite/lockfile_compat.rs @@ -771,3 +771,75 @@ dependencies = [ p.cargo("build --locked").run(); } + +#[cargo_test] +fn same_name_version_different_sources() { + let cksum = Package::new("foo", "0.1.0").publish(); + let (git_project, repo) = git::new_repo("dep1", |project| { + project + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + }); + let head_id = repo.head().unwrap().target().unwrap(); + + // Lockfile was generated with Rust 1.51 + let lockfile = format!( + r#"# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "foo" +version = "0.1.0" +dependencies = [ + "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foo 0.1.0 (git+{url})", +] + +[[package]] +name = "foo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "{cksum}" + +[[package]] +name = "foo" +version = "0.1.0" +source = "git+{url}#{sha}" +"#, + sha = head_id, + url = git_project.url(), + cksum = cksum + ); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [project] + name = "foo" + version = "0.1.0" + + [dependencies] + foo = "0.1.0" + foo2 = {{ git = '{}', package = 'foo' }} + "#, + git_project.url(), + ), + ) + .file("src/lib.rs", "") + .file("Cargo.lock", &lockfile) + .build(); + + p.cargo("build").run(); + + assert_eq!(p.read_file("Cargo.lock"), lockfile); +}