diff --git a/Cargo.lock b/Cargo.lock index d2378c2f5..e641364be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -274,6 +274,7 @@ dependencies = [ name = "archives" version = "0.0.0" dependencies = [ + "anki_io", "camino", "flate2", "reqwest", diff --git a/build/archives/Cargo.toml b/build/archives/Cargo.toml index 3092134d4..05e6a1dce 100644 --- a/build/archives/Cargo.toml +++ b/build/archives/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true rust-version.workspace = true [dependencies] +anki_io = { version = "0.0.0", path = "../../rslib/io" } camino = "1.1.4" flate2 = "1.0.25" sha2 = { version = "0.10.6" } diff --git a/build/archives/src/main.rs b/build/archives/src/main.rs index ddb74011c..3f6b4c724 100644 --- a/build/archives/src/main.rs +++ b/build/archives/src/main.rs @@ -4,7 +4,9 @@ use std::error::Error; use std::fs; use std::io::Read; +use std::path::Path; +use anki_io::read_file; use camino::Utf8Path; use sha2::Digest; @@ -19,7 +21,7 @@ async fn main() -> Result<()> { "download" => { let archive_url = &args[2]; let checksum = &args[3]; - let output_path = &args[4]; + let output_path = Path::new(&args[4]); download_and_check(archive_url, checksum, output_path).await?; } "extract" => { @@ -33,13 +35,15 @@ async fn main() -> Result<()> { Ok(()) } -async fn download_and_check(archive_url: &str, checksum: &str, output_path: &str) -> Result<()> { +async fn download_and_check(archive_url: &str, checksum: &str, output_path: &Path) -> Result<()> { + // skip download if we already have a valid file + if output_path.exists() && sha2_data(&read_file(output_path)?) == checksum { + return Ok(()); + } + let response = reqwest::get(archive_url).await?.error_for_status()?; let data = response.bytes().await?.to_vec(); - let mut digest = sha2::Sha256::new(); - digest.update(&data); - let result = digest.finalize(); - let actual_checksum = format!("{:x}", result); + let actual_checksum = sha2_data(&data); if actual_checksum != checksum { println!("expected {checksum}, got {actual_checksum}"); std::process::exit(1); @@ -49,6 +53,13 @@ async fn download_and_check(archive_url: &str, checksum: &str, output_path: &str Ok(()) } +fn sha2_data(data: &[u8]) -> String { + let mut digest = sha2::Sha256::new(); + digest.update(data); + let result = digest.finalize(); + format!("{:x}", result) +} + enum CompressionKind { Zstd, Gzip, diff --git a/build/ninja_gen/src/archives.rs b/build/ninja_gen/src/archives.rs index 70b40e797..075c22e81 100644 --- a/build/ninja_gen/src/archives.rs +++ b/build/ninja_gen/src/archives.rs @@ -97,6 +97,10 @@ impl BuildAction for DownloadArchive { fn on_first_instance(&self, build: &mut Build) -> Result<()> { build_archive_tool(build) } + + fn check_output_timestamps(&self) -> bool { + true + } } struct ExtractArchive<'a, I> { @@ -155,6 +159,10 @@ where fn name(&self) -> &'static str { "extract" } + + fn check_output_timestamps(&self) -> bool { + true + } } fn build_archive_tool(build: &mut Build) -> Result<()> {