Skip to content

Commit

Permalink
Use reinstall report formatting for uv python install --reinstall (#…
Browse files Browse the repository at this point in the history
…8487)

## Summary

Resolves #8456

## Test Plan

```console
$ cargo run -- python install 3.13
$ cargo run -- python install --reinstall 3.13
Searching for Python versions matching: Python 3.13
Found existing installation for Python 3.13: cpython-3.13.0-macos-aarch64-none
Installed Python 3.13.0 in 7.39s
 ~ cpython-3.13.0-macos-aarch64-none
```

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
  • Loading branch information
j178 and charliermarsh authored Oct 23, 2024
1 parent e9c08b1 commit 9540d6a
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 15 deletions.
2 changes: 1 addition & 1 deletion crates/uv-python/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub enum EnvironmentPreference {
Any,
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum PythonVariant {
#[default]
Default,
Expand Down
1 change: 1 addition & 0 deletions crates/uv-python/src/installation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,5 +405,6 @@ impl Ord for PythonInstallationKey {
.then_with(|| self.os.to_string().cmp(&other.os.to_string()))
.then_with(|| self.arch.to_string().cmp(&other.arch.to_string()))
.then_with(|| self.libc.to_string().cmp(&other.libc.to_string()))
.then_with(|| self.variant.cmp(&other.variant))
}
}
36 changes: 25 additions & 11 deletions crates/uv/src/commands/python/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use futures::stream::FuturesUnordered;
use futures::StreamExt;
use itertools::Itertools;
use owo_colors::OwoColorize;
use rustc_hash::FxHashSet;
use std::collections::BTreeSet;
use std::fmt::Write;
use std::path::Path;
Expand Down Expand Up @@ -63,7 +64,7 @@ pub(crate) async fn install(
.inspect(|installation| debug!("Found existing installation {}", installation.key()))
.collect();
let mut unfilled_requests = Vec::new();
let mut uninstalled = Vec::new();
let mut uninstalled = FxHashSet::default();
for (request, download_request) in requests.iter().zip(download_requests) {
if matches!(requests.as_slice(), [PythonRequest::Default]) {
writeln!(printer.stderr(), "Searching for Python installations")?;
Expand All @@ -89,7 +90,7 @@ pub(crate) async fn install(
)?;
}
if reinstall {
uninstalled.push(installation.key().clone());
uninstalled.insert(installation.key());
unfilled_requests.push(download_request);
}
} else {
Expand Down Expand Up @@ -155,7 +156,7 @@ pub(crate) async fn install(
});
}

let mut installed = vec![];
let mut installed = FxHashSet::default();
let mut errors = vec![];
while let Some((key, result)) = tasks.next().await {
match result {
Expand All @@ -166,7 +167,7 @@ pub(crate) async fn install(
DownloadResult::Fetched(path) => path,
};

installed.push(key.clone());
installed.insert(key);

// Ensure the installations have externally managed markers
let managed = ManagedPythonInstallation::new(path.clone())?;
Expand All @@ -180,7 +181,8 @@ pub(crate) async fn install(
}

if !installed.is_empty() {
if let [installed] = installed.as_slice() {
if installed.len() == 1 {
let installed = installed.iter().next().unwrap();
// Ex) "Installed Python 3.9.7 in 1.68s"
writeln!(
printer.stderr(),
Expand All @@ -194,29 +196,38 @@ pub(crate) async fn install(
)?;
} else {
// Ex) "Installed 2 versions in 1.68s"
let s = if installed.len() == 1 { "" } else { "s" };
writeln!(
printer.stderr(),
"{}",
format!(
"Installed {} {}",
format!("{} version{s}", installed.len()).bold(),
format!("{} versions", installed.len()).bold(),
format!("in {}", elapsed(start.elapsed())).dimmed()
)
.dimmed()
)?;
}

let reinstalled = uninstalled
.intersection(&installed)
.copied()
.collect::<FxHashSet<_>>();
let uninstalled = uninstalled.difference(&reinstalled).copied();
let installed = installed.difference(&reinstalled).copied();

for event in uninstalled
.into_iter()
.map(|key| ChangeEvent {
key,
key: key.clone(),
kind: ChangeEventKind::Removed,
})
.chain(installed.into_iter().map(|key| ChangeEvent {
key,
.chain(installed.map(|key| ChangeEvent {
key: key.clone(),
kind: ChangeEventKind::Added,
}))
.chain(reinstalled.iter().map(|&key| ChangeEvent {
key: key.clone(),
kind: ChangeEventKind::Reinstalled,
}))
.sorted_unstable_by(|a, b| a.key.cmp(&b.key).then_with(|| a.kind.cmp(&b.kind)))
{
match event.kind {
Expand All @@ -226,6 +237,9 @@ pub(crate) async fn install(
ChangeEventKind::Removed => {
writeln!(printer.stderr(), " {} {}", "-".red(), event.key.bold())?;
}
ChangeEventKind::Reinstalled => {
writeln!(printer.stderr(), " {} {}", "~".yellow(), event.key.bold(),)?;
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/uv/src/commands/python/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub(super) enum ChangeEventKind {
Removed,
/// The Python version was installed.
Added,
/// The Python version was reinstalled.
Reinstalled,
}

#[derive(Debug)]
Expand Down
4 changes: 1 addition & 3 deletions crates/uv/src/commands/python/uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,10 @@ async fn do_uninstall(
.sorted_unstable_by(|a, b| a.key.cmp(&b.key).then_with(|| a.kind.cmp(&b.kind)))
{
match event.kind {
ChangeEventKind::Added => {
writeln!(printer.stderr(), " {} {}", "+".green(), event.key.bold())?;
}
ChangeEventKind::Removed => {
writeln!(printer.stderr(), " {} {}", "-".red(), event.key.bold())?;
}
_ => unreachable!(),
}
}
}
Expand Down

0 comments on commit 9540d6a

Please sign in to comment.