From c2fcab8fa8c8864978769986ec3365d5e50540a8 Mon Sep 17 00:00:00 2001 From: ad hoc Date: Wed, 25 Sep 2024 01:14:54 +0200 Subject: [PATCH] add progress bar to client downloads --- crates/client/src/api.rs | 15 +++++++++++---- crates/client/src/depsolve.rs | 2 +- crates/client/src/lib.rs | 16 ++++++++++++---- src/commands/dependencies.rs | 19 +++++++++++++++---- src/commands/download.rs | 10 +++++++--- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/crates/client/src/api.rs b/crates/client/src/api.rs index 8b600a96..e3a784c6 100644 --- a/crates/client/src/api.rs +++ b/crates/client/src/api.rs @@ -457,6 +457,7 @@ impl Client { &self, registry_domain: Option<&RegistryDomain>, digest: &AnyHash, + mut with_progress: impl FnMut(u64, u64) + Send + Sync + 'static, ) -> Result>, ClientError> { let ContentSourcesResponse { content_sources } = self.content_sources(registry_domain, digest).await?; @@ -479,10 +480,16 @@ impl Client { continue; } - return Ok(validate_stream( - digest, - response.bytes_stream().map_err(|e| anyhow!(e)), - )); + let total_bytes = response.content_length().unwrap_or(0); + let stream = response + .bytes_stream() + .map_err(|e| anyhow!(e)) + .inspect(move |r| { + if let Ok(b) = r { + with_progress(b.len() as u64, total_bytes); + } + }); + return Ok(validate_stream(digest, stream)); } Err(ClientError::AllSourcesFailed(digest.clone())) diff --git a/crates/client/src/depsolve.rs b/crates/client/src/depsolve.rs index 445b2785..f95a4194 100644 --- a/crates/client/src/depsolve.rs +++ b/crates/client/src/depsolve.rs @@ -120,7 +120,7 @@ impl LockListBuilder { } self.lock_list.insert(import); } else { - client.download(&id, &VersionReq::STAR).await?; + client.download(&id, &VersionReq::STAR, |_, _| ()).await?; if let Some(info) = client .registry() .load_package( diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index 68abd015..fb21d7f3 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -655,6 +655,7 @@ impl Client Result, ClientError> { let info = self.package(package).await?; @@ -674,7 +675,7 @@ impl Client Client, digest: &AnyHash, + with_progress: impl FnMut(u64, u64) + Send + Sync + 'static, ) -> Result { match self.content.content_location(digest) { Some(path) => { @@ -1319,7 +1321,11 @@ current_registry = registry_domain.map(|d| d.as_str()).unwrap_or(&self.url().saf None => { self.content .store_content( - Box::pin(self.api.download_content(registry_domain, digest).await?), + Box::pin( + self.api + .download_content(registry_domain, digest, with_progress) + .await?, + ), Some(digest), ) .await?; @@ -1352,7 +1358,9 @@ current_registry = registry_domain.map(|d| d.as_str()).unwrap_or(&self.url().saf Ok(ReaderStream::new(file).map_err(Into::into).boxed()) } None => Ok(Box::pin( - self.api.download_content(registry_domain, digest).await?, + self.api + .download_content(registry_domain, digest, |_, _| ()) + .await?, )), } } diff --git a/src/commands/dependencies.rs b/src/commands/dependencies.rs index eee893db..4857f526 100644 --- a/src/commands/dependencies.rs +++ b/src/commands/dependencies.rs @@ -1,3 +1,5 @@ +use crate::progress::make_progress_handler; + use super::CommonOptions; use anyhow::{bail, Result}; use async_recursion::async_recursion; @@ -47,9 +49,14 @@ impl DependenciesCommand { node: &mut TreeBuilder, parser: &mut DepsParser, ) -> Result<()> { - client.download(id, &version).await?; - - if let Some(download) = client.download(id, &version).await? { + if let Some(download) = client + .download( + id, + &version, + make_progress_handler(format!("Downloading `{id}`")), + ) + .await? + { let bytes = fs::read(download.path)?; let deps = parser.parse(&bytes)?; for dep in deps { @@ -77,7 +84,11 @@ impl DependenciesCommand { async fn print_package_info(client: &FileSystemClient, info: &PackageInfo) -> Result<()> { let mut parser = DepsParser::new(); - if let Some(download) = client.download(&info.name, &Default::default()).await? { + let progress = |_inc, _total| {}; + if let Some(download) = client + .download(&info.name, &Default::default(), progress) + .await? + { let mut tree = new_tree(info.name.namespace(), info.name.name(), &download.version); let bytes = fs::read(&download.path)?; let deps = parser.parse(&bytes)?; diff --git a/src/commands/download.rs b/src/commands/download.rs index 33853cd9..c114e618 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -1,3 +1,5 @@ +use crate::progress::make_progress_handler; + use super::CommonOptions; use anyhow::Result; use clap::Args; @@ -30,8 +32,6 @@ impl DownloadCommand { let config = self.common.read_config()?; let client = self.common.create_client(&config).await?; - println!("Downloading `{name}`...", name = self.name); - // if user specifies exact verion, then set the `VersionReq` to exact match let version = match &self.version { Some(version) => VersionReq::parse(&format!("={}", version))?, @@ -39,7 +39,11 @@ impl DownloadCommand { }; let download = client - .download(&self.name, &version) + .download( + &self.name, + &version, + make_progress_handler(format!("Downloading `{name}`...", name = self.name)), + ) .await? .ok_or_else(|| ClientError::PackageVersionRequirementDoesNotExist { name: self.name.clone(),