Skip to content

Commit

Permalink
Enable --all to uninstall all managed Pythons
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jul 9, 2024
1 parent 8da91f5 commit a0f984b
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 28 deletions.
4 changes: 4 additions & 0 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2198,6 +2198,10 @@ pub struct PythonUninstallArgs {
/// The Python version(s) to uninstall.
#[arg(required = true)]
pub targets: Vec<String>,

/// Uninstall all managed Python versions.
#[arg(long, conflicts_with("targets"))]
pub all: bool,
}

#[derive(Args)]
Expand Down
64 changes: 39 additions & 25 deletions crates/uv/src/commands/python/uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::printer::Printer;
/// Uninstall managed Python versions.
pub(crate) async fn uninstall(
targets: Vec<String>,
all: bool,
preview: PreviewMode,
printer: Printer,
) -> Result<ExitStatus> {
Expand All @@ -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::<BTreeSet<_>>();
let requests = targets
.iter()
.map(|target| PythonRequest::parse(target.as_str()))
.collect::<Vec<_>>();
let requests = if all {
vec![PythonRequest::Any]
} else {
let targets = targets.into_iter().collect::<BTreeSet<_>>();
targets
.iter()
.map(|target| PythonRequest::parse(target.as_str()))
.collect::<Vec<_>>()
};

let download_requests = requests
.iter()
Expand All @@ -44,27 +49,40 @@ 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()
.filter(|installation| download_request.satisfied_by_key(installation.key()))
{
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: {}",
Expand All @@ -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);
}

Expand All @@ -105,7 +119,7 @@ pub(crate) async fn uninstall(
key.green()
)?;
} else {
writeln!(printer.stderr(), "Uninstalled {}", key.green())?;
writeln!(printer.stderr(), "Uninstalled: {}", key.green())?;
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/uv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ async fn run() -> Result<ExitStatus> {
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),
Expand Down
5 changes: 3 additions & 2 deletions crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ impl PythonInstallSettings {
#[derive(Debug, Clone)]
pub(crate) struct PythonUninstallSettings {
pub(crate) targets: Vec<String>,
pub(crate) all: bool,
}

impl PythonUninstallSettings {
Expand All @@ -385,9 +386,9 @@ impl PythonUninstallSettings {
args: PythonUninstallArgs,
_filesystem: Option<FilesystemOptions>,
) -> Self {
let PythonUninstallArgs { targets } = args;
let PythonUninstallArgs { targets, all } = args;

Self { targets }
Self { targets, all }
}
}

Expand Down

0 comments on commit a0f984b

Please sign in to comment.