Skip to content

Commit f096a94

Browse files
committed
fix: update --breaking now understands package@version.
1 parent 8882d05 commit f096a94

File tree

2 files changed

+53
-10
lines changed

2 files changed

+53
-10
lines changed

src/cargo/ops/cargo_update.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ pub fn upgrade_manifests(
222222
let mut upgrades = HashMap::new();
223223
let mut upgrade_messages = HashSet::new();
224224

225+
let to_update = to_update
226+
.iter()
227+
.map(|s| PackageIdSpec::parse(s))
228+
.collect::<Result<Vec<_>, _>>()?;
229+
225230
// Updates often require a lot of modifications to the registry, so ensure
226231
// that we're synchronized against other Cargos.
227232
let _lock = gctx.acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;
@@ -239,7 +244,7 @@ pub fn upgrade_manifests(
239244
.try_map_dependencies(|d| {
240245
upgrade_dependency(
241246
&gctx,
242-
to_update,
247+
&to_update,
243248
&mut registry,
244249
&mut upgrades,
245250
&mut upgrade_messages,
@@ -253,7 +258,7 @@ pub fn upgrade_manifests(
253258

254259
fn upgrade_dependency(
255260
gctx: &GlobalContext,
256-
to_update: &Vec<String>,
261+
to_update: &Vec<PackageIdSpec>,
257262
registry: &mut PackageRegistry<'_>,
258263
upgrades: &mut UpgradeMap,
259264
upgrade_messages: &mut HashSet<String>,
@@ -267,7 +272,18 @@ fn upgrade_dependency(
267272
return Ok(dependency);
268273
}
269274

270-
if !to_update.is_empty() && !to_update.contains(&name.to_string()) {
275+
if !to_update.is_empty()
276+
&& !to_update.iter().any(|spec| {
277+
spec.name() == name.as_str()
278+
&& dependency.source_id().is_registry()
279+
&& spec
280+
.url()
281+
.map_or(true, |url| url == dependency.source_id().url())
282+
&& spec
283+
.version()
284+
.map_or(true, |v| dependency.version_req().matches(&v))
285+
})
286+
{
271287
trace!("skipping dependency `{name}` not selected for upgrading");
272288
return Ok(dependency);
273289
}

tests/testsuite/update.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -2261,7 +2261,11 @@ fn update_breaking_spec_version() {
22612261
// Invalid spec
22622262
p.cargo("update -Zunstable-options --breaking incompatible@foo")
22632263
.masquerade_as_nightly_cargo(&["update-breaking"])
2264-
.with_stderr_data(str![[r#""#]])
2264+
.with_status(101)
2265+
.with_stderr_data(str![[r#"
2266+
[ERROR] expected a version like "1.32"
2267+
2268+
"#]])
22652269
.run();
22662270

22672271
// Spec version not matching our current dependencies
@@ -2279,20 +2283,35 @@ fn update_breaking_spec_version() {
22792283
// Accepted spec
22802284
p.cargo("update -Zunstable-options --breaking [email protected]")
22812285
.masquerade_as_nightly_cargo(&["update-breaking"])
2282-
.with_stderr_data(str![[r#""#]])
2286+
.with_stderr_data(str![[r#"
2287+
[UPDATING] `[..]` index
2288+
[UPGRADING] incompatible ^1.0 -> ^2.0
2289+
[LOCKING] 1 package to latest compatible version
2290+
[UPDATING] incompatible v1.0.0 -> v2.0.0
2291+
2292+
"#]])
22832293
.run();
22842294

22852295
// Accepted spec, full format
22862296
Package::new("incompatible", "3.0.0").publish();
22872297
p.cargo("update -Zunstable-options --breaking https://github.com/rust-lang/crates.io-index#[email protected]")
22882298
.masquerade_as_nightly_cargo(&["update-breaking"])
2289-
.with_stderr_data(str![[r#""#]])
2299+
.with_stderr_data(str![[r#"
2300+
[UPDATING] `[..]` index
2301+
[UPGRADING] incompatible ^2.0 -> ^3.0
2302+
[LOCKING] 1 package to latest compatible version
2303+
[UPDATING] incompatible v2.0.0 -> v3.0.0
2304+
2305+
"#]])
22902306
.run();
22912307

22922308
// Spec matches a dependency that will not be upgraded
22932309
p.cargo("update -Zunstable-options --breaking [email protected]")
22942310
.masquerade_as_nightly_cargo(&["update-breaking"])
2295-
.with_stderr_data(str![[r#""#]])
2311+
.with_stderr_data(str![[r#"
2312+
[UPDATING] `[..]` index
2313+
2314+
"#]])
22962315
.run();
22972316

22982317
// Non-existing versions
@@ -2352,14 +2371,22 @@ fn update_breaking_spec_version_transitive() {
23522371
// Will upgrade the direct dependency
23532372
p.cargo("update -Zunstable-options --breaking [email protected]")
23542373
.masquerade_as_nightly_cargo(&["update-breaking"])
2355-
// FIXME: Should upgrade a dependency here.
2356-
.with_stderr_data(str![[r#""#]])
2374+
.with_stderr_data(str![[r#"
2375+
[UPDATING] `[..]` index
2376+
[UPGRADING] dep ^1.0 -> ^2.0
2377+
[LOCKING] 1 package to latest compatible version
2378+
[ADDING] dep v2.0.0
2379+
2380+
"#]])
23572381
.run();
23582382

23592383
// But not the transitive one, because bar is not a workspace member
23602384
p.cargo("update -Zunstable-options --breaking [email protected]")
23612385
.masquerade_as_nightly_cargo(&["update-breaking"])
2362-
.with_stderr_data(str![[r#""#]])
2386+
.with_stderr_data(str![[r#"
2387+
[UPDATING] `[..]` index
2388+
2389+
"#]])
23632390
.run();
23642391

23652392
// A non-breaking update is different, as it will update transitive dependencies

0 commit comments

Comments
 (0)