diff --git a/Cargo.lock b/Cargo.lock index 0faba31..b0ccbae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -615,6 +616,15 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.64" @@ -1321,6 +1331,7 @@ dependencies = [ "tar", "tempfile", "tokio", + "zstd", ] [[package]] @@ -1592,3 +1603,33 @@ checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.8+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +dependencies = [ + "cc", + "libc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index e757db9..f98400e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ indicatif = "0.17.7" dirs = "5.0.1" sha2 = "0.10.8" tar = "0.4.40" +zstd = "0.12" tempfile = "3.8.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/commands/download.rs b/src/commands/download.rs index e656878..2edd93a 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -18,13 +18,15 @@ pub async fn download( return Ok(()); }; let output_dir = tempfile::tempdir()?; - + let pb = ProgressBar::new_spinner(); pb.enable_steady_tick(std::time::Duration::new(0, 500)); - pb.set_style(ProgressStyle::default_spinner() - .template("[{spinner}] {prefix} {wide_msg}") - .unwrap() - .tick_chars("/|\\- ")); + pb.set_style( + ProgressStyle::default_spinner() + .template("[{spinner}] {prefix} {wide_msg}") + .unwrap() + .tick_chars("/|\\- "), + ); pb.set_message("Looking for artifacts..."); let mut output_exists_req = remote_client.exists( vercel_cache_helper::vercel::constants::FASTN_VERCEL_REMOTE_CACHE_HASH.to_string(), @@ -70,7 +72,10 @@ pub async fn download( .seek(std::io::SeekFrom::Start(0)) .unwrap(); - vercel_cache_helper::utils::extract_tar_gz(output_dir_archive, &output_dir.path())?; + vercel_cache_helper::utils::extract_tar_zst( + output_dir_archive, + &output_dir.path().to_path_buf(), + )?; let temp_build_dir = output_dir.path().join(".build"); let temp_cache_dir = output_dir.path().join("cache"); diff --git a/src/commands/upload.rs b/src/commands/upload.rs index 7de50a5..9c68100 100644 --- a/src/commands/upload.rs +++ b/src/commands/upload.rs @@ -21,10 +21,12 @@ pub async fn upload( let pb = ProgressBar::new_spinner(); pb.enable_steady_tick(std::time::Duration::new(0, 500)); - pb.set_style(ProgressStyle::default_spinner() - .template("[{spinner}] {prefix} {wide_msg}") - .unwrap() - .tick_chars("/|\\- ")); + pb.set_style( + ProgressStyle::default_spinner() + .template("[{spinner}] {prefix} {wide_msg}") + .unwrap() + .tick_chars("/|\\- "), + ); pb.set_message("Preparing to upload artifacts..."); let build_dir = project_dir.join(".build"); @@ -37,7 +39,7 @@ pub async fn upload( let mut output_dir_archive = tempfile::tempfile()?; - vercel_cache_helper::utils::create_tar_gz_archive( + vercel_cache_helper::utils::create_tar_zst_archive( &output_dir.path().to_path_buf(), &output_dir_archive, )?; diff --git a/src/utils.rs b/src/utils.rs index c9d3567..ff263a7 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -57,11 +57,10 @@ pub fn copy_recursively( } Ok(()) } - -pub fn create_tar_gz_archive( +pub fn create_tar_zst_archive( src_folder: &std::path::PathBuf, dest_file: &std::fs::File, -) -> vercel_cache_helper::Result<()> { +) -> std::io::Result<()> { println!("Creating archive from: {:?}", src_folder); if !src_folder.exists() { @@ -74,35 +73,46 @@ pub fn create_tar_gz_archive( return Ok(()); } - let gz_encoder = std::io::BufWriter::new(flate2::write::GzEncoder::new( - dest_file, - flate2::Compression::default(), - )); - let mut tar_builder = tar::Builder::new(gz_encoder); + // Create the Zstd encoder with proper error handling + let zst_encoder = + match zstd::stream::write::Encoder::new(dest_file, zstd::DEFAULT_COMPRESSION_LEVEL) { + Ok(encoder) => encoder, + Err(err) => { + println!("Error creating Zstd encoder: {:?}", err); + return Err(err); + } + }; - tar_builder.append_dir_all("", src_folder).map_err(|e| { - println!("Error creating archive: {:?}", e); - e - })?; + let mut tar_builder = tar::Builder::new(zst_encoder); - println!("Archive created successfully."); - Ok(()) + tar_builder.append_dir_all("", src_folder)?; + + // Ensure the archive is properly flushed and closed + match tar_builder.into_inner()?.finish() { + Ok(_) => { + println!("Archive created successfully."); + Ok(()) + } + Err(err) => { + println!("Error closing the archive: {:?}", err); + Err(err) + } + } } -pub fn extract_tar_gz( - file: std::fs::File, - dest_path: &std::path::Path, -) -> vercel_cache_helper::Result<()> { +pub fn extract_tar_zst(file: std::fs::File, dest_path: &std::path::PathBuf) -> std::io::Result<()> { println!( "Preparing to extract archive in {}...", dest_path.to_string_lossy() ); - let archive = flate2::read::GzDecoder::new(file); - let mut archive = tar::Archive::new(archive); - if let Err(err) = archive.unpack(dest_path) { - println!("Error extracting archive: {}", err); - return Err(err.into()); - } + + let zst_decoder = zstd::stream::read::Decoder::new(file)?; + + let mut archive = tar::Archive::new(zst_decoder); + + // Ensure that directories are created as needed while extracting + archive.unpack(dest_path)?; + println!("Unpacked archive in: {}", &dest_path.to_string_lossy()); Ok(()) }