Skip to content

Commit 9319f95

Browse files
epageantoniospg
authored andcommitted
feat(update): Report when incompatible-rust-version packages are selected
In discussin this in rust-lang#13873, it highlighted that we need to make sure we tell people when we get in this state. I decided to keep "latest" and "required rust version" messages mutually exclusive to avoid too much noise. I gave "required rust version" higher precedence as its the more critical to operation and, if you are using an MSRV-incompatible package, it likely is "latest" already. I was tempted to change colors to make "required rust version" stand out from "latest" but was unsure what direction to go, so I held off. Options included - red for "required rust version", yellow for "latest" - yellow for "required rust version", nothing for "latest" There is also more discussion on how to format "latest" at rust-lang#13908.
1 parent 645ac10 commit 9319f95

File tree

2 files changed

+53
-13
lines changed

2 files changed

+53
-13
lines changed

src/cargo/ops/cargo_update.rs

+45-12
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,14 @@ fn print_lockfile_generation(
514514
};
515515

516516
for package in diff.added.iter() {
517+
let required_rust_version = report_required_rust_version(ws, resolve, *package);
517518
let latest = report_latest(&possibilities, *package);
519+
let note = required_rust_version.or(latest);
518520

519-
if let Some(latest) = latest {
521+
if let Some(note) = note {
520522
ws.gctx().shell().status_with_color(
521523
"Adding",
522-
format!("{package}{latest}"),
524+
format!("{package}{note}"),
523525
&style::NOTE,
524526
)?;
525527
}
@@ -594,11 +596,13 @@ fn print_lockfile_sync(
594596
}
595597
} else {
596598
for package in diff.added.iter() {
597-
let latest = report_latest(&possibilities, *package).unwrap_or_default();
599+
let required_rust_version = report_required_rust_version(ws, resolve, *package);
600+
let latest = report_latest(&possibilities, *package);
601+
let note = required_rust_version.or(latest).unwrap_or_default();
598602

599603
ws.gctx().shell().status_with_color(
600604
"Adding",
601-
format!("{package}{latest}"),
605+
format!("{package}{note}"),
602606
&style::NOTE,
603607
)?;
604608
}
@@ -637,15 +641,17 @@ fn print_lockfile_updates(
637641
};
638642

639643
if let Some((removed, added)) = diff.change() {
640-
let latest = report_latest(&possibilities, *added).unwrap_or_default();
644+
let required_rust_version = report_required_rust_version(ws, resolve, *added);
645+
let latest = report_latest(&possibilities, *added);
646+
let note = required_rust_version.or(latest).unwrap_or_default();
641647

642648
let msg = if removed.source_id().is_git() {
643649
format!(
644-
"{removed} -> #{}",
650+
"{removed} -> #{}{note}",
645651
&added.source_id().precise_git_fragment().unwrap()[..8],
646652
)
647653
} else {
648-
format!("{removed} -> v{}{latest}", added.version())
654+
format!("{removed} -> v{}{note}", added.version())
649655
};
650656

651657
// If versions differ only in build metadata, we call it an "update"
@@ -670,24 +676,30 @@ fn print_lockfile_updates(
670676
)?;
671677
}
672678
for package in diff.added.iter() {
673-
let latest = report_latest(&possibilities, *package).unwrap_or_default();
679+
let required_rust_version = report_required_rust_version(ws, resolve, *package);
680+
let latest = report_latest(&possibilities, *package);
681+
let note = required_rust_version.or(latest).unwrap_or_default();
674682

675683
ws.gctx().shell().status_with_color(
676684
"Adding",
677-
format!("{package}{latest}"),
685+
format!("{package}{note}"),
678686
&style::NOTE,
679687
)?;
680688
}
681689
}
682690
for package in &diff.unchanged {
691+
let required_rust_version = report_required_rust_version(ws, resolve, *package);
683692
let latest = report_latest(&possibilities, *package);
693+
let note = required_rust_version.as_deref().or(latest.as_deref());
684694

685-
if let Some(latest) = latest {
686-
unchanged_behind += 1;
695+
if let Some(note) = note {
696+
if latest.is_some() {
697+
unchanged_behind += 1;
698+
}
687699
if ws.gctx().shell().verbosity() == Verbosity::Verbose {
688700
ws.gctx().shell().status_with_color(
689701
"Unchanged",
690-
format!("{package}{latest}"),
702+
format!("{package}{note}"),
691703
&anstyle::Style::new().bold(),
692704
)?;
693705
}
@@ -751,6 +763,27 @@ fn required_rust_version(ws: &Workspace<'_>) -> Option<PartialVersion> {
751763
}
752764
}
753765

766+
fn report_required_rust_version(
767+
ws: &Workspace<'_>,
768+
resolve: &Resolve,
769+
package: PackageId,
770+
) -> Option<String> {
771+
if package.source_id().is_path() {
772+
return None;
773+
}
774+
let summary = resolve.summary(package);
775+
let package_rust_version = summary.rust_version()?;
776+
let workspace_rust_version = required_rust_version(ws)?;
777+
if package_rust_version.is_compatible_with(&workspace_rust_version) {
778+
return None;
779+
}
780+
781+
let warn = style::WARN;
782+
Some(format!(
783+
" {warn}(requires Rust {package_rust_version}){warn:#}"
784+
))
785+
}
786+
754787
fn report_latest(possibilities: &[IndexSummary], package: PackageId) -> Option<String> {
755788
if !package.source_id().is_registry() {
756789
return None;

tests/testsuite/rust_version.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ foo v0.0.1 ([ROOT]/foo)
241241
[UPDATING] `dummy-registry` index
242242
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
243243
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
244+
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
244245
245246
"#]])
246247
.run();
@@ -315,6 +316,7 @@ foo v0.0.1 ([ROOT]/foo)
315316
[UPDATING] `dummy-registry` index
316317
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
317318
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
319+
[ADDING] only-newer v1.6.0 (requires Rust 1.2345)
318320
319321
"#]])
320322
.run();
@@ -387,6 +389,7 @@ foo v0.0.1 ([ROOT]/foo)
387389
.with_stderr_data(str![[r#"
388390
[UPDATING] `dummy-registry` index
389391
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
392+
[ADDING] has-rust-version v1.6.0 (requires Rust 1.65.0)
390393
391394
"#]])
392395
.run();
@@ -484,6 +487,7 @@ higher v0.0.1 ([ROOT]/foo)
484487
[UPDATING] `dummy-registry` index
485488
[LOCKING] 4 packages to latest Rust 1.50.0 compatible versions
486489
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
490+
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
487491
488492
"#]])
489493
.run();
@@ -612,6 +616,7 @@ fn resolve_edition2024() {
612616
[UPDATING] `dummy-registry` index
613617
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
614618
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
619+
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
615620
616621
"#]])
617622
.run();
@@ -715,6 +720,7 @@ fn resolve_v3() {
715720
[UPDATING] `dummy-registry` index
716721
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
717722
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
723+
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
718724
719725
"#]])
720726
.run();
@@ -932,7 +938,7 @@ fn update_precise_overrides_msrv_resolver() {
932938
.masquerade_as_nightly_cargo(&["msrv-policy"])
933939
.with_stderr_data(str![[r#"
934940
[UPDATING] `dummy-registry` index
935-
[UPDATING] bar v1.5.0 -> v1.6.0
941+
[UPDATING] bar v1.5.0 -> v1.6.0 (requires Rust 1.65.0)
936942
937943
"#]])
938944
.run();
@@ -1010,6 +1016,7 @@ foo v0.0.1 ([ROOT]/foo)
10101016
[UPDATING] `dummy-registry` index
10111017
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
10121018
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
1019+
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
10131020
[DOWNLOADING] crates ...
10141021
[DOWNLOADED] newer-and-older v1.5.0 (registry `dummy-registry`)
10151022
[CHECKING] newer-and-older v1.5.0

0 commit comments

Comments
 (0)