mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-16 21:38:31 +00:00
Improve interactions with existing Python executables during install (#8733)
Previously, we'd use the `--reinstall` flag to determine if we should replace existing Python executables in the bin directory during an install. There are a few problems with this: - We replace executables we don't manage - We can replace executables from other uv Python installations during reinstall (surprising) - We don't do the "right" thing when installing patch versions e.g. installing `3.12.4` then `3.12.6` would fail without the reinstall flag In `uv tool`, we have separate `--force` and `--reinstall` concepts. Here we separate the flags (`--force` was previously just a `--reinstall` alias) and add inspection of the existing executables to inform a decision on replacement. In brief, we will: - Replace any executables with `--force` - Replace executables for the same installation with `--reinstall` - Replace executables for an older patch version by default
This commit is contained in:
parent
6a6b9af466
commit
fb1d679f69
10 changed files with 354 additions and 38 deletions
|
@ -88,7 +88,7 @@ pub enum Error {
|
|||
LibcDetection(#[from] LibcDetectionError),
|
||||
}
|
||||
/// A collection of uv-managed Python installations installed on the current system.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ManagedPythonInstallations {
|
||||
/// The path to the top-level directory of the installed Python versions.
|
||||
root: PathBuf,
|
||||
|
@ -542,6 +542,35 @@ impl ManagedPythonInstallation {
|
|||
unreachable!("Only Windows and Unix are supported")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if self is a suitable upgrade of other.
|
||||
pub fn is_upgrade_of(&self, other: &ManagedPythonInstallation) -> bool {
|
||||
// Require matching implementation
|
||||
if self.key.implementation != other.key.implementation {
|
||||
return false;
|
||||
}
|
||||
// Require a matching variant
|
||||
if self.key.variant != other.key.variant {
|
||||
return false;
|
||||
}
|
||||
// Require matching minor version
|
||||
if (self.key.major, self.key.minor) != (other.key.major, other.key.minor) {
|
||||
return false;
|
||||
}
|
||||
// Require a newer, or equal patch version (for pre-release upgrades)
|
||||
if self.key.patch <= other.key.patch {
|
||||
return false;
|
||||
}
|
||||
if let Some(other_pre) = other.key.prerelease {
|
||||
if let Some(self_pre) = self.key.prerelease {
|
||||
return self_pre > other_pre;
|
||||
}
|
||||
// Do not upgrade from non-prerelease to prerelease
|
||||
return false;
|
||||
}
|
||||
// Do not upgrade if the patch versions are the same
|
||||
self.key.patch != other.key.patch
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a platform portion of a key from the environment.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue