Skip to content

Commit 25cf611

Browse files
committed
use tmpfile dep to remove partial downloads upon failure.
1 parent 63aa795 commit 25cf611

2 files changed

Lines changed: 10 additions & 9 deletions

File tree

clang-installer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ tokio = { workspace = true, features = ["macros"], optional = true }
3636
url = "2.5.8"
3737
which = "8.0.2"
3838
zip = { version = "8.2.0", default-features = false, features = ["deflate"] }
39+
tempfile = { workspace = true }
3940

4041
[dev-dependencies]
4142
colored = { workspace = true }
4243
mockito = { workspace = true }
4344
reqwest = { workspace = true, default-features = true }
44-
tempfile = { workspace = true }
4545
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
4646

4747
[features]

clang-installer/src/downloader/mod.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ pub enum DownloadError {
2929
/// An error that describes the mismatch between the expected and actual hash of the downloaded file.
3030
#[error("Hash mismatch for downloaded file. Expected: {expected}, Actual: {actual}")]
3131
HashMismatch { expected: String, actual: String },
32+
33+
/// An error that occurred while moving/persisting a temporary file into a cache path.
34+
#[error("Error persisting temporary file: {0}")]
35+
TempFilePersistence(#[from] tempfile::PersistError),
3236
}
3337

3438
/// Downloads data from the specified URL and returns the response.
@@ -42,11 +46,6 @@ async fn download(url: &Url, cache_path: &Path, timeout: u64) -> Result<(), Down
4246
if let Some(cache_parent) = cache_path.parent() {
4347
fs::create_dir_all(cache_parent)?;
4448
}
45-
let mut cache_file = fs::OpenOptions::new()
46-
.write(true)
47-
.create(true)
48-
.truncate(true)
49-
.open(cache_path)?;
5049
let mut response = client.get(url.clone()).send().await?;
5150
if let Err(e) = response.error_for_status_ref() {
5251
if let Ok(body) = response.text().await
@@ -58,17 +57,19 @@ async fn download(url: &Url, cache_path: &Path, timeout: u64) -> Result<(), Down
5857
}
5958
return Err(e.into());
6059
}
60+
let mut tmp_file = tempfile::NamedTempFile::new()?;
6161
let content_len = response.content_length();
6262
let mut progress_bar = ProgressBar::new(content_len, "Downloading");
6363
progress_bar.render()?;
6464
while let Some(chunk) = response.chunk().await? {
6565
let chunk_len = chunk.len() as u64;
6666
progress_bar.inc(chunk_len)?;
67-
cache_file.write_all(&chunk)?;
67+
tmp_file.write_all(&chunk)?;
6868
}
6969
progress_bar.finish()?;
70-
cache_file.flush()?;
71-
cache_file.set_modified(SystemTime::now())?;
70+
tmp_file.flush()?;
71+
tmp_file.as_file_mut().set_modified(SystemTime::now())?;
72+
tmp_file.persist(cache_path)?;
7273
Ok(())
7374
}
7475

0 commit comments

Comments
 (0)