diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 49cbdc72098a5..5fb97ce7e5a6a 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -511,6 +511,9 @@ pub struct SelfUpdateArgs { /// A token is not required but can be used to reduce the chance of encountering rate limits. #[arg(long, env = EnvVars::UV_GITHUB_TOKEN)] pub token: Option, + + #[arg(long)] + pub dry_run: bool, } #[derive(Args)] diff --git a/crates/uv/src/commands/self_update.rs b/crates/uv/src/commands/self_update.rs index 1ba48666cec91..96853ff040dda 100644 --- a/crates/uv/src/commands/self_update.rs +++ b/crates/uv/src/commands/self_update.rs @@ -15,6 +15,7 @@ use crate::printer::Printer; pub(crate) async fn self_update( version: Option, token: Option, + dry_run: bool, printer: Printer, ) -> Result { let mut updater = AxoUpdater::new_for("uv"); @@ -87,7 +88,31 @@ pub(crate) async fn self_update( UpdateRequest::Latest }; - updater.configure_version_specifier(update_request); + updater.configure_version_specifier(update_request.clone()); + + if dry_run { + // TODO: `updater.fetch_release` is not public, we can't say what the latest version is + if updater.is_update_needed().await? { + // TODO: `updater.version_specifier` is not public + let version = match update_request { + UpdateRequest::Latest | UpdateRequest::LatestMaybePrerelease => { + "the latest version".to_string() + } + UpdateRequest::SpecificTag(version) | UpdateRequest::SpecificVersion(version) => { + format!("v{version}") + } + }; + writeln!( + printer.stderr(), + "Would upgrade uv from {} to {}", + format!("v{}", env!("CARGO_PKG_VERSION")).bold().white(), + version.bold().white(), + )?; + } else { + write_is_latest(&printer)?; + } + return Ok(ExitStatus::Success); + } // Run the updater. This involves a network request, since we need to determine the latest // available version of uv. @@ -120,16 +145,7 @@ pub(crate) async fn self_update( )?; } Ok(None) => { - writeln!( - printer.stderr(), - "{}", - format_args!( - "{}{} You're on the latest version of uv ({})", - "success".green().bold(), - ":".bold(), - format!("v{}", env!("CARGO_PKG_VERSION")).bold().white() - ) - )?; + write_is_latest(&printer)?; } Err(err) => { return if let AxoupdateError::Reqwest(err) = err { @@ -156,3 +172,17 @@ pub(crate) async fn self_update( Ok(ExitStatus::Success) } + +fn write_is_latest(printer: &Printer) -> Result<(), anyhow::Error> { + writeln!( + printer.stderr(), + "{}", + format_args!( + "{}{} You're on the latest version of uv ({})", + "success".green().bold(), + ":".bold(), + format!("v{}", env!("CARGO_PKG_VERSION")).bold().white() + ) + )?; + Ok(()) +} diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 8b326f5cb9bba..b34d5fdf9ac0c 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -838,8 +838,9 @@ async fn run(mut cli: Cli) -> Result { SelfCommand::Update(SelfUpdateArgs { target_version, token, + dry_run, }), - }) => commands::self_update(target_version, token, printer).await, + }) => commands::self_update(target_version, token, dry_run, printer).await, #[cfg(not(feature = "self-update"))] Commands::Self_(_) => { anyhow::bail!(