From a0f984b0f976bd44167df1ac5b84d50a0ece1ff1 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 9 Jul 2024 11:00:45 -0700 Subject: [PATCH] Enable --all to uninstall all managed Pythons --- crates/uv-cli/src/lib.rs | 4 ++ crates/uv/src/commands/python/uninstall.rs | 64 +++++++++++++--------- crates/uv/src/main.rs | 2 +- crates/uv/src/settings.rs | 5 +- 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 9e73e2ee4a87..db2f1eddb50a 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -2198,6 +2198,10 @@ pub struct PythonUninstallArgs { /// The Python version(s) to uninstall. #[arg(required = true)] pub targets: Vec, + + /// Uninstall all managed Python versions. + #[arg(long, conflicts_with("targets"))] + pub all: bool, } #[derive(Args)] diff --git a/crates/uv/src/commands/python/uninstall.rs b/crates/uv/src/commands/python/uninstall.rs index bdd4c7e82e3f..79b98293eae6 100644 --- a/crates/uv/src/commands/python/uninstall.rs +++ b/crates/uv/src/commands/python/uninstall.rs @@ -18,6 +18,7 @@ use crate::printer::Printer; /// Uninstall managed Python versions. pub(crate) async fn uninstall( targets: Vec, + all: bool, preview: PreviewMode, printer: Printer, ) -> Result { @@ -30,11 +31,15 @@ pub(crate) async fn uninstall( let installations = ManagedPythonInstallations::from_settings()?.init()?; let _lock = installations.acquire_lock()?; - let targets = targets.into_iter().collect::>(); - let requests = targets - .iter() - .map(|target| PythonRequest::parse(target.as_str())) - .collect::>(); + let requests = if all { + vec![PythonRequest::Any] + } else { + let targets = targets.into_iter().collect::>(); + targets + .iter() + .map(|target| PythonRequest::parse(target.as_str())) + .collect::>() + }; let download_requests = requests .iter() @@ -44,11 +49,15 @@ pub(crate) async fn uninstall( let installed_installations: Vec<_> = installations.find_all()?.collect(); let mut matching_installations = BTreeSet::default(); for (request, download_request) in requests.iter().zip(download_requests) { - writeln!( - printer.stderr(), - "Searching for Python versions matching: {}", - request.cyan() - )?; + if matches!(requests.as_slice(), [PythonRequest::Any]) { + writeln!(printer.stderr(), "Searching for Python installations")?; + } else { + writeln!( + printer.stderr(), + "Searching for Python versions matching: {}", + request.cyan() + )?; + } let mut found = false; for installation in installed_installations .iter() @@ -56,15 +65,24 @@ pub(crate) async fn uninstall( { found = true; if matching_installations.insert(installation.clone()) { - writeln!( - printer.stderr(), - "Found existing installation for {}: {}", - request.cyan(), - installation.key().green(), - )?; + if matches!(requests.as_slice(), [PythonRequest::Any]) { + writeln!(printer.stderr(), "Found: {}", installation.key().green(),)?; + } else { + writeln!( + printer.stderr(), + "Found existing installation for {}: {}", + request.cyan(), + installation.key().green(), + )?; + } } } if !found { + if matches!(requests.as_slice(), [PythonRequest::Any]) { + writeln!(printer.stderr(), "No Python installations found")?; + return Ok(ExitStatus::Failure); + } + writeln!( printer.stderr(), "No existing installations found for: {}", @@ -74,14 +92,10 @@ pub(crate) async fn uninstall( } if matching_installations.is_empty() { - if matches!(requests.as_slice(), [PythonRequest::Any]) { - writeln!(printer.stderr(), "No Python installations found")?; - } else if requests.len() > 1 { - writeln!( - printer.stderr(), - "No Python installations found matching the requests" - )?; - } + writeln!( + printer.stderr(), + "No Python installations found matching the requests" + )?; return Ok(ExitStatus::Failure); } @@ -105,7 +119,7 @@ pub(crate) async fn uninstall( key.green() )?; } else { - writeln!(printer.stderr(), "Uninstalled {}", key.green())?; + writeln!(printer.stderr(), "Uninstalled: {}", key.green())?; } } diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index d19f71a30cd3..aac5b2cbe205 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -788,7 +788,7 @@ async fn run() -> Result { let args = settings::PythonUninstallSettings::resolve(args, filesystem); show_settings!(args); - commands::python_uninstall(args.targets, globals.preview, printer).await + commands::python_uninstall(args.targets, args.all, globals.preview, printer).await } Commands::Python(PythonNamespace { command: PythonCommand::Find(args), diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 6ad2f23a6fab..476d21feb5bf 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -376,6 +376,7 @@ impl PythonInstallSettings { #[derive(Debug, Clone)] pub(crate) struct PythonUninstallSettings { pub(crate) targets: Vec, + pub(crate) all: bool, } impl PythonUninstallSettings { @@ -385,9 +386,9 @@ impl PythonUninstallSettings { args: PythonUninstallArgs, _filesystem: Option, ) -> Self { - let PythonUninstallArgs { targets } = args; + let PythonUninstallArgs { targets, all } = args; - Self { targets } + Self { targets, all } } }