Skip to content

Commit 33d6a8c

Browse files
committed
rustup-dist: Use Download notifications to track install
People have requested some indication of progress for long-running install steps. This commit re-uses the download tracker logic to provide a progress bar (the length is the compressed component tarball but should be good enough) to provide such feedback. Fixes: #1557
1 parent be16639 commit 33d6a8c

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

src/rustup-dist/src/manifestation.rs

+52-2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,55 @@ pub enum UpdateStatus {
7474
Unchanged,
7575
}
7676

77+
struct FileReaderWithProgress<'a> {
78+
fh: std::fs::File,
79+
notify_handler: &'a Fn(Notification),
80+
sent_start: bool,
81+
nbytes: u64,
82+
flen: u64,
83+
}
84+
85+
impl<'a> FileReaderWithProgress<'a> {
86+
fn new_file(path: &Path, notify_handler: &'a Fn(Notification)) -> Result<Self> {
87+
Ok(FileReaderWithProgress {
88+
fh: std::fs::File::open(path)?,
89+
notify_handler,
90+
sent_start: false,
91+
nbytes: 0,
92+
flen: 0,
93+
})
94+
}
95+
}
96+
97+
impl<'a> std::io::Read for FileReaderWithProgress<'a> {
98+
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
99+
if !self.sent_start {
100+
// Send the start notifications
101+
let flen = self.fh.metadata()?.len();
102+
self.flen = flen;
103+
(self.notify_handler)(Notification::Utils(
104+
rustup_utils::Notification::DownloadContentLengthReceived(flen),
105+
));
106+
}
107+
match self.fh.read(buf) {
108+
Ok(nbytes) => {
109+
self.nbytes += nbytes as u64;
110+
if (nbytes == 0) || (self.flen == self.nbytes) {
111+
(self.notify_handler)(Notification::Utils(
112+
rustup_utils::Notification::DownloadFinished,
113+
));
114+
} else {
115+
(self.notify_handler)(Notification::Utils(
116+
rustup_utils::Notification::DownloadDataReceived(&buf[0..nbytes]),
117+
));
118+
}
119+
Ok(nbytes)
120+
}
121+
Err(e) => Err(e),
122+
}
123+
}
124+
}
125+
77126
impl Manifestation {
78127
/// Open the install prefix for updates from a distribution
79128
/// channel. The install prefix directory does not need to exist;
@@ -200,13 +249,14 @@ impl Manifestation {
200249

201250
let gz;
202251
let xz;
252+
let reader = FileReaderWithProgress::new_file(&installer_file, notify_handler)?;
203253
let package: &Package = match format {
204254
Format::Gz => {
205-
gz = TarGzPackage::new_file(&installer_file, temp_cfg)?;
255+
gz = TarGzPackage::new(reader, temp_cfg)?;
206256
&gz
207257
}
208258
Format::Xz => {
209-
xz = TarXzPackage::new_file(&installer_file, temp_cfg)?;
259+
xz = TarXzPackage::new(reader, temp_cfg)?;
210260
&xz
211261
}
212262
};

0 commit comments

Comments
 (0)