Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: add progress for extraction #209499

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cli/src/tunnels/code_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,11 @@ impl<'a> ServerBuilder<'a> {
.await?;

let server_dir = target_dir.join(SERVER_FOLDER_NAME);
unzip_downloaded_release(&archive_path, &server_dir, SilentCopyProgress())?;
unzip_downloaded_release(
&archive_path,
&server_dir,
self.logger.get_download_logger("server inflate progress:"),
)?;

if !skip_requirements_check().await {
let output = capture_command_and_check_status(
Expand Down
46 changes: 30 additions & 16 deletions cli/src/util/tar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tar::Archive;
use super::errors::wrapdbg;
use super::io::ReportCopyProgress;

fn should_skip_first_segment(file: &fs::File) -> Result<bool, WrappedError> {
fn should_skip_first_segment(file: &fs::File) -> Result<(bool, u64), WrappedError> {
// unfortunately, we need to re-read the archive here since you cannot reuse
// `.entries()`. But this will generally only look at one or two files, so this
// should be acceptably speedy... If not, we could hardcode behavior for
Expand All @@ -39,17 +39,21 @@ fn should_skip_first_segment(file: &fs::File) -> Result<bool, WrappedError> {
.to_owned()
};

let mut had_multiple = false;
let mut num_entries = 1;
let mut had_different_prefixes = false;
for file in entries.flatten() {
had_multiple = true;
if let Ok(name) = file.path() {
if name.iter().next() != Some(&first_name) {
return Ok(false);
if !had_different_prefixes {
if let Ok(name) = file.path() {
if name.iter().next() != Some(&first_name) {
had_different_prefixes = true;
}
}
}

num_entries += 1;
}

Ok(had_multiple) // prefix removal is invalid if there's only a single file
Ok((!had_different_prefixes && num_entries > 1, num_entries)) // prefix removal is invalid if there's only a single file
}

pub fn decompress_tarball<T>(
Expand All @@ -62,7 +66,11 @@ where
{
let mut tar_gz = fs::File::open(path)
.map_err(|e| wrap(e, format!("error opening file {}", path.display())))?;
let skip_first = should_skip_first_segment(&tar_gz)?;

let (skip_first, num_entries) = should_skip_first_segment(&tar_gz)?;
let report_progress_every = num_entries / 20;
let mut entries_so_far = 0;
let mut last_reported_at = 0;

// reset since skip logic read the tar already:
tar_gz
Expand All @@ -71,12 +79,19 @@ where

let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);

let results = archive
archive
.entries()
.map_err(|e| wrap(e, format!("error opening archive {}", path.display())))?
.filter_map(|e| e.ok())
.map(|mut entry| {
.try_for_each::<_, Result<_, WrappedError>>(|mut entry| {
// approximate progress based on where we are in the archive:
entries_so_far += 1;
if entries_so_far - last_reported_at > report_progress_every {
reporter.report_progress(entries_so_far, num_entries);
entries_so_far += 1;
last_reported_at = entries_so_far;
}

let entry_path = entry
.path()
.map_err(|e| wrap(e, "error reading entry path"))?;
Expand All @@ -95,12 +110,11 @@ where
entry
.unpack(&path)
.map_err(|e| wrapdbg(e, format!("error unpacking {}", path.display())))?;
Ok(path)
})
.collect::<Result<Vec<PathBuf>, WrappedError>>()?;

// Tarballs don't have a way to get the number of entries ahead of time
reporter.report_progress(results.len() as u64, results.len() as u64);
Ok(())
})?;

reporter.report_progress(num_entries, num_entries);

Ok(())
}
6 changes: 5 additions & 1 deletion cli/src/util/zipper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ where
.map_err(|e| wrap(e, format!("failed to open zip archive {}", path.display())))?;

let skip_segments_no = usize::from(should_skip_first_segment(&mut archive));
let report_progress_every = archive.len() / 20;

for i in 0..archive.len() {
reporter.report_progress(i as u64, archive.len() as u64);
if i % report_progress_every == 0 {
reporter.report_progress(i as u64, archive.len() as u64);
}
let mut file = archive
.by_index(i)
.map_err(|e| wrap(e, format!("could not open zip entry {}", i)))?;
Expand Down
Loading