feat: support progress reporting for wally

This commit is contained in:
LukaDev 2024-12-26 20:55:43 +01:00
parent 6669d725f1
commit 2902aa2a2b
2 changed files with 47 additions and 10 deletions

View file

@ -71,6 +71,7 @@ pub struct CliReporter<W = Stdout> {
writer: Mutex<W>, writer: Mutex<W>,
child_style: ProgressStyle, child_style: ProgressStyle,
child_style_with_bytes: ProgressStyle, child_style_with_bytes: ProgressStyle,
child_style_with_bytes_without_total: ProgressStyle,
multi_progress: MultiProgress, multi_progress: MultiProgress,
root_progress: ProgressBar, root_progress: ProgressBar,
} }
@ -88,6 +89,10 @@ impl<W> CliReporter<W> {
&"{msg} {bytes}/{total_bytes}".dimmed().to_string(), &"{msg} {bytes}/{total_bytes}".dimmed().to_string(),
) )
.unwrap(), .unwrap(),
child_style_with_bytes_without_total: ProgressStyle::with_template(
&"{msg} {bytes}".dimmed().to_string(),
)
.unwrap(),
multi_progress, multi_progress,
root_progress, root_progress,
} }
@ -135,7 +140,15 @@ impl<W: Write + Send + Sync + 'static> DownloadProgressReporter
progress.set_position(len); progress.set_position(len);
self.set_progress.call_once(|| { self.set_progress.call_once(|| {
progress.set_style(self.root_reporter.child_style_with_bytes.clone()); if total > 0 {
progress.set_style(self.root_reporter.child_style_with_bytes.clone());
} else {
progress.set_style(
self.root_reporter
.child_style_with_bytes_without_total
.clone(),
);
}
}); });
} }
} }

View file

@ -18,7 +18,7 @@ use crate::{
Project, Project,
}; };
use fs_err::tokio as fs; use fs_err::tokio as fs;
use futures::future::try_join_all; use futures::{future::try_join_all, StreamExt};
use gix::Url; use gix::Url;
use relative_path::RelativePathBuf; use relative_path::RelativePathBuf;
use reqwest::header::AUTHORIZATION; use reqwest::header::AUTHORIZATION;
@ -29,8 +29,12 @@ use std::{
sync::Arc, sync::Arc,
}; };
use tempfile::tempdir; use tempfile::tempdir;
use tokio::{io::AsyncWriteExt, sync::Mutex, task::spawn_blocking}; use tokio::{
use tokio_util::compat::FuturesAsyncReadCompatExt; io::{AsyncReadExt, AsyncWriteExt},
sync::Mutex,
task::spawn_blocking,
};
use tokio_util::{compat::FuturesAsyncReadCompatExt, io::StreamReader};
use tracing::instrument; use tracing::instrument;
pub(crate) mod compat_util; pub(crate) mod compat_util;
@ -203,7 +207,7 @@ impl PackageSource for WallyPackageSource {
pkg_ref: &Self::Ref, pkg_ref: &Self::Ref,
project: &Project, project: &Project,
reqwest: &reqwest::Client, reqwest: &reqwest::Client,
_reporter: Arc<impl DownloadProgressReporter>, reporter: Arc<impl DownloadProgressReporter>,
) -> Result<(PackageFS, Target), Self::DownloadError> { ) -> Result<(PackageFS, Target), Self::DownloadError> {
let config = self.config(project).await.map_err(Box::new)?; let config = self.config(project).await.map_err(Box::new)?;
let index_file = project let index_file = project
@ -252,12 +256,30 @@ impl PackageSource for WallyPackageSource {
} }
let response = request.send().await?.error_for_status()?; let response = request.send().await?.error_for_status()?;
let mut bytes = response.bytes().await?;
let archive = async_zip::tokio::read::seek::ZipFileReader::with_tokio( let total_len = response.content_length().unwrap_or(0);
std::io::Cursor::new(&mut bytes), reporter.report_progress(total_len, 0);
)
.await?; let mut bytes_downloaded = 0;
let bytes = response
.bytes_stream()
.inspect(|chunk| {
chunk.as_ref().ok().inspect(|chunk| {
bytes_downloaded += chunk.len() as u64;
reporter.report_progress(total_len, bytes_downloaded);
});
})
.map(|result| {
result.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
});
let mut bytes = StreamReader::new(bytes);
let mut buf = vec![];
bytes.read_to_end(&mut buf).await?;
let archive =
async_zip::tokio::read::seek::ZipFileReader::with_tokio(std::io::Cursor::new(&mut buf))
.await?;
let entries = (0..archive.file().entries().len()) let entries = (0..archive.file().entries().len())
.map(|index| { .map(|index| {
@ -330,6 +352,8 @@ impl PackageSource for WallyPackageSource {
.await .await
.map_err(errors::DownloadError::WriteIndex)?; .map_err(errors::DownloadError::WriteIndex)?;
reporter.report_done();
Ok((fs, get_target(project, &tempdir).await?)) Ok((fs, get_target(project, &tempdir).await?))
} }
} }