From 62cc00c27904fc53428bcb18c3958b55c65ab561 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 | 74 ++++++++++++++-------- crates/uv/src/main.rs | 2 +- crates/uv/src/settings.rs | 5 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 2ad27927e30bd..6bae971b74647 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -2096,6 +2096,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 bdd4c7e82e3f7..5158b7268b062 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,32 +65,41 @@ pub(crate) async fn uninstall( { found = true; if matching_installations.insert(installation.clone()) { + if matches!(requests.as_slice(), [PythonRequest::Any]) { + writeln!( + printer.stderr(), + "Found existing installation: {}", + 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); + } else { writeln!( printer.stderr(), - "Found existing installation for {}: {}", - request.cyan(), - installation.key().green(), + "No existing installations found for: {}", + request.cyan() )?; } } - if !found { - writeln!( - printer.stderr(), - "No existing installations found for: {}", - request.cyan() - )?; - } } 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); } diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index 4385b9b04c8f7..2c3a49dd36639 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -785,7 +785,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 04ba352a6118c..17c783a3cf487 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 } } }