From 676d5504102fa2c001ba8cf5519b48f99d4ff658 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 2 Jul 2024 17:03:39 -0400 Subject: [PATCH] Remove dangling environments in `tool uninstall` (#4740) ## Summary It seems useful that `tool uninstall` guarantees the tool is gone (e.g., if the receipt and environment get out-of-sync somehow). --- crates/uv/src/commands/tool/uninstall.rs | 17 ++++++++++++++++- crates/uv/tests/tool_uninstall.rs | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/uv/src/commands/tool/uninstall.rs b/crates/uv/src/commands/tool/uninstall.rs index 1740b3d0d..27d4f8611 100644 --- a/crates/uv/src/commands/tool/uninstall.rs +++ b/crates/uv/src/commands/tool/uninstall.rs @@ -25,7 +25,22 @@ pub(crate) async fn uninstall( let installed_tools = InstalledTools::from_settings()?; let Some(receipt) = installed_tools.get_tool_receipt(&name)? else { - bail!("Tool `{}` is not installed", name); + // If the tool is not installed, attempt to remove the environment anyway. + match installed_tools.remove_environment(&name) { + Ok(()) => { + writeln!( + printer.stderr(), + "Removed dangling environment for tool: `{name}` (missing receipt)" + )?; + return Ok(ExitStatus::Success); + } + Err(uv_tool::Error::IO(err)) if err.kind() == std::io::ErrorKind::NotFound => { + bail!("Tool `{name}` is not installed"); + } + Err(err) => { + return Err(err.into()); + } + } }; // Remove the tool itself. diff --git a/crates/uv/tests/tool_uninstall.rs b/crates/uv/tests/tool_uninstall.rs index f78685b9c..06402bbe6 100644 --- a/crates/uv/tests/tool_uninstall.rs +++ b/crates/uv/tests/tool_uninstall.rs @@ -108,12 +108,12 @@ fn tool_uninstall_missing_receipt() { uv_snapshot!(context.filters(), context.tool_uninstall().arg("black") .env("UV_TOOL_DIR", tool_dir.as_os_str()) .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- warning: `uv tool uninstall` is experimental and may change without warning. - error: Tool `black` is not installed + Removed dangling environment for tool: `black` (missing receipt) "###); }