mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-28 10:50:29 +00:00
Split resolver.rs into a module (#752)
This is just getting hard to navigate. No code changes, just moving stuff around.
This commit is contained in:
parent
48c7359622
commit
a8e52d2899
6 changed files with 226 additions and 187 deletions
|
|
@ -5,9 +5,7 @@ pub use prerelease_mode::PreReleaseMode;
|
||||||
pub use resolution::ResolutionGraph;
|
pub use resolution::ResolutionGraph;
|
||||||
pub use resolution_mode::ResolutionMode;
|
pub use resolution_mode::ResolutionMode;
|
||||||
pub use resolution_options::ResolutionOptions;
|
pub use resolution_options::ResolutionOptions;
|
||||||
pub use resolver::{
|
pub use resolver::{BuildId, Reporter as ResolverReporter, Resolver, ResolverProvider};
|
||||||
BuildId, DefaultResolverProvider, Reporter as ResolverReporter, Resolver, ResolverProvider,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod candidate_selector;
|
mod candidate_selector;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
|
||||||
17
crates/puffin-resolver/src/resolver/allowed_urls.rs
Normal file
17
crates/puffin-resolver/src/resolver/allowed_urls.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct AllowedUrls(FxHashSet<cache_key::CanonicalUrl>);
|
||||||
|
|
||||||
|
impl AllowedUrls {
|
||||||
|
pub(crate) fn contains(&self, url: &Url) -> bool {
|
||||||
|
self.0.contains(&cache_key::CanonicalUrl::new(url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromIterator<&'a Url> for AllowedUrls {
|
||||||
|
fn from_iter<T: IntoIterator<Item = &'a Url>>(iter: T) -> Self {
|
||||||
|
Self(iter.into_iter().map(cache_key::CanonicalUrl::new).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
26
crates/puffin-resolver/src/resolver/index.rs
Normal file
26
crates/puffin-resolver/src/resolver/index.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use distribution_types::{IndexUrl, PackageId};
|
||||||
|
use pep440_rs::VersionSpecifiers;
|
||||||
|
use puffin_normalize::PackageName;
|
||||||
|
use puffin_traits::OnceMap;
|
||||||
|
use pypi_types::{BaseUrl, Metadata21};
|
||||||
|
|
||||||
|
use crate::version_map::VersionMap;
|
||||||
|
|
||||||
|
/// In-memory index of package metadata.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub(crate) struct Index {
|
||||||
|
/// A map from package name to the metadata for that package and the index where the metadata
|
||||||
|
/// came from.
|
||||||
|
pub(crate) packages: OnceMap<PackageName, (IndexUrl, BaseUrl, VersionMap)>,
|
||||||
|
|
||||||
|
/// A map from package ID to metadata for that distribution.
|
||||||
|
pub(crate) distributions: OnceMap<PackageId, Metadata21>,
|
||||||
|
|
||||||
|
/// A map from package ID to required Python version.
|
||||||
|
pub(crate) incompatibilities: OnceMap<PackageId, VersionSpecifiers>,
|
||||||
|
|
||||||
|
/// A map from source URL to precise URL.
|
||||||
|
pub(crate) redirects: OnceMap<Url, Url>,
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
//! Given a set of requirements, find a set of compatible packages.
|
//! Given a set of requirements, find a set of compatible packages.
|
||||||
|
|
||||||
use std::future::Future;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use futures::channel::mpsc::UnboundedReceiver;
|
use futures::channel::mpsc::UnboundedReceiver;
|
||||||
use futures::{pin_mut, FutureExt, StreamExt, TryFutureExt};
|
use futures::{pin_mut, FutureExt, StreamExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pubgrub::error::PubGrubError;
|
use pubgrub::error::PubGrubError;
|
||||||
use pubgrub::range::Range;
|
use pubgrub::range::Range;
|
||||||
|
|
@ -19,17 +17,15 @@ use url::Url;
|
||||||
|
|
||||||
use distribution_filename::WheelFilename;
|
use distribution_filename::WheelFilename;
|
||||||
use distribution_types::{
|
use distribution_types::{
|
||||||
BuiltDist, Dist, DistributionMetadata, IndexUrl, LocalEditable, Name, PackageId, SourceDist,
|
BuiltDist, Dist, DistributionMetadata, IndexUrl, LocalEditable, Name, SourceDist, VersionOrUrl,
|
||||||
VersionOrUrl,
|
|
||||||
};
|
};
|
||||||
use pep440_rs::VersionSpecifiers;
|
|
||||||
use pep508_rs::{MarkerEnvironment, Requirement};
|
use pep508_rs::{MarkerEnvironment, Requirement};
|
||||||
use platform_tags::Tags;
|
use platform_tags::Tags;
|
||||||
use puffin_client::RegistryClient;
|
use puffin_client::RegistryClient;
|
||||||
use puffin_distribution::{DistributionDatabase, DistributionDatabaseError};
|
use puffin_distribution::DistributionDatabase;
|
||||||
use puffin_interpreter::Interpreter;
|
use puffin_interpreter::Interpreter;
|
||||||
use puffin_normalize::PackageName;
|
use puffin_normalize::PackageName;
|
||||||
use puffin_traits::{BuildContext, OnceMap};
|
use puffin_traits::BuildContext;
|
||||||
use pypi_types::{BaseUrl, Metadata21};
|
use pypi_types::{BaseUrl, Metadata21};
|
||||||
|
|
||||||
use crate::candidate_selector::CandidateSelector;
|
use crate::candidate_selector::CandidateSelector;
|
||||||
|
|
@ -43,107 +39,19 @@ use crate::pubgrub::{
|
||||||
};
|
};
|
||||||
use crate::python_requirement::PythonRequirement;
|
use crate::python_requirement::PythonRequirement;
|
||||||
use crate::resolution::ResolutionGraph;
|
use crate::resolution::ResolutionGraph;
|
||||||
|
use crate::resolver::allowed_urls::AllowedUrls;
|
||||||
|
use crate::resolver::index::Index;
|
||||||
|
use crate::resolver::provider::DefaultResolverProvider;
|
||||||
|
pub use crate::resolver::provider::ResolverProvider;
|
||||||
|
use crate::resolver::reporter::Facade;
|
||||||
|
pub use crate::resolver::reporter::{BuildId, Reporter};
|
||||||
use crate::version_map::VersionMap;
|
use crate::version_map::VersionMap;
|
||||||
use crate::yanks::AllowedYanks;
|
|
||||||
use crate::ResolutionOptions;
|
use crate::ResolutionOptions;
|
||||||
|
|
||||||
type VersionMapResponse = Result<(IndexUrl, BaseUrl, VersionMap), puffin_client::Error>;
|
mod allowed_urls;
|
||||||
type WheelMetadataResponse = Result<(Metadata21, Option<Url>), DistributionDatabaseError>;
|
mod index;
|
||||||
|
mod provider;
|
||||||
pub trait ResolverProvider: Send + Sync {
|
mod reporter;
|
||||||
/// Get the version map for a package.
|
|
||||||
fn get_version_map<'io>(
|
|
||||||
&'io self,
|
|
||||||
package_name: &'io PackageName,
|
|
||||||
) -> impl Future<Output = VersionMapResponse> + Send + 'io;
|
|
||||||
|
|
||||||
/// Get the metadata for a distribution.
|
|
||||||
///
|
|
||||||
/// For a wheel, this is done by querying it's (remote) metadata, for a source dist we
|
|
||||||
/// (fetch and) build the source distribution and return the metadata from the built
|
|
||||||
/// distribution.
|
|
||||||
fn get_or_build_wheel_metadata<'io>(
|
|
||||||
&'io self,
|
|
||||||
dist: &'io Dist,
|
|
||||||
) -> impl Future<Output = WheelMetadataResponse> + Send + 'io;
|
|
||||||
|
|
||||||
/// Set the [`Reporter`] to use for this installer.
|
|
||||||
#[must_use]
|
|
||||||
fn with_reporter(self, reporter: impl puffin_distribution::Reporter + 'static) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The main IO backend for the resolver, which does cached requests network requests using the
|
|
||||||
/// [`RegistryClient`] and [`DistributionDatabase`].
|
|
||||||
pub struct DefaultResolverProvider<'a, Context: BuildContext + Send + Sync> {
|
|
||||||
client: &'a RegistryClient,
|
|
||||||
fetcher: DistributionDatabase<'a, Context>,
|
|
||||||
tags: &'a Tags,
|
|
||||||
python_requirement: PythonRequirement<'a>,
|
|
||||||
exclude_newer: Option<DateTime<Utc>>,
|
|
||||||
allowed_yanks: AllowedYanks,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Context> {
|
|
||||||
pub fn new(
|
|
||||||
client: &'a RegistryClient,
|
|
||||||
fetcher: DistributionDatabase<'a, Context>,
|
|
||||||
tags: &'a Tags,
|
|
||||||
python_requirement: PythonRequirement<'a>,
|
|
||||||
exclude_newer: Option<DateTime<Utc>>,
|
|
||||||
allowed_yanks: AllowedYanks,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
client,
|
|
||||||
fetcher,
|
|
||||||
tags,
|
|
||||||
python_requirement,
|
|
||||||
exclude_newer,
|
|
||||||
allowed_yanks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Context: BuildContext + Send + Sync> ResolverProvider
|
|
||||||
for DefaultResolverProvider<'a, Context>
|
|
||||||
{
|
|
||||||
fn get_version_map<'io>(
|
|
||||||
&'io self,
|
|
||||||
package_name: &'io PackageName,
|
|
||||||
) -> impl Future<Output = VersionMapResponse> + Send + 'io {
|
|
||||||
self.client
|
|
||||||
.simple(package_name)
|
|
||||||
.map_ok(move |(index, base, metadata)| {
|
|
||||||
(
|
|
||||||
index,
|
|
||||||
base,
|
|
||||||
VersionMap::from_metadata(
|
|
||||||
metadata,
|
|
||||||
package_name,
|
|
||||||
self.tags,
|
|
||||||
&self.python_requirement,
|
|
||||||
&self.allowed_yanks,
|
|
||||||
self.exclude_newer.as_ref(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_build_wheel_metadata<'io>(
|
|
||||||
&'io self,
|
|
||||||
dist: &'io Dist,
|
|
||||||
) -> impl Future<Output = WheelMetadataResponse> + Send + 'io {
|
|
||||||
self.fetcher.get_or_build_wheel_metadata(dist)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the [`puffin_distribution::Reporter`] to use for this installer.
|
|
||||||
#[must_use]
|
|
||||||
fn with_reporter(self, reporter: impl puffin_distribution::Reporter + 'static) -> Self {
|
|
||||||
Self {
|
|
||||||
fetcher: self.fetcher.with_reporter(reporter),
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Resolver<'a, Provider: ResolverProvider> {
|
pub struct Resolver<'a, Provider: ResolverProvider> {
|
||||||
project: Option<PackageName>,
|
project: Option<PackageName>,
|
||||||
|
|
@ -373,7 +281,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
||||||
// Pick the next compatible version.
|
// Pick the next compatible version.
|
||||||
let version = match decision {
|
let version = match decision {
|
||||||
None => {
|
None => {
|
||||||
debug!("No compatible version found for: {}", next);
|
debug!("No compatible version found for: {next}");
|
||||||
|
|
||||||
let term_intersection = state
|
let term_intersection = state
|
||||||
.partial_solution
|
.partial_solution
|
||||||
|
|
@ -909,51 +817,6 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BuildId = usize;
|
|
||||||
|
|
||||||
pub trait Reporter: Send + Sync {
|
|
||||||
/// Callback to invoke when a dependency is resolved.
|
|
||||||
fn on_progress(&self, name: &PackageName, version: VersionOrUrl);
|
|
||||||
|
|
||||||
/// Callback to invoke when the resolution is complete.
|
|
||||||
fn on_complete(&self);
|
|
||||||
|
|
||||||
/// Callback to invoke when a source distribution build is kicked off.
|
|
||||||
fn on_build_start(&self, dist: &SourceDist) -> usize;
|
|
||||||
|
|
||||||
/// Callback to invoke when a source distribution build is complete.
|
|
||||||
fn on_build_complete(&self, dist: &SourceDist, id: usize);
|
|
||||||
|
|
||||||
/// Callback to invoke when a repository checkout begins.
|
|
||||||
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize;
|
|
||||||
|
|
||||||
/// Callback to invoke when a repository checkout completes.
|
|
||||||
fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A facade for converting from [`Reporter`] to [`puffin_distribution::Reporter`].
|
|
||||||
struct Facade {
|
|
||||||
reporter: Arc<dyn Reporter>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl puffin_distribution::Reporter for Facade {
|
|
||||||
fn on_build_start(&self, dist: &SourceDist) -> usize {
|
|
||||||
self.reporter.on_build_start(dist)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_build_complete(&self, dist: &SourceDist, id: usize) {
|
|
||||||
self.reporter.on_build_complete(dist, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize {
|
|
||||||
self.reporter.on_checkout_start(url, rev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize) {
|
|
||||||
self.reporter.on_checkout_complete(url, rev, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetch the metadata for an item
|
/// Fetch the metadata for an item
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
|
@ -975,38 +838,6 @@ enum Response {
|
||||||
Dist(Dist, Metadata21, Option<Url>),
|
Dist(Dist, Metadata21, Option<Url>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In-memory index of package metadata.
|
|
||||||
#[derive(Default)]
|
|
||||||
pub(crate) struct Index {
|
|
||||||
/// A map from package name to the metadata for that package and the index where the metadata
|
|
||||||
/// came from.
|
|
||||||
pub(crate) packages: OnceMap<PackageName, (IndexUrl, BaseUrl, VersionMap)>,
|
|
||||||
|
|
||||||
/// A map from package ID to metadata for that distribution.
|
|
||||||
pub(crate) distributions: OnceMap<PackageId, Metadata21>,
|
|
||||||
|
|
||||||
/// A map from package ID to required Python version.
|
|
||||||
pub(crate) incompatibilities: OnceMap<PackageId, VersionSpecifiers>,
|
|
||||||
|
|
||||||
/// A map from source URL to precise URL.
|
|
||||||
pub(crate) redirects: OnceMap<Url, Url>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct AllowedUrls(FxHashSet<cache_key::CanonicalUrl>);
|
|
||||||
|
|
||||||
impl AllowedUrls {
|
|
||||||
fn contains(&self, url: &Url) -> bool {
|
|
||||||
self.0.contains(&cache_key::CanonicalUrl::new(url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromIterator<&'a Url> for AllowedUrls {
|
|
||||||
fn from_iter<T: IntoIterator<Item = &'a Url>>(iter: T) -> Self {
|
|
||||||
Self(iter.into_iter().map(cache_key::CanonicalUrl::new).collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An enum used by [`DependencyProvider`] that holds information about package dependencies.
|
/// An enum used by [`DependencyProvider`] that holds information about package dependencies.
|
||||||
/// For each [Package] there is a set of versions allowed as a dependency.
|
/// For each [Package] there is a set of versions allowed as a dependency.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
116
crates/puffin-resolver/src/resolver/provider.rs
Normal file
116
crates/puffin-resolver/src/resolver/provider.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use futures::TryFutureExt;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use distribution_types::{Dist, IndexUrl};
|
||||||
|
use platform_tags::Tags;
|
||||||
|
use puffin_client::RegistryClient;
|
||||||
|
use puffin_distribution::{DistributionDatabase, DistributionDatabaseError};
|
||||||
|
use puffin_normalize::PackageName;
|
||||||
|
use puffin_traits::BuildContext;
|
||||||
|
use pypi_types::{BaseUrl, Metadata21};
|
||||||
|
|
||||||
|
use crate::python_requirement::PythonRequirement;
|
||||||
|
use crate::version_map::VersionMap;
|
||||||
|
use crate::yanks::AllowedYanks;
|
||||||
|
|
||||||
|
type VersionMapResponse = Result<(IndexUrl, BaseUrl, VersionMap), puffin_client::Error>;
|
||||||
|
type WheelMetadataResponse = Result<(Metadata21, Option<Url>), DistributionDatabaseError>;
|
||||||
|
|
||||||
|
pub trait ResolverProvider: Send + Sync {
|
||||||
|
/// Get the version map for a package.
|
||||||
|
fn get_version_map<'io>(
|
||||||
|
&'io self,
|
||||||
|
package_name: &'io PackageName,
|
||||||
|
) -> impl Future<Output = VersionMapResponse> + Send + 'io;
|
||||||
|
|
||||||
|
/// Get the metadata for a distribution.
|
||||||
|
///
|
||||||
|
/// For a wheel, this is done by querying it's (remote) metadata, for a source dist we
|
||||||
|
/// (fetch and) build the source distribution and return the metadata from the built
|
||||||
|
/// distribution.
|
||||||
|
fn get_or_build_wheel_metadata<'io>(
|
||||||
|
&'io self,
|
||||||
|
dist: &'io Dist,
|
||||||
|
) -> impl Future<Output = WheelMetadataResponse> + Send + 'io;
|
||||||
|
|
||||||
|
/// Set the [`Reporter`] to use for this installer.
|
||||||
|
#[must_use]
|
||||||
|
fn with_reporter(self, reporter: impl puffin_distribution::Reporter + 'static) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The main IO backend for the resolver, which does cached requests network requests using the
|
||||||
|
/// [`RegistryClient`] and [`DistributionDatabase`].
|
||||||
|
pub struct DefaultResolverProvider<'a, Context: BuildContext + Send + Sync> {
|
||||||
|
client: &'a RegistryClient,
|
||||||
|
fetcher: DistributionDatabase<'a, Context>,
|
||||||
|
tags: &'a Tags,
|
||||||
|
python_requirement: PythonRequirement<'a>,
|
||||||
|
exclude_newer: Option<DateTime<Utc>>,
|
||||||
|
allowed_yanks: AllowedYanks,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Context> {
|
||||||
|
pub fn new(
|
||||||
|
client: &'a RegistryClient,
|
||||||
|
fetcher: DistributionDatabase<'a, Context>,
|
||||||
|
tags: &'a Tags,
|
||||||
|
python_requirement: PythonRequirement<'a>,
|
||||||
|
exclude_newer: Option<DateTime<Utc>>,
|
||||||
|
allowed_yanks: AllowedYanks,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
client,
|
||||||
|
fetcher,
|
||||||
|
tags,
|
||||||
|
python_requirement,
|
||||||
|
exclude_newer,
|
||||||
|
allowed_yanks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Context: BuildContext + Send + Sync> ResolverProvider
|
||||||
|
for DefaultResolverProvider<'a, Context>
|
||||||
|
{
|
||||||
|
fn get_version_map<'io>(
|
||||||
|
&'io self,
|
||||||
|
package_name: &'io PackageName,
|
||||||
|
) -> impl Future<Output = VersionMapResponse> + Send + 'io {
|
||||||
|
self.client
|
||||||
|
.simple(package_name)
|
||||||
|
.map_ok(move |(index, base, metadata)| {
|
||||||
|
(
|
||||||
|
index,
|
||||||
|
base,
|
||||||
|
VersionMap::from_metadata(
|
||||||
|
metadata,
|
||||||
|
package_name,
|
||||||
|
self.tags,
|
||||||
|
&self.python_requirement,
|
||||||
|
&self.allowed_yanks,
|
||||||
|
self.exclude_newer.as_ref(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_or_build_wheel_metadata<'io>(
|
||||||
|
&'io self,
|
||||||
|
dist: &'io Dist,
|
||||||
|
) -> impl Future<Output = WheelMetadataResponse> + Send + 'io {
|
||||||
|
self.fetcher.get_or_build_wheel_metadata(dist)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the [`puffin_distribution::Reporter`] to use for this installer.
|
||||||
|
#[must_use]
|
||||||
|
fn with_reporter(self, reporter: impl puffin_distribution::Reporter + 'static) -> Self {
|
||||||
|
Self {
|
||||||
|
fetcher: self.fetcher.with_reporter(reporter),
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
crates/puffin-resolver/src/resolver/reporter.rs
Normal file
51
crates/puffin-resolver/src/resolver/reporter.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use distribution_types::{SourceDist, VersionOrUrl};
|
||||||
|
use puffin_normalize::PackageName;
|
||||||
|
|
||||||
|
pub type BuildId = usize;
|
||||||
|
|
||||||
|
pub trait Reporter: Send + Sync {
|
||||||
|
/// Callback to invoke when a dependency is resolved.
|
||||||
|
fn on_progress(&self, name: &PackageName, version: VersionOrUrl);
|
||||||
|
|
||||||
|
/// Callback to invoke when the resolution is complete.
|
||||||
|
fn on_complete(&self);
|
||||||
|
|
||||||
|
/// Callback to invoke when a source distribution build is kicked off.
|
||||||
|
fn on_build_start(&self, dist: &SourceDist) -> usize;
|
||||||
|
|
||||||
|
/// Callback to invoke when a source distribution build is complete.
|
||||||
|
fn on_build_complete(&self, dist: &SourceDist, id: usize);
|
||||||
|
|
||||||
|
/// Callback to invoke when a repository checkout begins.
|
||||||
|
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize;
|
||||||
|
|
||||||
|
/// Callback to invoke when a repository checkout completes.
|
||||||
|
fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A facade for converting from [`Reporter`] to [`puffin_distribution::Reporter`].
|
||||||
|
pub(crate) struct Facade {
|
||||||
|
pub(crate) reporter: Arc<dyn Reporter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl puffin_distribution::Reporter for Facade {
|
||||||
|
fn on_build_start(&self, dist: &SourceDist) -> usize {
|
||||||
|
self.reporter.on_build_start(dist)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_build_complete(&self, dist: &SourceDist, id: usize) {
|
||||||
|
self.reporter.on_build_complete(dist, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize {
|
||||||
|
self.reporter.on_checkout_start(url, rev)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize) {
|
||||||
|
self.reporter.on_checkout_complete(url, rev, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue