Skip to content

Commit

Permalink
feat(update): Report when incompatible-rust-version packages are sele…
Browse files Browse the repository at this point in the history
…cted

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.
  • Loading branch information
epage committed Aug 14, 2024
1 parent 374701e commit 209c3c9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
57 changes: 45 additions & 12 deletions src/cargo/ops/cargo_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,14 @@ fn print_lockfile_generation(
};

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

if let Some(latest) = latest {
if let Some(note) = note {
ws.gctx().shell().status_with_color(
"Adding",
format!("{package}{latest}"),
format!("{package}{note}"),
&style::NOTE,
)?;
}
Expand Down Expand Up @@ -594,11 +596,13 @@ fn print_lockfile_sync(
}
} else {
for package in diff.added.iter() {
let latest = report_latest(&possibilities, *package).unwrap_or_default();
let required_rust_version = report_required_rust_version(ws, resolve, *package);
let latest = report_latest(&possibilities, *package);
let note = required_rust_version.or(latest).unwrap_or_default();

ws.gctx().shell().status_with_color(
"Adding",
format!("{package}{latest}"),
format!("{package}{note}"),
&style::NOTE,
)?;
}
Expand Down Expand Up @@ -637,15 +641,17 @@ fn print_lockfile_updates(
};

if let Some((removed, added)) = diff.change() {
let latest = report_latest(&possibilities, *added).unwrap_or_default();
let required_rust_version = report_required_rust_version(ws, resolve, *added);
let latest = report_latest(&possibilities, *added);
let note = required_rust_version.or(latest).unwrap_or_default();

let msg = if removed.source_id().is_git() {
format!(
"{removed} -> #{}",
"{removed} -> #{}{note}",
&added.source_id().precise_git_fragment().unwrap()[..8],
)
} else {
format!("{removed} -> v{}{latest}", added.version())
format!("{removed} -> v{}{note}", added.version())
};

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

ws.gctx().shell().status_with_color(
"Adding",
format!("{package}{latest}"),
format!("{package}{note}"),
&style::NOTE,
)?;
}
}
for package in &diff.unchanged {
let required_rust_version = report_required_rust_version(ws, resolve, *package);
let latest = report_latest(&possibilities, *package);
let note = required_rust_version.as_deref().or(latest.as_deref());

if let Some(latest) = latest {
unchanged_behind += 1;
if let Some(note) = note {
if latest.is_some() {
unchanged_behind += 1;
}
if ws.gctx().shell().verbosity() == Verbosity::Verbose {
ws.gctx().shell().status_with_color(
"Unchanged",
format!("{package}{latest}"),
format!("{package}{note}"),
&anstyle::Style::new().bold(),
)?;
}
Expand Down Expand Up @@ -751,6 +763,27 @@ fn required_rust_version(ws: &Workspace<'_>) -> Option<PartialVersion> {
}
}

fn report_required_rust_version(
ws: &Workspace<'_>,
resolve: &Resolve,
package: PackageId,
) -> Option<String> {
if package.source_id().is_path() {
return None;
}
let summary = resolve.summary(package);
let package_rust_version = summary.rust_version()?;
let workspace_rust_version = required_rust_version(ws)?;
if package_rust_version.is_compatible_with(&workspace_rust_version) {
return None;
}

let warn = style::WARN;
Some(format!(
" {warn}(requires Rust {package_rust_version}){warn:#}"
))
}

fn report_latest(possibilities: &[IndexSummary], package: PackageId) -> Option<String> {
if possibilities.is_empty() {
return None;
Expand Down
9 changes: 8 additions & 1 deletion tests/testsuite/rust_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ foo v0.0.1 ([ROOT]/foo)
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -315,6 +316,7 @@ foo v0.0.1 ([ROOT]/foo)
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.2345)
"#]])
.run();
Expand Down Expand Up @@ -387,6 +389,7 @@ foo v0.0.1 ([ROOT]/foo)
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] has-rust-version v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -484,6 +487,7 @@ higher v0.0.1 ([ROOT]/foo)
[UPDATING] `dummy-registry` index
[LOCKING] 4 packages to latest Rust 1.50.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -612,6 +616,7 @@ fn resolve_edition2024() {
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -715,6 +720,7 @@ fn resolve_v3() {
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -932,7 +938,7 @@ fn update_precise_overrides_msrv_resolver() {
.masquerade_as_nightly_cargo(&["msrv-policy"])
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
[UPDATING] bar v1.5.0 -> v1.6.0
[UPDATING] bar v1.5.0 -> v1.6.0 (requires Rust 1.65.0)
"#]])
.run();
Expand Down Expand Up @@ -1010,6 +1016,7 @@ foo v0.0.1 ([ROOT]/foo)
[UPDATING] `dummy-registry` index
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
[ADDING] only-newer v1.6.0 (requires Rust 1.65.0)
[DOWNLOADING] crates ...
[DOWNLOADED] newer-and-older v1.5.0 (registry `dummy-registry`)
[CHECKING] newer-and-older v1.5.0
Expand Down

0 comments on commit 209c3c9

Please sign in to comment.