Skip to content

Commit

Permalink
Handle a case where cargo new oscillates
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Nov 18, 2019
1 parent 013c1af commit c37a46c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
26 changes: 25 additions & 1 deletion src/cargo/core/resolver/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl EncodableResolve {
/// `features`. Care should be taken when using this Resolve. One of the
/// primary uses is to be used with `resolve_with_previous` to guide the
/// resolver to create a complete Resolve.
pub fn into_resolve(self, ws: &Workspace<'_>) -> CargoResult<Resolve> {
pub fn into_resolve(self, original: &str, ws: &Workspace<'_>) -> CargoResult<Resolve> {
let path_deps = build_path_deps(ws);
let mut checksums = HashMap::new();

Expand Down Expand Up @@ -333,6 +333,30 @@ impl EncodableResolve {
unused_patches.push(id);
}

// We have a curious issue where in the "v1 format" we buggily had a
// trailing blank line at the end of lock files under some specific
// conditions.
//
// Cargo is trying to write new lockfies in the "v2 format" but if you
// have no dependencies, for example, then the lockfile encoded won't
// really have any indicator that it's in the new format (no
// dependencies or checksums listed). This means that if you type `cargo
// new` followed by `cargo build` it will generate a "v2 format" lock
// file since none previously existed. When reading this on the next
// `cargo build`, however, it generates a new lock file because when
// reading in that lockfile we think it's the v1 format.
//
// To help fix this issue we special case here. If our lockfile only has
// one trailing newline, not two, *and* it only has one package, then
// this is actually the v2 format.
if original.ends_with("\n")
&& !original.ends_with("\n\n")
&& version == ResolveVersion::V1
&& g.iter().count() == 1
{
version = ResolveVersion::V2;
}

Ok(Resolve::new(
g,
replacements,
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {
let resolve = (|| -> CargoResult<Option<Resolve>> {
let resolve: toml::Value = cargo_toml::parse(&s, f.path(), ws.config())?;
let v: resolver::EncodableResolve = resolve.try_into()?;
Ok(Some(v.into_resolve(ws)?))
Ok(Some(v.into_resolve(&s, ws)?))
})()
.chain_err(|| format!("failed to parse lock file at: {}", f.path().display()))?;
Ok(resolve)
Expand Down Expand Up @@ -172,7 +172,7 @@ fn are_equal_lockfiles(mut orig: String, current: &str, ws: &Workspace<'_>) -> b
let res: CargoResult<bool> = (|| {
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)?)
Ok(old.into_resolve(&orig, ws)? == new.into_resolve(current, ws)?)
})();
if let Ok(true) = res {
return true;
Expand Down
11 changes: 11 additions & 0 deletions tests/testsuite/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,14 @@ fn new_with_reference_link() {
let contents = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
assert!(contents.contains("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html"))
}

#[cargo_test]
fn lockfile_constant_during_new() {
cargo_process("new foo").env("USER", "foo").run();

cargo_process("build").cwd(&paths::root().join("foo")).run();
let before = fs::read_to_string(paths::root().join("foo/Cargo.lock")).unwrap();
cargo_process("build").cwd(&paths::root().join("foo")).run();
let after = fs::read_to_string(paths::root().join("foo/Cargo.lock")).unwrap();
assert_eq!(before, after);
}

0 comments on commit c37a46c

Please sign in to comment.