Turn the new lock file format on by default

This commit enables the support added in #7070 by default. This means
that gradually over time all `Cargo.lock` files will be migrated to the
new format. Cargo shipped with Rust 1.38.0 supports this new lock file
format, so any project using Rust 1.38.0 or above will converge quickly
onto the new lock file format and continue working.

The main benefit of the new format is to be more friendly to git merge
conflicts. Information is deduplicated throughout the lock file to avoid
verbose `depedencies` lists and the `checksum` data is all listed inline
with `[[package]]`. This has been deployed with rust-lang/rust for some
time now and it subjectively at least seems to have greatly reduced the
amount of bouncing that happens for touching `Cargo.lock`.
This commit is contained in:
Alex Crichton 2019-11-08 15:48:04 -08:00
parent 8280633db6
commit 366ae3f7ba
4 changed files with 68 additions and 50 deletions

View File

@ -15,7 +15,6 @@ use super::encode::Metadata;
/// ///
/// Each instance of `Resolve` also understands the full set of features used /// Each instance of `Resolve` also understands the full set of features used
/// for each package. /// for each package.
#[derive(PartialEq)]
pub struct Resolve { pub struct Resolve {
/// A graph, whose vertices are packages and edges are dependency specifications /// A graph, whose vertices are packages and edges are dependency specifications
/// from `Cargo.toml`. We need a `Vec` here because the same package /// from `Cargo.toml`. We need a `Vec` here because the same package
@ -358,6 +357,26 @@ unable to verify that `{0}` is the same as when the lockfile was generated
} }
} }
impl PartialEq for Resolve {
fn eq(&self, other: &Resolve) -> bool {
macro_rules! compare {
($($fields:ident)* | $($ignored:ident)*) => {
let Resolve { $($fields,)* $($ignored,)* } = self;
$(drop($ignored);)*
$($fields == &other.$fields)&&*
}
}
compare! {
// fields to compare
graph replacements reverse_replacements empty_features features
checksums metadata unused_patches public_dependencies
|
// fields to ignore
version
}
}
}
impl fmt::Debug for Resolve { impl fmt::Debug for Resolve {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(fmt, "graph: {:?}", self.graph)?; writeln!(fmt, "graph: {:?}", self.graph)?;
@ -376,7 +395,7 @@ impl ResolveVersion {
/// previous `Cargo.lock` files, and generally matches with what we want to /// previous `Cargo.lock` files, and generally matches with what we want to
/// encode. /// encode.
pub fn default() -> ResolveVersion { pub fn default() -> ResolveVersion {
ResolveVersion::V1 ResolveVersion::V2
} }
/// Returns whether this encoding version is "from the future". /// Returns whether this encoding version is "from the future".
@ -385,7 +404,7 @@ impl ResolveVersion {
/// intended to become the default "soon". /// intended to become the default "soon".
pub fn from_the_future(&self) -> bool { pub fn from_the_future(&self) -> bool {
match self { match self {
ResolveVersion::V2 => true, ResolveVersion::V2 => false,
ResolveVersion::V1 => false, ResolveVersion::V1 => false,
} }
} }

View File

@ -10,6 +10,14 @@ fn oldest_lockfile_still_works() {
} }
} }
fn assert_lockfiles_eq(expected: &str, actual: &str) {
for (l, r) in expected.lines().zip(actual.lines()) {
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(expected.lines().count(), actual.lines().count());
}
fn oldest_lockfile_still_works_with_command(cargo_command: &str) { fn oldest_lockfile_still_works_with_command(cargo_command: &str) {
Package::new("bar", "0.1.0").publish(); Package::new("bar", "0.1.0").publish();
@ -19,16 +27,14 @@ fn oldest_lockfile_still_works_with_command(cargo_command: &str) {
name = "bar" name = "bar"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "[..]"
[[package]] [[package]]
name = "foo" name = "foo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bar",
] ]
[metadata]
"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "[..]"
"#; "#;
let old_lockfile = r#" let old_lockfile = r#"
@ -65,11 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
p.cargo(cargo_command).run(); p.cargo(cargo_command).run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
for (l, r) in expected_lockfile.lines().zip(lock.lines()) { assert_lockfiles_eq(expected_lockfile, &lock);
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(lock.lines().count(), expected_lockfile.lines().count());
} }
#[cargo_test] #[cargo_test]
@ -115,11 +117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
p.cargo("build --locked").run(); p.cargo("build --locked").run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
for (l, r) in old_lockfile.lines().zip(lock.lines()) { assert_lockfiles_eq(&old_lockfile, &lock);
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(lock.lines().count(), old_lockfile.lines().count());
} }
#[cargo_test] #[cargo_test]
@ -166,26 +164,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
p.cargo("build").run(); p.cargo("build").run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
assert!(lock.starts_with( assert_lockfiles_eq(
r#" r#"# This file is automatically @generated by Cargo.
# This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "bar" name = "bar"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "[..]"
[[package]] [[package]]
name = "foo" name = "foo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bar",
] ]
"#,
[metadata] &lock,
"# );
.trim()
));
} }
#[cargo_test] #[cargo_test]
@ -413,22 +409,16 @@ fn current_lockfile_format() {
name = \"bar\" name = \"bar\"
version = \"0.1.0\" version = \"0.1.0\"
source = \"registry+https://github.com/rust-lang/crates.io-index\" source = \"registry+https://github.com/rust-lang/crates.io-index\"
checksum = \"[..]\"
[[package]] [[package]]
name = \"foo\" name = \"foo\"
version = \"0.0.1\" version = \"0.0.1\"
dependencies = [ dependencies = [
\"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)\", \"bar\",
] ]
";
[metadata] assert_lockfiles_eq(expected, &actual);
\"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)\" = \"[..]\"";
for (l, r) in expected.lines().zip(actual.lines()) {
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(actual.lines().count(), expected.lines().count());
} }
#[cargo_test] #[cargo_test]
@ -447,7 +437,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "foo" name = "foo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bar",
] ]
"#; "#;
@ -472,7 +462,24 @@ dependencies = [
p.cargo("build").run(); p.cargo("build").run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
assert!(lock.starts_with(lockfile.trim())); assert_lockfiles_eq(
r#"# [..]
# [..]
[[package]]
name = "bar"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "[..]"
[[package]]
name = "foo"
version = "0.0.1"
dependencies = [
"bar",
]
"#,
&lock,
);
} }
#[cargo_test] #[cargo_test]
@ -549,11 +556,7 @@ dependencies = [
p.cargo("fetch").run(); p.cargo("fetch").run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
for (l, r) in lockfile.lines().zip(lock.lines()) { assert_lockfiles_eq(&lockfile, &lock);
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(lock.lines().count(), lockfile.lines().count());
} }
#[cargo_test] #[cargo_test]
@ -624,9 +627,5 @@ dependencies = [
p.cargo("fetch").run(); p.cargo("fetch").run();
let lock = p.read_lockfile(); let lock = p.read_lockfile();
for (l, r) in lockfile.lines().zip(lock.lines()) { assert_lockfiles_eq(&lockfile, &lock);
assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
}
assert_eq!(lock.lines().count(), lockfile.lines().count());
} }

View File

@ -1171,7 +1171,7 @@ fn publish_git_with_version() {
name = \"foo\"\n\ name = \"foo\"\n\
version = \"0.1.0\"\n\ version = \"0.1.0\"\n\
dependencies = [\n\ dependencies = [\n\
\x20\"dep1 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)\",\n\ \x20\"dep1\",\n\
]\n\ ]\n\
[..]", [..]",
), ),

View File

@ -30,5 +30,5 @@ fn minimal_version_cli() {
let lock = p.read_lockfile(); let lock = p.read_lockfile();
assert!(lock.contains("dep 1.0.0")); assert!(!lock.contains("1.1.0"));
} }