diff --git a/crates/uv-publish/src/lib.rs b/crates/uv-publish/src/lib.rs index ea5d0df860608..fabec10dad6dd 100644 --- a/crates/uv-publish/src/lib.rs +++ b/crates/uv-publish/src/lib.rs @@ -26,8 +26,8 @@ use uv_metadata::read_metadata_async_seek; #[derive(Error, Debug)] pub enum PublishError { - #[error("Invalid publish paths")] - Pattern(#[from] PatternError), + #[error("Invalid publish path: `{0}`")] + Pattern(String, #[source] PatternError), /// [`GlobError`] is a wrapped io error. #[error(transparent)] Glob(#[from] GlobError), @@ -180,7 +180,7 @@ pub fn files_for_publishing( let mut seen = HashSet::new(); let mut files = Vec::new(); for path in paths { - for entry in glob(&path)? { + for entry in glob(&path).map_err(|err| PublishError::Pattern(path.to_string(), err))? { let entry = entry?; if !seen.insert(entry.clone()) { continue; diff --git a/crates/uv/src/commands/reporters.rs b/crates/uv/src/commands/reporters.rs index 6a037765d00c5..d3f1b78ec1276 100644 --- a/crates/uv/src/commands/reporters.rs +++ b/crates/uv/src/commands/reporters.rs @@ -485,6 +485,48 @@ impl uv_python::downloads::Reporter for PythonDownloadReporter { } } +#[derive(Debug)] +pub(crate) struct PublishReporter { + reporter: ProgressReporter, +} + +impl PublishReporter { + /// Initialize a [`crate::commands::reporters::PythonDownloadReporter`] for a single Python download. + pub(crate) fn single(printer: Printer) -> Self { + Self::new(printer, 1) + } + + /// Initialize a [`crate::commands::reporters::PythonDownloadReporter`] for multiple Python downloads. + pub(crate) fn new(printer: Printer, length: u64) -> Self { + let multi_progress = MultiProgress::with_draw_target(printer.target()); + let root = multi_progress.add(ProgressBar::with_draw_target( + Some(length), + printer.target(), + )); + let reporter = ProgressReporter::new(root, multi_progress, printer); + Self { reporter } + } +} + +impl uv_publish::Reporter for PublishReporter { + fn on_progress(&self, _name: &PythonInstallationKey, id: usize) { + self.reporter.on_download_complete(id); + } + + fn on_download_start(&self, name: &PythonInstallationKey, size: Option) -> usize { + self.reporter.on_download_start(name.to_string(), size) + } + + fn on_download_progress(&self, id: usize, inc: u64) { + self.reporter.on_download_progress(id, inc); + } + + fn on_download_complete(&self) { + self.reporter.root.set_message(""); + self.reporter.root.finish_and_clear(); + } +} + /// Like [`std::fmt::Display`], but with colors. trait ColorDisplay { fn to_color_string(&self) -> String;