Skip to content

Commit

Permalink
Auto merge of #2092 - gkoz:lock_line_endings, r=alexcrichton
Browse files Browse the repository at this point in the history
Before writing the lockfile read the existing one and

 * detect the line endings style, fixes #2076, #1722;
 * compare the contents to avoid redundant overwriting.
  • Loading branch information
bors committed Oct 30, 2015
2 parents 0590d30 + da4b8af commit 3367b9c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/cargo/ops/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,31 @@ pub fn write_lockfile(dst: &Path, resolve: &Resolve) -> CargoResult<()> {
None => {}
}

// Load the original lockfile if it exists.
if let Ok(orig) = paths::read(dst) {
if has_crlf_line_endings(&orig) {
out = out.replace("\n", "\r\n");
}
if out == orig {
// The lockfile contents haven't changed so don't rewrite it.
// This is helpful on read-only filesystems.
return Ok(())
}
}

try!(paths::write(dst, out.as_bytes()));
Ok(())
}

fn has_crlf_line_endings(s: &str) -> bool {
// Only check the first line.
if let Some(lf) = s.find('\n') {
s[..lf].ends_with('\r')
} else {
false
}
}

fn emit_package(dep: &toml::Table, out: &mut String) {
out.push_str(&format!("name = {}\n", lookup(dep, "name")));
out.push_str(&format!("version = {}\n", lookup(dep, "version")));
Expand Down
51 changes: 50 additions & 1 deletion tests/test_cargo_generate_lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fs::File;
use std::io::prelude::*;

use support::{project, execs};
use hamcrest::assert_that;
use hamcrest::{assert_that, existing_file};

fn setup() {}

Expand Down Expand Up @@ -122,3 +122,52 @@ foo = "bar"
File::open(&lockfile).unwrap().read_to_string(&mut lock).unwrap();
assert!(lock.contains(metadata.trim()), "{}", lock);
});

test!(preserve_line_endings_issue_2076 {
let p = project("foo")
.file("Cargo.toml", r#"
[package]
name = "foo"
authors = []
version = "0.0.1"
"#)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", r#"
[package]
name = "bar"
authors = []
version = "0.0.1"
"#)
.file("bar/src/lib.rs", "");

let lockfile = p.root().join("Cargo.lock");
assert_that(p.cargo_process("generate-lockfile"),
execs().with_status(0));
assert_that(&lockfile,
existing_file());
assert_that(p.cargo("generate-lockfile"),
execs().with_status(0));

let mut lock0 = String::new();
{
File::open(&lockfile).unwrap().read_to_string(&mut lock0).unwrap();
}

assert!(lock0.starts_with("[root]\n"));

let lock1 = lock0.replace("\n", "\r\n");
{
File::create(&lockfile).unwrap().write_all(lock1.as_bytes()).unwrap();
}

assert_that(p.cargo("generate-lockfile"),
execs().with_status(0));

let mut lock2 = String::new();
{
File::open(&lockfile).unwrap().read_to_string(&mut lock2).unwrap();
}

assert!(lock2.starts_with("[root]\r\n"));
assert_eq!(lock1, lock2);
});

0 comments on commit 3367b9c

Please sign in to comment.