]> git.proxmox.com Git - cargo.git/commitdiff
Don't update lockfiles from previous Cargo versions if `--locked` is passed
authorAleksey Kladov <aleksey.kladov@gmail.com>
Mon, 30 Oct 2017 19:56:46 +0000 (22:56 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 31 Oct 2017 09:25:37 +0000 (12:25 +0300)
src/cargo/ops/lockfile.rs
tests/lockfile-compat.rs

index 8dc5b45672e2c08fae0efa2efca1fddb87730d8c..0a7aef5a95690cf2f571962aa1b4915c9a3ab426 100644 (file)
@@ -40,10 +40,7 @@ pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()>
         Ok(s)
     });
 
-    let toml = toml::Value::try_from(WorkspaceResolve {
-        ws: ws,
-        resolve: resolve,
-    }).unwrap();
+    let toml = toml::Value::try_from(WorkspaceResolve { ws, resolve }).unwrap();
 
     let mut out = String::new();
 
@@ -72,10 +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 has_crlf_line_endings(&orig) {
-            out = out.replace("\n", "\r\n");
-        }
-        if out == orig {
+        if are_equal_lockfiles(orig, &out, ws.config().lock_update_allowed()) {
             return Ok(())
         }
     }
@@ -97,6 +91,23 @@ pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()>
     })
 }
 
+fn are_equal_lockfiles(mut orig: String, current: &str, lock_update_allowed: bool) -> 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::<toml::Value>(), current.parse::<toml::Value>()) {
+            (Ok(ref a), Ok(ref b)) if a == b => return true,
+            _ => {}
+        }
+    }
+    current == orig
+}
+
 fn has_crlf_line_endings(s: &str) -> bool {
     // Only check the first line.
     if let Some(lf) = s.find('\n') {
index f532e7dfbcdfd5d975accd47a8a7e4c69ee661c8..3f887c9818eb136a6b88067c37de7fba2cda76bc 100644 (file)
@@ -37,8 +37,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "[..]"
 "#;
 
-    let old_lockfile = r#"
-[root]
+    let old_lockfile =
+r#"[root]
 name = "bar"
 version = "0.0.1"
 dependencies = [
@@ -62,9 +62,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
             foo = "0.1.0"
         "#)
         .file("src/lib.rs", "")
-        .file("Cargo.lock", old_lockfile);
-
-    let p = p.build();
+        .file("Cargo.lock", old_lockfile)
+        .build();
 
     assert_that(p.cargo(cargo_command),
                 execs().with_status(0));
@@ -77,6 +76,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
     assert_eq!(lock.lines().count(), expected_lockfile.lines().count());
 }
 
+
+#[test]
+fn frozen_flag_preserves_old_lockfile() {
+    Package::new("foo", "0.1.0").publish();
+
+    let old_lockfile =
+        r#"[root]
+name = "bar"
+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)" = "f9e0a16bdf5c05435698fa27192d89e331b22a26a972c34984f560662544453b"
+"#;
+
+    let p = project("bar")
+        .file("Cargo.toml", r#"
+            [project]
+            name = "bar"
+            version = "0.0.1"
+            authors = []
+
+            [dependencies]
+            foo = "0.1.0"
+        "#)
+        .file("src/lib.rs", "")
+        .file("Cargo.lock", old_lockfile)
+        .build();
+
+    assert_that(p.cargo("build").arg("--locked"),
+                execs().with_status(0));
+
+    let lock = p.read_lockfile();
+    for (l, r) in old_lockfile.lines().zip(lock.lines()) {
+        assert!(lines_match(l, r), "Lines differ:\n{}\n\n{}", l, r);
+    }
+
+    assert_eq!(lock.lines().count(), old_lockfile.lines().count());
+}
+
+
 #[test]
 fn totally_wild_checksums_works() {
     Package::new("foo", "0.1.0").publish();