From efbcff1a93ab8505684f39f7b325736ebd98ed57 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 19 Aug 2024 22:56:24 -0500 Subject: [PATCH] Special-case reinstalls in environment update summaries --- crates/distribution-types/src/any.rs | 37 ++++++++---- crates/distribution-types/src/cached.rs | 6 +- crates/distribution-types/src/installed.rs | 12 ++-- crates/distribution-types/src/lib.rs | 2 +- crates/distribution-types/src/traits.rs | 2 +- crates/uv/src/commands/mod.rs | 6 +- crates/uv/src/commands/pip/loggers.rs | 24 +++++++- crates/uv/src/commands/pip/operations.rs | 48 ++++++++++++---- crates/uv/tests/cache_prune.rs | 3 +- crates/uv/tests/edit.rs | 48 ++++++---------- crates/uv/tests/lock.rs | 3 +- crates/uv/tests/pip_install.rs | 27 +++------ crates/uv/tests/pip_sync.rs | 66 ++++++++-------------- crates/uv/tests/tool_install.rs | 42 +++++--------- 14 files changed, 164 insertions(+), 162 deletions(-) diff --git a/crates/distribution-types/src/any.rs b/crates/distribution-types/src/any.rs index d1bf078f41c4..1f39535a77f4 100644 --- a/crates/distribution-types/src/any.rs +++ b/crates/distribution-types/src/any.rs @@ -1,3 +1,5 @@ +use std::hash::Hash; + use uv_normalize::PackageName; use crate::cached::CachedDist; @@ -5,14 +7,16 @@ use crate::installed::InstalledDist; use crate::{InstalledMetadata, InstalledVersion, Name}; /// A distribution which is either installable, is a wheel in our cache or is already installed. -#[derive(Debug, Clone)] +/// +/// Note equality and hash operations are only based on the name and version, not the kind. +#[derive(Debug, Clone, Eq)] #[allow(clippy::large_enum_variant)] -pub enum LocalDist<'a> { - Cached(&'a CachedDist), - Installed(&'a InstalledDist), +pub enum LocalDist { + Cached(CachedDist), + Installed(InstalledDist), } -impl Name for LocalDist<'_> { +impl Name for LocalDist { fn name(&self) -> &PackageName { match self { Self::Cached(dist) => dist.name(), @@ -21,7 +25,7 @@ impl Name for LocalDist<'_> { } } -impl InstalledMetadata for LocalDist<'_> { +impl InstalledMetadata for LocalDist { fn installed_version(&self) -> InstalledVersion { match self { Self::Cached(dist) => dist.installed_version(), @@ -30,14 +34,27 @@ impl InstalledMetadata for LocalDist<'_> { } } -impl<'a> From<&'a CachedDist> for LocalDist<'a> { - fn from(dist: &'a CachedDist) -> Self { +impl From for LocalDist { + fn from(dist: CachedDist) -> Self { Self::Cached(dist) } } -impl<'a> From<&'a InstalledDist> for LocalDist<'a> { - fn from(dist: &'a InstalledDist) -> Self { +impl From for LocalDist { + fn from(dist: InstalledDist) -> Self { Self::Installed(dist) } } + +impl Hash for LocalDist { + fn hash(&self, state: &mut H) { + self.name().hash(state); + self.installed_version().hash(state); + } +} + +impl PartialEq for LocalDist { + fn eq(&self, other: &Self) -> bool { + self.name() == other.name() && self.installed_version() == other.installed_version() + } +} diff --git a/crates/distribution-types/src/cached.rs b/crates/distribution-types/src/cached.rs index 624b8a7273a6..8aa99107a5f4 100644 --- a/crates/distribution-types/src/cached.rs +++ b/crates/distribution-types/src/cached.rs @@ -13,7 +13,7 @@ use crate::{ }; /// A built distribution (wheel) that exists in the local cache. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum CachedDist { /// The distribution exists in a registry, like `PyPI`. Registry(CachedRegistryDist), @@ -21,14 +21,14 @@ pub enum CachedDist { Url(CachedDirectUrlDist), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct CachedRegistryDist { pub filename: WheelFilename, pub path: PathBuf, pub hashes: Vec, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct CachedDirectUrlDist { pub filename: WheelFilename, pub url: VerbatimUrl, diff --git a/crates/distribution-types/src/installed.rs b/crates/distribution-types/src/installed.rs index ecbab4addd89..510a75f84b67 100644 --- a/crates/distribution-types/src/installed.rs +++ b/crates/distribution-types/src/installed.rs @@ -16,7 +16,7 @@ use uv_normalize::PackageName; use crate::{DistributionMetadata, InstalledMetadata, InstalledVersion, Name, VersionOrUrlRef}; /// A built distribution (wheel) that is installed in a virtual environment. -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum InstalledDist { /// The distribution was derived from a registry, like `PyPI`. Registry(InstalledRegistryDist), @@ -30,14 +30,14 @@ pub enum InstalledDist { LegacyEditable(InstalledLegacyEditable), } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InstalledRegistryDist { pub name: PackageName, pub version: Version, pub path: PathBuf, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InstalledDirectUrlDist { pub name: PackageName, pub version: Version, @@ -47,21 +47,21 @@ pub struct InstalledDirectUrlDist { pub path: PathBuf, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InstalledEggInfoFile { pub name: PackageName, pub version: Version, pub path: PathBuf, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InstalledEggInfoDirectory { pub name: PackageName, pub version: Version, pub path: PathBuf, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct InstalledLegacyEditable { pub name: PackageName, pub version: Version, diff --git a/crates/distribution-types/src/lib.rs b/crates/distribution-types/src/lib.rs index 640792e2fc92..b9db7d5fc2fb 100644 --- a/crates/distribution-types/src/lib.rs +++ b/crates/distribution-types/src/lib.rs @@ -115,7 +115,7 @@ impl std::fmt::Display for VersionOrUrlRef<'_> { } } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum InstalledVersion<'a> { /// A PEP 440 version specifier, used to identify a distribution in a registry. Version(&'a Version), diff --git a/crates/distribution-types/src/traits.rs b/crates/distribution-types/src/traits.rs index 81e229726776..ebd9c2ada822 100644 --- a/crates/distribution-types/src/traits.rs +++ b/crates/distribution-types/src/traits.rs @@ -117,7 +117,7 @@ impl Verbatim for T { } // Implement `Display` for all known types that implement `Metadata`. -impl std::fmt::Display for LocalDist<'_> { +impl std::fmt::Display for LocalDist { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}{}", self.name(), self.installed_version()) } diff --git a/crates/uv/src/commands/mod.rs b/crates/uv/src/commands/mod.rs index 61b57a1ad42b..e2446a6b6a5b 100644 --- a/crates/uv/src/commands/mod.rs +++ b/crates/uv/src/commands/mod.rs @@ -113,11 +113,13 @@ pub(super) enum ChangeEventKind { Removed, /// The package was added to the environment. Added, + /// The package was reinstalled without changing versions. + Reinstalled, } #[derive(Debug)] -pub(super) struct ChangeEvent { - dist: T, +pub(super) struct ChangeEvent<'a, T: InstalledMetadata> { + dist: &'a T, kind: ChangeEventKind, } diff --git a/crates/uv/src/commands/pip/loggers.rs b/crates/uv/src/commands/pip/loggers.rs index bbaabdfe259f..8aba931d6527 100644 --- a/crates/uv/src/commands/pip/loggers.rs +++ b/crates/uv/src/commands/pip/loggers.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use owo_colors::OwoColorize; use rustc_hash::{FxBuildHasher, FxHashMap}; -use distribution_types::{InstalledMetadata, LocalDist, Name}; +use distribution_types::{InstalledMetadata, Name}; use pep440_rs::Version; use uv_normalize::PackageName; @@ -108,13 +108,22 @@ impl InstallLogger for DefaultInstallLogger { .uninstalled .iter() .map(|distribution| ChangeEvent { - dist: LocalDist::from(distribution), + dist: distribution, kind: ChangeEventKind::Removed, }) .chain(changelog.installed.iter().map(|distribution| ChangeEvent { - dist: LocalDist::from(distribution), + dist: distribution, kind: ChangeEventKind::Added, })) + .chain( + changelog + .reinstalled + .iter() + .map(|distribution| ChangeEvent { + dist: distribution, + kind: ChangeEventKind::Reinstalled, + }), + ) .sorted_unstable_by(|a, b| { a.dist .name() @@ -142,6 +151,15 @@ impl InstallLogger for DefaultInstallLogger { event.dist.installed_version().dimmed() )?; } + ChangeEventKind::Reinstalled => { + writeln!( + printer.stderr(), + " {} {}{}", + "~".yellow(), + event.dist.name().bold(), + event.dist.installed_version().dimmed() + )?; + } } } Ok(()) diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index f5bbd9bf26ee..5bb479295f26 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -3,13 +3,14 @@ use anyhow::{anyhow, Context}; use itertools::Itertools; use owo_colors::OwoColorize; -use std::collections::BTreeSet; +use std::collections::{BTreeSet, HashSet}; use std::fmt::Write; use std::path::PathBuf; use tracing::debug; use distribution_types::{ - CachedDist, Diagnostic, InstalledDist, ResolutionDiagnostic, UnresolvedRequirementSpecification, + CachedDist, Diagnostic, InstalledDist, LocalDist, ResolutionDiagnostic, + UnresolvedRequirementSpecification, }; use distribution_types::{ DistributionMetadata, IndexLocations, InstalledMetadata, Name, Resolution, @@ -289,17 +290,38 @@ pub(crate) enum Modifications { #[derive(Debug, Clone, Default)] pub(crate) struct Changelog { /// The distributions that were installed. - pub(crate) installed: Vec, + pub(crate) installed: HashSet, /// The distributions that were uninstalled. - pub(crate) uninstalled: Vec, + pub(crate) uninstalled: HashSet, + /// The distributions that were reinstalled. + pub(crate) reinstalled: HashSet, } impl Changelog { + /// Create a [`Changelog`] from a list of installed and uninstalled distributions. + pub(crate) fn new(installed: Vec, uninstalled: Vec) -> Self { + let mut uninstalled: HashSet<_> = uninstalled.into_iter().map(LocalDist::from).collect(); + + let (reinstalled, installed): (HashSet<_>, HashSet<_>) = installed + .into_iter() + .map(LocalDist::from) + .partition(|dist| uninstalled.contains(dist)); + + uninstalled.retain(|dist| !reinstalled.contains(dist)); + + Self { + installed, + uninstalled, + reinstalled, + } + } + /// Create a [`Changelog`] from a list of installed distributions. pub(crate) fn from_installed(installed: Vec) -> Self { Self { - installed, - uninstalled: vec![], + installed: installed.into_iter().map(LocalDist::from).collect(), + uninstalled: HashSet::default(), + reinstalled: HashSet::default(), } } @@ -474,10 +496,7 @@ pub(crate) async fn install( } // Construct a summary of the changes made to the environment. - let changelog = Changelog { - installed: installs, - uninstalled: uninstalls, - }; + let changelog = Changelog::new(installs, uninstalls); // Notify the user of any environment modifications. logger.on_complete(&changelog, printer)?; @@ -619,6 +638,15 @@ fn report_dry_run( event.version.dimmed() )?; } + ChangeEventKind::Reinstalled => { + writeln!( + printer.stderr(), + " {} {}{}", + "~".yellow(), + event.name.bold(), + event.version.dimmed() + )?; + } } } diff --git a/crates/uv/tests/cache_prune.rs b/crates/uv/tests/cache_prune.rs index a0b9b11bf850..6a3ee83a1a58 100644 --- a/crates/uv/tests/cache_prune.rs +++ b/crates/uv/tests/cache_prune.rs @@ -224,8 +224,7 @@ fn prune_unzipped() -> Result<()> { Uninstalled 2 packages in [TIME] Installed 1 package in [TIME] - iniconfig==2.0.0 - - source-distribution==0.0.1 - + source-distribution==0.0.1 + ~ source-distribution==0.0.1 "###); requirements_txt.write_str(indoc! { r" diff --git a/crates/uv/tests/edit.rs b/crates/uv/tests/edit.rs index a0372b579d26..3851b440f6d2 100644 --- a/crates/uv/tests/edit.rs +++ b/crates/uv/tests/edit.rs @@ -192,8 +192,7 @@ fn add_git() -> Result<()> { Prepared 2 packages in [TIME] Uninstalled 1 package in [TIME] Installed 2 packages in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979) "###); @@ -606,8 +605,7 @@ fn add_git_raw() -> Result<()> { Prepared 2 packages in [TIME] Uninstalled 1 package in [TIME] Installed 2 packages in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979) "###); @@ -762,8 +760,7 @@ fn add_git_implicit() -> Result<()> { Prepared 2 packages in [TIME] Uninstalled 1 package in [TIME] Installed 2 packages in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage.git@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) "###); @@ -1050,8 +1047,7 @@ fn add_remove_dev() -> Result<()> { Installed 1 package in [TIME] - anyio==3.7.0 - idna==3.6 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) - sniffio==1.3.1 "###); @@ -1260,8 +1256,7 @@ fn add_remove_optional() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -1470,8 +1465,7 @@ fn add_remove_workspace() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 2 packages in [TIME] Installed 1 package in [TIME] - - child1==0.1.0 (from file://[TEMP_DIR]/child1) - + child1==0.1.0 (from file://[TEMP_DIR]/child1) + ~ child1==0.1.0 (from file://[TEMP_DIR]/child1) - child2==0.1.0 (from file://[TEMP_DIR]/child2) "###); @@ -1718,8 +1712,7 @@ fn update() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -1753,8 +1746,7 @@ fn update() -> Result<()> { Uninstalled 1 package in [TIME] Installed 3 packages in [TIME] + chardet==5.2.0 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) + pysocks==1.7.1 "###); @@ -1791,8 +1783,7 @@ fn update() -> Result<()> { Prepared 2 packages in [TIME] Uninstalled 2 packages in [TIME] Installed 2 packages in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) - requests==2.31.0 + requests==2.32.3 (from git+https://github.com/psf/requests@0e322af87745eff34caffe4df68456ebc20d9068) "###); @@ -2005,8 +1996,7 @@ fn add_update_marker() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -2041,8 +2031,7 @@ fn add_update_marker() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -2079,8 +2068,7 @@ fn add_update_marker() -> Result<()> { Installed 3 packages in [TIME] - idna==3.6 + idna==2.7 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) - urllib3==2.2.1 + urllib3==1.23 "###); @@ -2118,8 +2106,7 @@ fn add_update_marker() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -2160,8 +2147,7 @@ fn add_update_marker() -> Result<()> { - certifi==2024.2.2 - charset-normalizer==3.3.2 - idna==2.7 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) - requests==2.31.0 - urllib3==1.23 "###); @@ -2308,8 +2294,7 @@ fn add_no_clean() -> Result<()> { Uninstalled 1 package in [TIME] Installed 2 packages in [TIME] + iniconfig==2.0.0 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -2446,8 +2431,7 @@ fn remove_registry() -> Result<()> { Installed 1 package in [TIME] - anyio==3.7.0 - idna==3.6 - - project==0.1.0 (from file://[TEMP_DIR]/) - + project==0.1.0 (from file://[TEMP_DIR]/) + ~ project==0.1.0 (from file://[TEMP_DIR]/) - sniffio==1.3.1 "###); diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index c529c11f6813..30c6c2851aa0 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -5607,8 +5607,7 @@ fn lock_redact_https() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - foo==0.1.0 (from file://[TEMP_DIR]/) - + foo==0.1.0 (from file://[TEMP_DIR]/) + ~ foo==0.1.0 (from file://[TEMP_DIR]/) "###); Ok(()) diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index 479536c2033c..91fbdfda16bc 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -562,8 +562,7 @@ fn respect_installed_and_reinstall() -> Result<()> { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - flask==3.0.2 - + flask==3.0.2 + ~ flask==3.0.2 "### ); @@ -1819,8 +1818,7 @@ fn reinstall_no_binary() { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - anyio==4.3.0 - + anyio==4.3.0 + ~ anyio==4.3.0 "### ); @@ -2968,8 +2966,7 @@ requires-python = ">=3.8" Installed 2 packages in [TIME] - anyio==4.0.0 + anyio==3.7.1 - - example==0.0.0 (from file://[TEMP_DIR]/editable) - + example==0.0.0 (from file://[TEMP_DIR]/editable) + ~ example==0.0.0 (from file://[TEMP_DIR]/editable) "### ); @@ -3111,8 +3108,7 @@ requires-python = ">=3.8" Installed 2 packages in [TIME] - anyio==4.0.0 + anyio==3.7.1 - - example==0.0.0 (from file://[TEMP_DIR]/editable) - + example==0.0.0 (from file://[TEMP_DIR]/editable) + ~ example==0.0.0 (from file://[TEMP_DIR]/editable) "### ); @@ -4416,8 +4412,7 @@ fn already_installed_dependent_editable() { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) - + first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) + ~ first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) "### ); } @@ -4515,8 +4510,7 @@ fn already_installed_local_path_dependent() { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) - + first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) + ~ first-local==0.1.0 (from file://[WORKSPACE]/scripts/packages/dependent_locals/first_local) "### ); @@ -4645,8 +4639,7 @@ fn already_installed_local_version_of_remote_package() { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.3.0+foo (from file://[WORKSPACE]/scripts/packages/anyio_local) - + anyio==4.3.0+foo (from file://[WORKSPACE]/scripts/packages/anyio_local) + ~ anyio==4.3.0+foo (from file://[WORKSPACE]/scripts/packages/anyio_local) "### ); @@ -4768,8 +4761,7 @@ fn already_installed_multiple_versions() -> Result<()> { Uninstalled 2 packages in [TIME] Installed 1 package in [TIME] - anyio==3.7.0 - - anyio==4.0.0 - + anyio==4.0.0 + ~ anyio==4.0.0 "### ); @@ -4902,8 +4894,7 @@ fn already_installed_remote_url() { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) - + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) + ~ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) "###); // Request installation again with a different version diff --git a/crates/uv/tests/pip_sync.rs b/crates/uv/tests/pip_sync.rs index 605500ab2866..eff9da962b6f 100644 --- a/crates/uv/tests/pip_sync.rs +++ b/crates/uv/tests/pip_sync.rs @@ -1146,8 +1146,7 @@ fn install_local_wheel() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - tomli==2.0.1 (from file://[TEMP_DIR]/tomli-2.0.1-py3-none-any.whl) - + tomli==2.0.1 (from file://[TEMP_DIR]/tomli-2.0.1-py3-none-any.whl) + ~ tomli==2.0.1 (from file://[TEMP_DIR]/tomli-2.0.1-py3-none-any.whl) "### ); @@ -1993,10 +1992,8 @@ fn reinstall() -> Result<()> { Prepared 2 packages in [TIME] Uninstalled 2 packages in [TIME] Installed 2 packages in [TIME] - - markupsafe==2.1.3 - + markupsafe==2.1.3 - - tomli==2.0.1 - + tomli==2.0.1 + ~ markupsafe==2.1.3 + ~ tomli==2.0.1 "### ); @@ -2048,8 +2045,7 @@ fn reinstall_package() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - tomli==2.0.1 - + tomli==2.0.1 + ~ tomli==2.0.1 "### ); @@ -2102,8 +2098,7 @@ fn reinstall_git() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) - + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) + ~ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389) "### ); @@ -2292,8 +2287,7 @@ fn sync_editable() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - poetry-editable==0.1.0 (from file://[TEMP_DIR]/poetry_editable) - + poetry-editable==0.1.0 (from file://[TEMP_DIR]/poetry_editable) + ~ poetry-editable==0.1.0 (from file://[TEMP_DIR]/poetry_editable) "### ); @@ -2389,8 +2383,7 @@ fn sync_editable() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - poetry-editable==0.1.1 (from file://[TEMP_DIR]/poetry_editable) - + poetry-editable==0.1.1 (from file://[TEMP_DIR]/poetry_editable) + ~ poetry-editable==0.1.1 (from file://[TEMP_DIR]/poetry_editable) "### ); @@ -2563,8 +2556,7 @@ fn sync_editable_and_local() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - black==0.1.0 (from file://[TEMP_DIR]/black_editable) - + black==0.1.0 (from file://[TEMP_DIR]/black_editable) + ~ black==0.1.0 (from file://[TEMP_DIR]/black_editable) "### ); @@ -2585,8 +2577,7 @@ fn sync_editable_and_local() -> Result<()> { Resolved 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - black==0.1.0 (from file://[TEMP_DIR]/black_editable) - + black==0.1.0 (from file://[TEMP_DIR]/black_editable) + ~ black==0.1.0 (from file://[TEMP_DIR]/black_editable) "### ); @@ -2838,8 +2829,7 @@ fn find_links_wheel_cache() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - tqdm==1000.0.0 - + tqdm==1000.0.0 + ~ tqdm==1000.0.0 "### ); @@ -2889,8 +2879,7 @@ fn find_links_source_cache() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - tqdm==999.0.0 - + tqdm==999.0.0 + ~ tqdm==999.0.0 "### ); @@ -3271,8 +3260,7 @@ requires-python = ">=3.8" Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - example==0.0.0 (from file://[TEMP_DIR]/editable) - + example==0.0.0 (from file://[TEMP_DIR]/editable) + ~ example==0.0.0 (from file://[TEMP_DIR]/editable) "### ); @@ -3805,8 +3793,7 @@ fn require_hashes_source_url() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - source-distribution==0.0.1 (from https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz) - + source-distribution==0.0.1 (from https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz) + ~ source-distribution==0.0.1 (from https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz) "### ); @@ -3907,8 +3894,7 @@ fn require_hashes_wheel_url() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) - + anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) + ~ anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) "### ); @@ -4121,8 +4107,7 @@ fn require_hashes_re_download() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 - + anyio==4.0.0 + ~ anyio==4.0.0 "### ); @@ -4414,8 +4399,7 @@ fn require_hashes_repeated_hash() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) - + anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) + ~ anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) "### ); @@ -4440,8 +4424,7 @@ fn require_hashes_repeated_hash() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) - + anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) + ~ anyio==4.0.0 (from https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl) "### ); @@ -4522,8 +4505,7 @@ fn require_hashes_at_least_one() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 - + anyio==4.0.0 + ~ anyio==4.0.0 "### ); @@ -4545,8 +4527,7 @@ fn require_hashes_at_least_one() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - anyio==4.0.0 - + anyio==4.0.0 + ~ anyio==4.0.0 "### ); @@ -4661,8 +4642,7 @@ fn require_hashes_find_links_no_hash() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - example-a-961b4c22==1.0.0 - + example-a-961b4c22==1.0.0 + ~ example-a-961b4c22==1.0.0 "### ); @@ -4806,8 +4786,7 @@ fn require_hashes_find_links_invalid_hash() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - example-a-961b4c22==1.0.0 - + example-a-961b4c22==1.0.0 + ~ example-a-961b4c22==1.0.0 "### ); @@ -5014,8 +4993,7 @@ fn require_hashes_registry_invalid_hash() -> Result<()> { Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] Installed 1 package in [TIME] - - example-a-961b4c22==1.0.0 - + example-a-961b4c22==1.0.0 + ~ example-a-961b4c22==1.0.0 "### ); diff --git a/crates/uv/tests/tool_install.rs b/crates/uv/tests/tool_install.rs index df92e4db766a..0829361198bd 100644 --- a/crates/uv/tests/tool_install.rs +++ b/crates/uv/tests/tool_install.rs @@ -910,18 +910,12 @@ fn tool_install_already_installed() { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - black==24.3.0 - + black==24.3.0 - - click==8.1.7 - + click==8.1.7 - - mypy-extensions==1.0.0 - + mypy-extensions==1.0.0 - - packaging==24.0 - + packaging==24.0 - - pathspec==0.12.1 - + pathspec==0.12.1 - - platformdirs==4.2.0 - + platformdirs==4.2.0 + ~ black==24.3.0 + ~ click==8.1.7 + ~ mypy-extensions==1.0.0 + ~ packaging==24.0 + ~ pathspec==0.12.1 + ~ platformdirs==4.2.0 Installed 2 executables: black, blackd "###); @@ -944,8 +938,7 @@ fn tool_install_already_installed() { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - black==24.3.0 - + black==24.3.0 + ~ black==24.3.0 Installed 2 executables: black, blackd "###); @@ -968,8 +961,7 @@ fn tool_install_already_installed() { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - click==8.1.7 - + click==8.1.7 + ~ click==8.1.7 Installed 2 executables: black, blackd "###); } @@ -1169,18 +1161,12 @@ fn tool_install_entry_point_exists() { Prepared [N] packages in [TIME] Uninstalled [N] packages in [TIME] Installed [N] packages in [TIME] - - black==24.3.0 - + black==24.3.0 - - click==8.1.7 - + click==8.1.7 - - mypy-extensions==1.0.0 - + mypy-extensions==1.0.0 - - packaging==24.0 - + packaging==24.0 - - pathspec==0.12.1 - + pathspec==0.12.1 - - platformdirs==4.2.0 - + platformdirs==4.2.0 + ~ black==24.3.0 + ~ click==8.1.7 + ~ mypy-extensions==1.0.0 + ~ packaging==24.0 + ~ pathspec==0.12.1 + ~ platformdirs==4.2.0 Installed 2 executables: black, blackd "###);