Skip to content

Commit c37a46c

Browse files
committed
Handle a case where cargo new oscillates
1 parent 013c1af commit c37a46c

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

src/cargo/core/resolver/encode.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl EncodableResolve {
132132
/// `features`. Care should be taken when using this Resolve. One of the
133133
/// primary uses is to be used with `resolve_with_previous` to guide the
134134
/// resolver to create a complete Resolve.
135-
pub fn into_resolve(self, ws: &Workspace<'_>) -> CargoResult<Resolve> {
135+
pub fn into_resolve(self, original: &str, ws: &Workspace<'_>) -> CargoResult<Resolve> {
136136
let path_deps = build_path_deps(ws);
137137
let mut checksums = HashMap::new();
138138

@@ -333,6 +333,30 @@ impl EncodableResolve {
333333
unused_patches.push(id);
334334
}
335335

336+
// We have a curious issue where in the "v1 format" we buggily had a
337+
// trailing blank line at the end of lock files under some specific
338+
// conditions.
339+
//
340+
// Cargo is trying to write new lockfies in the "v2 format" but if you
341+
// have no dependencies, for example, then the lockfile encoded won't
342+
// really have any indicator that it's in the new format (no
343+
// dependencies or checksums listed). This means that if you type `cargo
344+
// new` followed by `cargo build` it will generate a "v2 format" lock
345+
// file since none previously existed. When reading this on the next
346+
// `cargo build`, however, it generates a new lock file because when
347+
// reading in that lockfile we think it's the v1 format.
348+
//
349+
// To help fix this issue we special case here. If our lockfile only has
350+
// one trailing newline, not two, *and* it only has one package, then
351+
// this is actually the v2 format.
352+
if original.ends_with("\n")
353+
&& !original.ends_with("\n\n")
354+
&& version == ResolveVersion::V1
355+
&& g.iter().count() == 1
356+
{
357+
version = ResolveVersion::V2;
358+
}
359+
336360
Ok(Resolve::new(
337361
g,
338362
replacements,

src/cargo/ops/lockfile.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {
2222
let resolve = (|| -> CargoResult<Option<Resolve>> {
2323
let resolve: toml::Value = cargo_toml::parse(&s, f.path(), ws.config())?;
2424
let v: resolver::EncodableResolve = resolve.try_into()?;
25-
Ok(Some(v.into_resolve(ws)?))
25+
Ok(Some(v.into_resolve(&s, ws)?))
2626
})()
2727
.chain_err(|| format!("failed to parse lock file at: {}", f.path().display()))?;
2828
Ok(resolve)
@@ -172,7 +172,7 @@ fn are_equal_lockfiles(mut orig: String, current: &str, ws: &Workspace<'_>) -> b
172172
let res: CargoResult<bool> = (|| {
173173
let old: resolver::EncodableResolve = toml::from_str(&orig)?;
174174
let new: resolver::EncodableResolve = toml::from_str(current)?;
175-
Ok(old.into_resolve(ws)? == new.into_resolve(ws)?)
175+
Ok(old.into_resolve(&orig, ws)? == new.into_resolve(current, ws)?)
176176
})();
177177
if let Ok(true) = res {
178178
return true;

tests/testsuite/new.rs

+11
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,14 @@ fn new_with_reference_link() {
527527
let contents = fs::read_to_string(paths::root().join("foo/Cargo.toml")).unwrap();
528528
assert!(contents.contains("# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html"))
529529
}
530+
531+
#[cargo_test]
532+
fn lockfile_constant_during_new() {
533+
cargo_process("new foo").env("USER", "foo").run();
534+
535+
cargo_process("build").cwd(&paths::root().join("foo")).run();
536+
let before = fs::read_to_string(paths::root().join("foo/Cargo.lock")).unwrap();
537+
cargo_process("build").cwd(&paths::root().join("foo")).run();
538+
let after = fs::read_to_string(paths::root().join("foo/Cargo.lock")).unwrap();
539+
assert_eq!(before, after);
540+
}

0 commit comments

Comments
 (0)