diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index b605742d4ed..4c938f87ec5 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -73,6 +73,7 @@ mod encode; /// /// Each instance of `Resolve` also understands the full set of features used /// for each package. +#[derive(PartialEq)] pub struct Resolve { graph: Graph, replacements: HashMap, diff --git a/src/cargo/ops/lockfile.rs b/src/cargo/ops/lockfile.rs index 0a7aef5a956..7368bbf8ade 100644 --- a/src/cargo/ops/lockfile.rs +++ b/src/cargo/ops/lockfile.rs @@ -69,7 +69,7 @@ pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()> // If the lockfile contents haven't changed so don't rewrite it. This is // helpful on read-only filesystems. if let Ok(orig) = orig { - if are_equal_lockfiles(orig, &out, ws.config().lock_update_allowed()) { + if are_equal_lockfiles(orig, &out, ws) { return Ok(()) } } @@ -91,20 +91,25 @@ pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()> }) } -fn are_equal_lockfiles(mut orig: String, current: &str, lock_update_allowed: bool) -> bool { +fn are_equal_lockfiles(mut orig: String, current: &str, ws: &Workspace) -> bool { if has_crlf_line_endings(&orig) { orig = orig.replace("\r\n", "\n"); } - // Old lockfiles have unused `[root]` section, - // just ignore it if we are in the `--frozen` mode. - if !lock_update_allowed && orig.starts_with("[root]") { - orig = orig.replacen("[root]", "[[package]]", 1); - match (orig.parse::(), current.parse::()) { - (Ok(ref a), Ok(ref b)) if a == b => return true, - _ => {} + // If we want to try and avoid updating the lockfile, parse both and + // compare them; since this is somewhat expensive, don't do it in the + // common case where we can update lockfiles. + if !ws.config().lock_update_allowed() { + let res: CargoResult = (|| { + let old: resolver::EncodableResolve = toml::from_str(&orig)?; + let new: resolver::EncodableResolve = toml::from_str(current)?; + Ok(old.into_resolve(ws)? == new.into_resolve(ws)?) + })(); + if let Ok(true) = res { + return true; } } + current == orig } diff --git a/tests/lockfile-compat.rs b/tests/lockfile-compat.rs index 3f887c9818e..0c90fd417ad 100644 --- a/tests/lockfile-compat.rs +++ b/tests/lockfile-compat.rs @@ -22,24 +22,24 @@ fn oldest_lockfile_still_works_with_command(cargo_command: &str) { let expected_lockfile = r#"[[package]] -name = "bar" +name = "foo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "zzz" version = "0.0.1" dependencies = [ "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "foo" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [metadata] "checksum foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "[..]" "#; let old_lockfile = r#"[root] -name = "bar" +name = "zzz" version = "0.0.1" dependencies = [ "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -54,7 +54,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" let p = project("bar") .file("Cargo.toml", r#" [project] - name = "bar" + name = "zzz" version = "0.0.1" authors = [] @@ -83,7 +83,7 @@ fn frozen_flag_preserves_old_lockfile() { let old_lockfile = r#"[root] -name = "bar" +name = "zzz" version = "0.0.1" dependencies = [ "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -101,7 +101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" let p = project("bar") .file("Cargo.toml", r#" [project] - name = "bar" + name = "zzz" version = "0.0.1" authors = []