Skip to content

Commit 501e580

Browse files
committed
Fix cargo update with unused patch.
1 parent 2fef2e5 commit 501e580

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

src/cargo/ops/cargo_generate_lockfile.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use termcolor::Color::{self, Cyan, Green, Red};
55

66
use crate::core::registry::PackageRegistry;
77
use crate::core::resolver::ResolveOpts;
8-
use crate::core::PackageId;
8+
use crate::core::{PackageId, PackageIdSpec};
99
use crate::core::{Resolve, SourceId, Workspace};
1010
use crate::ops;
1111
use crate::util::config::Config;
@@ -79,6 +79,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
7979

8080
if opts.to_update.is_empty() {
8181
to_avoid.extend(previous_resolve.iter());
82+
to_avoid.extend(previous_resolve.unused_patches());
8283
} else {
8384
let mut sources = Vec::new();
8485
for name in opts.to_update.iter() {
@@ -102,6 +103,11 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
102103
None => dep.source_id().with_precise(None),
103104
});
104105
}
106+
if let Ok(unused_id) =
107+
PackageIdSpec::query_str(name, previous_resolve.unused_patches().iter().cloned())
108+
{
109+
to_avoid.insert(unused_id);
110+
}
105111
}
106112

107113
registry.add_sources(sources)?;

tests/testsuite/patch.rs

+76
Original file line numberDiff line numberDiff line change
@@ -1445,3 +1445,79 @@ fn canonicalize_a_bunch() {
14451445
p.cargo("build").with_stderr("[FINISHED] [..]").run();
14461446
p.cargo("build").with_stderr("[FINISHED] [..]").run();
14471447
}
1448+
1449+
#[cargo_test]
1450+
fn update_unused_new_version() {
1451+
// If there is an unused patch entry, and then you update the patch,
1452+
// make sure `cargo update` will be able to fix the lock file.
1453+
Package::new("bar", "0.1.5").publish();
1454+
1455+
// Start with a lock file to 0.1.5, and an "unused" patch because the
1456+
// version is too old.
1457+
let p = project()
1458+
.file(
1459+
"Cargo.toml",
1460+
r#"
1461+
[package]
1462+
name = "foo"
1463+
version = "0.0.1"
1464+
1465+
[dependencies]
1466+
bar = "0.1.5"
1467+
1468+
[patch.crates-io]
1469+
bar = { path = "../bar" }
1470+
"#,
1471+
)
1472+
.file("src/lib.rs", "")
1473+
.build();
1474+
1475+
// Patch is too old.
1476+
let bar = project()
1477+
.at("bar")
1478+
.file("Cargo.toml", &basic_manifest("bar", "0.1.4"))
1479+
.file("src/lib.rs", "")
1480+
.build();
1481+
1482+
p.cargo("build")
1483+
.with_stderr_contains("[WARNING] Patch `bar v0.1.4 [..] was not used in the crate graph.")
1484+
.run();
1485+
// unused patch should be in the lock file
1486+
let lock = p.read_lockfile();
1487+
let toml: toml::Value = toml::from_str(&lock).unwrap();
1488+
assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
1489+
assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
1490+
assert_eq!(
1491+
toml["patch"]["unused"][0]["version"].as_str(),
1492+
Some("0.1.4")
1493+
);
1494+
1495+
// Oh, OK, let's update to the latest version.
1496+
bar.change_file("Cargo.toml", &basic_manifest("bar", "0.1.6"));
1497+
1498+
// Create a backup so we can test it with different options.
1499+
fs::copy(p.root().join("Cargo.lock"), p.root().join("Cargo.lock.bak")).unwrap();
1500+
1501+
// Try with `-p`.
1502+
p.cargo("update -p bar")
1503+
.with_stderr(
1504+
"\
1505+
[UPDATING] `[..]/registry` index
1506+
[ADDING] bar v0.1.6 ([..]/bar)
1507+
[REMOVING] bar v0.1.5
1508+
",
1509+
)
1510+
.run();
1511+
1512+
// Try with bare `cargo update`.
1513+
fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
1514+
p.cargo("update")
1515+
.with_stderr(
1516+
"\
1517+
[UPDATING] `[..]/registry` index
1518+
[ADDING] bar v0.1.6 ([..]/bar)
1519+
[REMOVING] bar v0.1.5
1520+
",
1521+
)
1522+
.run();
1523+
}

0 commit comments

Comments
 (0)