Skip to content
Draft
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
18 changes: 15 additions & 3 deletions src/dist/download.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::borrow::Cow;
use std::fs;
use std::io::Read;
use std::ops;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
use std::time::{Duration, Instant};

use anyhow::{Context, Result, anyhow};
use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};
use indicatif::{MultiProgress, ProgressBar, ProgressBarIter, ProgressDrawTarget, ProgressStyle};
use sha2::{Digest, Sha256};
use tracing::{debug, warn};
use url::Url;
Expand Down Expand Up @@ -300,6 +301,18 @@ impl DownloadStatus {
);
}

pub(crate) fn unpack<T: Read>(&self, inner: T) -> ProgressBarIter<T> {
self.progress.reset();
self.progress.set_style(
ProgressStyle::with_template(
"{msg:>12.bold} unpacking {spinner:.green} {total_bytes:>18}",
)
.unwrap()
.tick_chars(r"|/-\ "),
);
self.progress.wrap_read(inner)
}

pub(crate) fn installing(&self) {
self.progress.set_style(
ProgressStyle::with_template(
Expand All @@ -321,8 +334,7 @@ impl DownloadStatus {

fn file_hash(path: &Path) -> Result<String> {
let mut hasher = Sha256::new();
let mut downloaded = utils::FileReaderWithProgress::new_file(path)?;
use std::io::Read;
let mut downloaded = utils::buffered(path)?;
let mut buf = vec![0; 32768];
while let Ok(n) = downloaded.read(&mut buf) {
if n == 0 {
Expand Down
7 changes: 3 additions & 4 deletions src/dist/manifestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ impl Manifestation {
}

// Install all the components in the installer
let reader = utils::FileReaderWithProgress::new_file(&installer_file)?;
let reader = utils::buffered(&installer_file)?;
let package = DirectoryPackage::compressed(reader, CompressionKind::GZip, dl_cfg)?;
for component in package.components() {
tx = package.install(&self.installation, &component, None, tx)?;
Expand Down Expand Up @@ -720,9 +720,7 @@ impl<'a> ComponentBinary<'a> {
let short_pkg_name = component.short_name_in_manifest();
let short_name = component.short_name(self.manifest);

self.status.installing();

let reader = utils::FileReaderWithProgress::new_file(&installer_file)?;
let reader = self.status.unpack(utils::buffered(&installer_file)?);
let package =
DirectoryPackage::compressed(reader, self.binary.compression, self.download_cfg)?;

Expand All @@ -732,6 +730,7 @@ impl<'a> ComponentBinary<'a> {
return Err(RustupError::CorruptComponent(short_name).into());
}

self.status.installing();
let tx = package.install(
&manifestation.installation,
&pkg_name,
Expand Down
43 changes: 8 additions & 35 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::ops::{BitAnd, BitAndAssign};
use std::path::{Path, PathBuf};
use std::process::ExitStatus;

use anyhow::{Context, Result, anyhow, bail};
use anyhow::{Context, Result, anyhow};
use retry::delay::{Fibonacci, jitter};
use retry::{OperationResult, retry};
use tracing::{debug, info, warn};
Expand Down Expand Up @@ -444,40 +444,13 @@ pub(crate) fn delete_dir_contents_following_links(dir_path: &Path) {
}
}

pub(crate) struct FileReaderWithProgress {
fh: BufReader<File>,
nbytes: u64,
}

impl FileReaderWithProgress {
pub(crate) fn new_file(path: &Path) -> Result<Self> {
let fh = match File::open(path) {
Ok(fh) => fh,
Err(_) => {
bail!(RustupError::ReadingFile {
name: "downloaded",
path: path.to_path_buf(),
})
}
};

// Inform the tracker of the file size
Ok(FileReaderWithProgress {
fh: BufReader::with_capacity(8 * 1024 * 1024, fh),
nbytes: 0,
})
}
}

impl io::Read for FileReaderWithProgress {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.fh.read(buf) {
Ok(nbytes) => {
self.nbytes += nbytes as u64;
Ok(nbytes)
}
Err(e) => Err(e),
}
pub(crate) fn buffered(path: &Path) -> Result<BufReader<File>, anyhow::Error> {
match File::open(path) {
Ok(fh) => Ok(BufReader::with_capacity(8 * 1024 * 1024, fh)),
Err(_) => Err(anyhow!(RustupError::ReadingFile {
name: "downloaded",
path: path.to_path_buf(),
})),
}
}

Expand Down
Loading