Avoid downloading files we already have

This commit is contained in:
Damien Elmes 2023-06-15 21:51:16 +10:00
parent de8f62f831
commit f70307a753
4 changed files with 27 additions and 6 deletions

1
Cargo.lock generated
View File

@ -274,6 +274,7 @@ dependencies = [
name = "archives" name = "archives"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"anki_io",
"camino", "camino",
"flate2", "flate2",
"reqwest", "reqwest",

View File

@ -9,6 +9,7 @@ license.workspace = true
rust-version.workspace = true rust-version.workspace = true
[dependencies] [dependencies]
anki_io = { version = "0.0.0", path = "../../rslib/io" }
camino = "1.1.4" camino = "1.1.4"
flate2 = "1.0.25" flate2 = "1.0.25"
sha2 = { version = "0.10.6" } sha2 = { version = "0.10.6" }

View File

@ -4,7 +4,9 @@
use std::error::Error; use std::error::Error;
use std::fs; use std::fs;
use std::io::Read; use std::io::Read;
use std::path::Path;
use anki_io::read_file;
use camino::Utf8Path; use camino::Utf8Path;
use sha2::Digest; use sha2::Digest;
@ -19,7 +21,7 @@ async fn main() -> Result<()> {
"download" => { "download" => {
let archive_url = &args[2]; let archive_url = &args[2];
let checksum = &args[3]; 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?; download_and_check(archive_url, checksum, output_path).await?;
} }
"extract" => { "extract" => {
@ -33,13 +35,15 @@ async fn main() -> Result<()> {
Ok(()) 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 response = reqwest::get(archive_url).await?.error_for_status()?;
let data = response.bytes().await?.to_vec(); let data = response.bytes().await?.to_vec();
let mut digest = sha2::Sha256::new(); let actual_checksum = sha2_data(&data);
digest.update(&data);
let result = digest.finalize();
let actual_checksum = format!("{:x}", result);
if actual_checksum != checksum { if actual_checksum != checksum {
println!("expected {checksum}, got {actual_checksum}"); println!("expected {checksum}, got {actual_checksum}");
std::process::exit(1); std::process::exit(1);
@ -49,6 +53,13 @@ async fn download_and_check(archive_url: &str, checksum: &str, output_path: &str
Ok(()) 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 { enum CompressionKind {
Zstd, Zstd,
Gzip, Gzip,

View File

@ -97,6 +97,10 @@ impl BuildAction for DownloadArchive {
fn on_first_instance(&self, build: &mut Build) -> Result<()> { fn on_first_instance(&self, build: &mut Build) -> Result<()> {
build_archive_tool(build) build_archive_tool(build)
} }
fn check_output_timestamps(&self) -> bool {
true
}
} }
struct ExtractArchive<'a, I> { struct ExtractArchive<'a, I> {
@ -155,6 +159,10 @@ where
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
"extract" "extract"
} }
fn check_output_timestamps(&self) -> bool {
true
}
} }
fn build_archive_tool(build: &mut Build) -> Result<()> { fn build_archive_tool(build: &mut Build) -> Result<()> {