Add a resolver reporter (#225)

Closes https://github.com/astral-sh/puffin/issues/223.
This commit is contained in:
Charlie Marsh 2023-10-29 19:00:09 -07:00 committed by GitHub
parent 6da9c2f534
commit f2dd0d90be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 4 deletions

View file

@ -18,6 +18,7 @@ use puffin_dispatch::BuildDispatch;
use puffin_interpreter::Virtualenv; use puffin_interpreter::Virtualenv;
use puffin_resolver::{Manifest, PreReleaseMode, ResolutionMode}; use puffin_resolver::{Manifest, PreReleaseMode, ResolutionMode};
use crate::commands::reporters::ResolverReporter;
use crate::commands::{elapsed, ExitStatus}; use crate::commands::{elapsed, ExitStatus};
use crate::index_urls::IndexUrls; use crate::index_urls::IndexUrls;
use crate::printer::Printer; use crate::printer::Printer;
@ -110,7 +111,8 @@ pub(crate) async fn pip_compile(
&tags, &tags,
&client, &client,
&build_dispatch, &build_dispatch,
); )
.with_reporter(ResolverReporter::from(printer));
let resolution = match resolver.resolve().await { let resolution = match resolver.resolve().await {
Err(puffin_resolver::ResolveError::PubGrub(pubgrub::error::PubGrubError::NoSolution( Err(puffin_resolver::ResolveError::PubGrub(pubgrub::error::PubGrubError::NoSolution(
mut derivation_tree, mut derivation_tree,

View file

@ -1,4 +1,5 @@
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use std::time::Duration;
use pep440_rs::Version; use pep440_rs::Version;
use puffin_package::package_name::PackageName; use puffin_package::package_name::PackageName;
@ -29,7 +30,7 @@ impl WheelFinderReporter {
} }
} }
impl puffin_resolver::Reporter for WheelFinderReporter { impl puffin_resolver::WheelFinderReporter for WheelFinderReporter {
fn on_progress(&self, package: &puffin_resolver::PinnedPackage) { fn on_progress(&self, package: &puffin_resolver::PinnedPackage) {
self.progress self.progress
.set_message(format!("{}=={}", package.name(), package.version())); .set_message(format!("{}=={}", package.name(), package.version()));
@ -145,3 +146,32 @@ impl puffin_installer::InstallReporter for InstallReporter {
self.progress.finish_and_clear(); self.progress.finish_and_clear();
} }
} }
#[derive(Debug)]
pub(crate) struct ResolverReporter {
progress: ProgressBar,
}
impl From<Printer> for ResolverReporter {
fn from(printer: Printer) -> Self {
let progress = ProgressBar::with_draw_target(None, printer.target());
progress.set_message("Resolving dependencies...");
progress.enable_steady_tick(Duration::from_millis(200));
progress.set_style(
ProgressStyle::with_template("{spinner:.white} {wide_msg:.dim}")
.unwrap()
.tick_strings(&["", "", "", "", "", "", "", "", "", ""]),
);
Self { progress }
}
}
impl puffin_resolver::ResolverReporter for ResolverReporter {
fn on_progress(&self, name: &PackageName, version: &Version) {
self.progress.set_message(format!("{name}=={version}"));
}
fn on_complete(&self) {
self.progress.finish_and_clear();
}
}

View file

@ -3,9 +3,9 @@ pub use manifest::Manifest;
pub use prerelease_mode::PreReleaseMode; pub use prerelease_mode::PreReleaseMode;
pub use resolution::{Graph, PinnedPackage}; pub use resolution::{Graph, PinnedPackage};
pub use resolution_mode::ResolutionMode; pub use resolution_mode::ResolutionMode;
pub use resolver::Resolver; pub use resolver::{Reporter as ResolverReporter, Resolver};
pub use source_distribution::BuiltSourceDistributionCache; pub use source_distribution::BuiltSourceDistributionCache;
pub use wheel_finder::{Reporter, WheelFinder}; pub use wheel_finder::{Reporter as WheelFinderReporter, WheelFinder};
mod candidate_selector; mod candidate_selector;
mod distribution; mod distribution;

View file

@ -50,6 +50,7 @@ pub struct Resolver<'a, Context: BuildContext + Sync> {
selector: CandidateSelector, selector: CandidateSelector,
index: Arc<Index>, index: Arc<Index>,
build_context: &'a Context, build_context: &'a Context,
reporter: Option<Box<dyn Reporter>>,
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -92,6 +93,16 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
tags, tags,
client, client,
build_context, build_context,
reporter: None,
}
}
/// Set the [`Reporter`] to use for this installer.
#[must_use]
pub fn with_reporter(self, reporter: impl Reporter + 'static) -> Self {
Self {
reporter: Some(Box::new(reporter)),
..self
} }
} }
@ -121,6 +132,8 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
} }
}; };
self.on_complete();
Ok(resolution) Ok(resolution)
} }
@ -210,6 +223,8 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
Some(version) => version, Some(version) => version,
}; };
self.on_progress(&next, &version);
if added_dependencies if added_dependencies
.entry(next.clone()) .entry(next.clone())
.or_default() .or_default()
@ -620,6 +635,28 @@ impl<'a, Context: BuildContext + Sync> Resolver<'a, Context> {
}), }),
} }
} }
fn on_progress(&self, package: &PubGrubPackage, version: &PubGrubVersion) {
if let Some(reporter) = self.reporter.as_ref() {
if let PubGrubPackage::Package(package_name, _) = package {
reporter.on_progress(package_name, version.into());
}
}
}
fn on_complete(&self) {
if let Some(reporter) = self.reporter.as_ref() {
reporter.on_complete();
}
}
}
pub trait Reporter: Send + Sync {
/// Callback to invoke when a dependency is resolved.
fn on_progress(&self, name: &PackageName, version: &pep440_rs::Version);
/// Callback to invoke when the resolution is complete.
fn on_complete(&self);
} }
/// Fetch the metadata for an item /// Fetch the metadata for an item