diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index 5ec46a63bce9..17f13105509a 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -7,7 +7,7 @@ use itertools::Itertools; use owo_colors::OwoColorize; use tracing::debug; -use distribution_types::Requirement; +use distribution_types::{Dist, Requirement}; use distribution_types::{ DistributionMetadata, IndexLocations, InstalledMetadata, InstalledVersion, LocalDist, Name, ParsedUrl, RequirementSource, Resolution, @@ -514,32 +514,7 @@ pub(crate) async fn install( } } - // TODO(konstin): Also check the cache whether any cached or installed dist is already known to - // have been yanked, we currently don't show this message on the second run anymore - for dist in &remote { - let Some(file) = dist.file() else { - continue; - }; - match &file.yanked { - None | Some(Yanked::Bool(false)) => {} - Some(Yanked::Bool(true)) => { - writeln!( - printer.stderr(), - "{}{} {dist} is yanked.", - "warning".yellow().bold(), - ":".bold(), - )?; - } - Some(Yanked::Reason(reason)) => { - writeln!( - printer.stderr(), - "{}{} {dist} is yanked (reason: \"{reason}\").", - "warning".yellow().bold(), - ":".bold(), - )?; - } - } - } + report_yanks(&remote, printer)?; Ok(()) } @@ -607,7 +582,7 @@ fn report_dry_run( ) .dimmed() )?; - remote + remote.clone() }; // Remove any upgraded or extraneous installations. @@ -682,6 +657,40 @@ fn report_dry_run( } } + report_yanks(&remote, printer)?; + + Ok(()) +} + +/// Report on any yanked distributions in the resolution. +pub(crate) fn report_yanks(remote: &[Dist], printer: Printer) -> Result<(), Error> { + // TODO(konstin): Also check the cache whether any cached or installed dist is already known to + // have been yanked, we currently don't show this message on the second run anymore + for dist in remote { + let Some(file) = dist.file() else { + continue; + }; + match &file.yanked { + None | Some(Yanked::Bool(false)) => {} + Some(Yanked::Bool(true)) => { + writeln!( + printer.stderr(), + "{}{} {dist} is yanked.", + "warning".yellow().bold(), + ":".bold(), + )?; + } + Some(Yanked::Reason(reason)) => { + writeln!( + printer.stderr(), + "{}{} {dist} is yanked (reason: \"{reason}\").", + "warning".yellow().bold(), + ":".bold(), + )?; + } + } + } + Ok(()) } diff --git a/crates/uv/tests/pip_sync.rs b/crates/uv/tests/pip_sync.rs index 737aed14aa6c..343c53bfab50 100644 --- a/crates/uv/tests/pip_sync.rs +++ b/crates/uv/tests/pip_sync.rs @@ -902,7 +902,7 @@ fn install_no_index_cached() -> Result<()> { } #[test] -fn warn_on_yanked_version() -> Result<()> { +fn warn_on_yanked() -> Result<()> { let context = TestContext::new("3.12"); // This version is yanked. @@ -928,6 +928,34 @@ fn warn_on_yanked_version() -> Result<()> { Ok(()) } +#[test] +fn warn_on_yanked_dry_run() -> Result<()> { + let context = TestContext::new("3.12"); + + // This version is yanked. + let requirements_in = context.temp_dir.child("requirements.txt"); + requirements_in.write_str("colorama==0.4.2")?; + + uv_snapshot!(context.filters(), windows_filters=false, command(&context) + .arg("requirements.txt") + .arg("--dry-run") + .arg("--strict"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Would download 1 package + Would install 1 package + + colorama==0.4.2 + warning: colorama==0.4.2 is yanked (reason: "Bad build, missing files, will not install"). + "### + ); + + Ok(()) +} + /// Resolve a local wheel. #[test] fn install_local_wheel() -> Result<()> {