diff --git a/crates/uv-distribution/src/distribution_database.rs b/crates/uv-distribution/src/distribution_database.rs index 95b52b516051..ca1432bd5e00 100644 --- a/crates/uv-distribution/src/distribution_database.rs +++ b/crates/uv-distribution/src/distribution_database.rs @@ -72,8 +72,7 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> { /// Set the [`Reporter`] to use for this source distribution fetcher. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { - let reporter = Arc::new(reporter); + pub fn with_reporter(self, reporter: Arc) -> Self { Self { reporter: Some(reporter.clone()), builder: self.builder.with_reporter(reporter), diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index 227b2f2fca53..393099cf2202 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -1319,7 +1319,11 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { resource.git, client.unmanaged.uncached_client(resource.url).clone(), self.build_context.cache().bucket(CacheBucket::Git), - self.reporter.clone().map(Facade::from), + self.reporter + .clone() + .map(Facade::from) + .map(Arc::new) + .map(|reporter| reporter as _), ) .await?; @@ -1416,7 +1420,11 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { resource.git, client.unmanaged.uncached_client(resource.url).clone(), self.build_context.cache().bucket(CacheBucket::Git), - self.reporter.clone().map(Facade::from), + self.reporter + .clone() + .map(Facade::from) + .map(Arc::new) + .map(|reporter| reporter as _), ) .await?; @@ -1592,7 +1600,11 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { &source.git, client.unmanaged.uncached_client(&source.url).clone(), self.build_context.cache().bucket(CacheBucket::Git), - self.reporter.clone().map(Facade::from), + self.reporter + .clone() + .map(Facade::from) + .map(Arc::new) + .map(|reporter| reporter as _), ) .await?; } @@ -1603,7 +1615,11 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { source.git, client.unmanaged.uncached_client(source.url).clone(), self.build_context.cache().bucket(CacheBucket::Git), - self.reporter.clone().map(Facade::from), + self.reporter + .clone() + .map(Facade::from) + .map(Arc::new) + .map(|reporter| reporter as _), ) .await?; } diff --git a/crates/uv-git/src/resolver.rs b/crates/uv-git/src/resolver.rs index e0636ec243d3..741ee7acb9d2 100644 --- a/crates/uv-git/src/resolver.rs +++ b/crates/uv-git/src/resolver.rs @@ -44,7 +44,7 @@ impl GitResolver { url: &GitUrl, client: ClientWithMiddleware, cache: PathBuf, - reporter: Option, + reporter: Option>, ) -> Result { debug!("Resolving source distribution from Git: {url}"); @@ -88,7 +88,7 @@ impl GitResolver { url: &GitUrl, client: ClientWithMiddleware, cache: PathBuf, - reporter: Option, + reporter: Option>, ) -> Result { debug!("Fetching source distribution from Git: {url}"); @@ -138,7 +138,7 @@ impl GitResolver { /// For example, given a Git dependency with a reference to a branch or tag, return a URL /// with a precise reference to the current commit of that branch or tag. /// - /// This method takes into account various normalizations that are independent from the Git + /// This method takes into account various normalizations that are independent of the Git /// layer. For example: removing `#subdirectory=pkg_dir`-like fragments, and removing `git+` /// prefix kinds. /// diff --git a/crates/uv-git/src/source.rs b/crates/uv-git/src/source.rs index 5b475af90fd6..2c29decff20a 100644 --- a/crates/uv-git/src/source.rs +++ b/crates/uv-git/src/source.rs @@ -2,11 +2,11 @@ //! Cargo is dual-licensed under either Apache 2.0 or MIT, at the user's choice. //! Source: -use std::borrow::Cow; -use std::path::{Path, PathBuf}; - use anyhow::Result; use reqwest_middleware::ClientWithMiddleware; +use std::borrow::Cow; +use std::path::{Path, PathBuf}; +use std::sync::Arc; use tracing::{debug, instrument}; use url::Url; @@ -24,11 +24,11 @@ pub struct GitSource { /// The path to the Git source database. cache: PathBuf, /// The reporter to use for this source. - reporter: Option>, + reporter: Option>, } impl GitSource { - /// Initialize a new Git source. + /// Initialize a [`GitSource`] with the given Git URL, HTTP client, and cache path. pub fn new( git: GitUrl, client: impl Into, @@ -42,11 +42,11 @@ impl GitSource { } } - /// Set the [`Reporter`] to use for this `GIt` source. + /// Set the [`Reporter`] to use for the [`GitSource`]. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { - reporter: Some(Box::new(reporter)), + reporter: Some(reporter), ..self } } diff --git a/crates/uv-installer/src/installer.rs b/crates/uv-installer/src/installer.rs index f8fa0cbc0980..d37bdab4514b 100644 --- a/crates/uv-installer/src/installer.rs +++ b/crates/uv-installer/src/installer.rs @@ -1,7 +1,7 @@ use anyhow::{Context, Error, Result}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use std::convert; -use std::sync::LazyLock; +use std::sync::{Arc, LazyLock}; use tokio::sync::oneshot; use tracing::instrument; use uv_install_wheel::{linker::LinkMode, Layout}; @@ -15,7 +15,7 @@ pub struct Installer<'a> { venv: &'a PythonEnvironment, link_mode: LinkMode, cache: Option<&'a Cache>, - reporter: Option>, + reporter: Option>, installer_name: Option, installer_metadata: bool, } @@ -50,9 +50,9 @@ impl<'a> Installer<'a> { /// Set the [`Reporter`] to use for this installer. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { - reporter: Some(Box::new(reporter)), + reporter: Some(reporter), ..self } } @@ -66,7 +66,7 @@ impl<'a> Installer<'a> { } } - /// Set the whether to link Uv specific files in dist-info + /// Set whether to install uv-specifier files in the dist-info directory. #[must_use] pub fn with_installer_metadata(self, installer_metadata: bool) -> Self { Self { @@ -151,7 +151,7 @@ fn install( layout: Layout, installer_name: Option, link_mode: LinkMode, - reporter: Option>, + reporter: Option>, relocatable: bool, installer_metadata: bool, ) -> Result> { diff --git a/crates/uv-installer/src/preparer.rs b/crates/uv-installer/src/preparer.rs index fac49057025c..cd35c1881591 100644 --- a/crates/uv-installer/src/preparer.rs +++ b/crates/uv-installer/src/preparer.rs @@ -48,15 +48,16 @@ impl<'a, Context: BuildContext> Preparer<'a, Context> { /// Set the [`Reporter`] to use for operations. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { - let reporter: Arc = Arc::new(reporter); + pub fn with_reporter(self, reporter: Arc) -> Self { Self { tags: self.tags, cache: self.cache, hashes: self.hashes, build_options: self.build_options, - database: self.database.with_reporter(Facade::from(reporter.clone())), - reporter: Some(reporter.clone()), + database: self + .database + .with_reporter(Arc::new(Facade::from(reporter.clone()))), + reporter: Some(reporter), } } @@ -269,7 +270,7 @@ pub trait Reporter: Send + Sync { fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize); } -/// A facade for converting from [`Reporter`] to [`uv_git::Reporter`]. +/// A facade for converting from [`Reporter`] to [`uv_distribution::Reporter`]. struct Facade { reporter: Arc, } diff --git a/crates/uv-requirements/src/extras.rs b/crates/uv-requirements/src/extras.rs index 2d72f6b1f214..d8c2e6959271 100644 --- a/crates/uv-requirements/src/extras.rs +++ b/crates/uv-requirements/src/extras.rs @@ -37,7 +37,7 @@ impl<'a, Context: BuildContext> ExtrasResolver<'a, Context> { /// Set the [`Reporter`] to use for this resolver. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { database: self.database.with_reporter(reporter), ..self diff --git a/crates/uv-requirements/src/lookahead.rs b/crates/uv-requirements/src/lookahead.rs index 77c18ea81ab1..3f191ed172e7 100644 --- a/crates/uv-requirements/src/lookahead.rs +++ b/crates/uv-requirements/src/lookahead.rs @@ -67,7 +67,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> { /// Set the [`Reporter`] to use for this resolver. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { database: self.database.with_reporter(reporter), ..self diff --git a/crates/uv-requirements/src/source_tree.rs b/crates/uv-requirements/src/source_tree.rs index 569c658b6200..74acfd67e5fe 100644 --- a/crates/uv-requirements/src/source_tree.rs +++ b/crates/uv-requirements/src/source_tree.rs @@ -65,7 +65,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> { /// Set the [`Reporter`] to use for this resolver. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { database: self.database.with_reporter(reporter), ..self diff --git a/crates/uv-requirements/src/unnamed.rs b/crates/uv-requirements/src/unnamed.rs index 252cc368e1d5..9356e42dea7c 100644 --- a/crates/uv-requirements/src/unnamed.rs +++ b/crates/uv-requirements/src/unnamed.rs @@ -49,7 +49,7 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> { /// Set the [`Reporter`] to use for this resolver. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { + pub fn with_reporter(self, reporter: Arc) -> Self { Self { database: self.database.with_reporter(reporter), ..self diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index aeeebb8d9ebc..6fb152173c82 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -245,15 +245,15 @@ impl /// Set the [`Reporter`] to use for this installer. #[must_use] - pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self { - let reporter = Arc::new(reporter); - + pub fn with_reporter(self, reporter: Arc) -> Self { Self { state: ResolverState { reporter: Some(reporter.clone()), ..self.state }, - provider: self.provider.with_reporter(Facade { reporter }), + provider: self + .provider + .with_reporter(Arc::new(Facade::from(reporter))), } } diff --git a/crates/uv-resolver/src/resolver/provider.rs b/crates/uv-resolver/src/resolver/provider.rs index 29e02384699e..2c243796fad6 100644 --- a/crates/uv-resolver/src/resolver/provider.rs +++ b/crates/uv-resolver/src/resolver/provider.rs @@ -2,7 +2,7 @@ use std::future::Future; use std::sync::Arc; use uv_configuration::BuildOptions; -use uv_distribution::{ArchiveMetadata, DistributionDatabase}; +use uv_distribution::{ArchiveMetadata, DistributionDatabase, Reporter}; use uv_distribution_types::{Dist, IndexCapabilities, IndexUrl}; use uv_normalize::PackageName; use uv_pep440::{Version, VersionSpecifiers}; @@ -91,9 +91,9 @@ pub trait ResolverProvider { dist: &'io Dist, ) -> impl Future + 'io; - /// Set the [`uv_distribution::Reporter`] to use for this installer. + /// Set the [`Reporter`] to use for this installer. #[must_use] - fn with_reporter(self, reporter: impl uv_distribution::Reporter + 'static) -> Self; + fn with_reporter(self, reporter: Arc) -> Self; } /// The main IO backend for the resolver, which does cached requests network requests using the @@ -253,9 +253,9 @@ impl<'a, Context: BuildContext> ResolverProvider for DefaultResolverProvider<'a, } } - /// Set the [`uv_distribution::Reporter`] to use for this installer. + /// Set the [`Reporter`] to use for this installer. #[must_use] - fn with_reporter(self, reporter: impl uv_distribution::Reporter + 'static) -> Self { + fn with_reporter(self, reporter: Arc) -> Self { Self { fetcher: self.fetcher.with_reporter(reporter), ..self diff --git a/crates/uv-resolver/src/resolver/reporter.rs b/crates/uv-resolver/src/resolver/reporter.rs index 3010ec6388c8..db5854d170d7 100644 --- a/crates/uv-resolver/src/resolver/reporter.rs +++ b/crates/uv-resolver/src/resolver/reporter.rs @@ -39,7 +39,13 @@ pub trait Reporter: Send + Sync { /// A facade for converting from [`Reporter`] to [`uv_distribution::Reporter`]. pub(crate) struct Facade { - pub(crate) reporter: Arc, + reporter: Arc, +} + +impl From> for Facade { + fn from(reporter: Arc) -> Self { + Self { reporter } + } } impl uv_distribution::Reporter for Facade { diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index b9ad40512a25..6a0193baa431 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -6,6 +6,7 @@ use owo_colors::OwoColorize; use std::collections::{BTreeSet, HashSet}; use std::fmt::Write; use std::path::PathBuf; +use std::sync::Arc; use tracing::debug; use uv_tool::InstalledTools; @@ -138,7 +139,7 @@ pub(crate) async fn resolve( index, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(unnamed.into_iter()) .await?, ); @@ -152,7 +153,7 @@ pub(crate) async fn resolve( index, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(source_trees.iter().map(PathBuf::as_path)) .await?; @@ -221,7 +222,7 @@ pub(crate) async fn resolve( index, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(unnamed.into_iter()) .await?, ); @@ -251,7 +252,7 @@ pub(crate) async fn resolve( index, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(&resolver_env) .await? } @@ -297,7 +298,7 @@ pub(crate) async fn resolve( installed_packages, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), )? - .with_reporter(reporter); + .with_reporter(Arc::new(reporter)); resolver.resolve().await? }; @@ -460,7 +461,9 @@ pub(crate) async fn install( build_options, DistributionDatabase::new(client, build_dispatch, concurrency.downloads), ) - .with_reporter(PrepareReporter::from(printer).with_length(remote.len() as u64)); + .with_reporter(Arc::new( + PrepareReporter::from(printer).with_length(remote.len() as u64), + )); let wheels = preparer .prepare(remote.clone(), in_flight, resolution) @@ -519,7 +522,9 @@ pub(crate) async fn install( .with_link_mode(link_mode) .with_cache(cache) .with_installer_metadata(installer_metadata) - .with_reporter(InstallReporter::from(printer).with_length(installs.len() as u64)) + .with_reporter(Arc::new( + InstallReporter::from(printer).with_length(installs.len() as u64), + )) // This technically can block the runtime, but we are on the main thread and // have no other running tasks at this point, so this lets us avoid spawning a blocking // task. diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index c0bb80796880..f53327204ee3 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -1,12 +1,12 @@ -use std::collections::hash_map::Entry; -use std::fmt::Write; -use std::io; -use std::path::{Path, PathBuf}; - use anyhow::{bail, Context, Result}; use itertools::Itertools; use owo_colors::OwoColorize; use rustc_hash::{FxBuildHasher, FxHashMap}; +use std::collections::hash_map::Entry; +use std::fmt::Write; +use std::io; +use std::path::{Path, PathBuf}; +use std::sync::Arc; use tracing::debug; use url::Url; @@ -372,7 +372,7 @@ pub(crate) async fn add( state.index(), DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(unnamed.into_iter()) .await?, ); diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index 5b498a0ca3d8..4c2af68c5031 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -3,6 +3,7 @@ use std::collections::BTreeSet; use std::fmt::Write; use std::path::Path; +use std::sync::Arc; use owo_colors::OwoColorize; use rustc_hash::{FxBuildHasher, FxHashMap}; @@ -624,7 +625,7 @@ async fn do_lock( // Resolve the requirements. let resolution = pip::operations::resolve( ExtrasResolver::new(&hasher, state.index(), database) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(workspace.members_requirements()) .await .map_err(|err| ProjectError::Operation(err.into()))? diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index d77cee35e797..7b26bd2d2742 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -1,5 +1,6 @@ use std::fmt::Write; use std::path::{Path, PathBuf}; +use std::sync::Arc; use itertools::Itertools; use owo_colors::OwoColorize; @@ -1003,7 +1004,7 @@ pub(crate) async fn resolve_names( state.index(), DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads), ) - .with_reporter(ResolverReporter::from(printer)) + .with_reporter(Arc::new(ResolverReporter::from(printer))) .resolve(unnamed.into_iter()) .await?, ); diff --git a/crates/uv/src/commands/reporters.rs b/crates/uv/src/commands/reporters.rs index 0ceef7f8dac3..1e3fdb1e50cd 100644 --- a/crates/uv/src/commands/reporters.rs +++ b/crates/uv/src/commands/reporters.rs @@ -6,6 +6,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use owo_colors::OwoColorize; use rustc_hash::FxHashMap; use url::Url; + use uv_cache::Removal; use uv_distribution_types::{ BuildableSource, CachedDist, DistributionMetadata, Name, SourceDist, VersionOrUrlRef,