diff --git a/Cargo.lock b/Cargo.lock index 04e219b..086fb69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -995,6 +995,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -1351,7 +1360,7 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vercel-cache-helper" -version = "0.2.3" +version = "0.2.4" dependencies = [ "atty", "clap", @@ -1366,6 +1375,7 @@ dependencies = [ "tempfile", "tokio", "tokio-util", + "walkdir", "zstd", ] @@ -1375,6 +1385,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1495,6 +1515,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index fb8c11e..62e41d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vercel-cache-helper" -version = "0.2.3" +version = "0.2.4" edition = "2021" description = "Hello world" @@ -21,3 +21,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" futures = "0.3" tokio-util = { version = "0.7.9", features = ["codec"]} +walkdir = "2" diff --git a/src/commands/upload.rs b/src/commands/upload.rs index 14d9558..495d44a 100644 --- a/src/commands/upload.rs +++ b/src/commands/upload.rs @@ -1,5 +1,5 @@ use indicatif::{ProgressBar, ProgressStyle}; -use std::io::{Seek, Read}; +use std::io::{Read, Seek}; pub async fn upload( remote_client: vercel_cache_helper::vercel::remote_client::RemoteClient, @@ -39,7 +39,7 @@ pub async fn upload( let mut output_dir_archive = tempfile::tempfile()?; - vercel_cache_helper::utils::create_tar_zst_archive( + vercel_cache_helper::utils::create_filtered_tar_zst_archive( &output_dir.path().to_path_buf(), &output_dir_archive, )?; @@ -64,7 +64,8 @@ pub async fn upload( pb.set_message("Uploading artfiacts..."); let response = output_put_req - .buffer(&mut output_archive_buf, output_archive_size).await?; + .buffer(&mut output_archive_buf, output_archive_size) + .await?; if !response.status().is_success() { println!("Could not upload artifacts."); diff --git a/src/constants.rs b/src/constants.rs new file mode 100644 index 0000000..97d083d --- /dev/null +++ b/src/constants.rs @@ -0,0 +1 @@ +pub const VALID_EXTENSIONS: [&str; 5] = ["html", "css", "js", "json", "ftd"]; diff --git a/src/lib.rs b/src/lib.rs index abe6041..e4bf027 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ use std::convert::From; pub enum Error { FileNotFound(String), InvalidInput(String), + WalkDirError(String), EnvVarNotFound(String), ReqwestError(String), Other(Box), @@ -16,6 +17,7 @@ impl std::fmt::Display for Error { match self { Error::FileNotFound(message) => write!(f, "File not found: {}", message), Error::InvalidInput(message) => write!(f, "Invalid input: {}", message), + Error::WalkDirError(message) => write!(f, "Walkdir error: {}", message), Error::EnvVarNotFound(var_name) => { write!(f, "Environment variable not found: {}", var_name) } @@ -35,6 +37,12 @@ impl From for Error { } } +impl From for Error { + fn from(walkdir_error: walkdir::Error) -> Self { + Error::WalkDirError(walkdir_error.to_string()) + } +} + impl From for Error { fn from(env_error: std::env::VarError) -> Self { Error::EnvVarNotFound(env_error.to_string()) @@ -48,6 +56,7 @@ impl From for Error { } pub mod commands; +pub mod constants; pub mod utils; pub mod vercel; diff --git a/src/utils.rs b/src/utils.rs index db3124e..1c1bcc6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -132,3 +132,63 @@ pub fn extract_tar_zst(file: std::fs::File, dest_path: &std::path::PathBuf) -> s println!("Unpacked archive in: {}", &dest_path.to_string_lossy()); Ok(()) } + +pub fn create_filtered_tar_zst_archive( + src_folder: &std::path::PathBuf, + dest_file: &std::fs::File, +) -> vercel_cache_helper::Result<()> { + println!("Creating archive from: {:?}", src_folder); + + if !src_folder.exists() { + println!("Source folder does not exist: {:?}", src_folder); + return Ok(()); + } + + if std::fs::read_dir(src_folder)?.next().is_none() { + println!("Source folder is empty: {:?}", src_folder); + return Ok(()); + } + + 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.into()); + } + }; + + let mut tar_builder = tar::Builder::new(zst_encoder); + + let walker = walkdir::WalkDir::new(src_folder).into_iter(); + for entry in walker { + let entry = entry?; + let path = entry.path(); + + if path.starts_with(src_folder.join("-")) { + continue; + } + + if let Some(extension) = path.extension() { + let ext_str = extension.to_string_lossy().to_lowercase(); + if vercel_cache_helper::constants::VALID_EXTENSIONS.contains(&ext_str.as_ref()) { + // Calculate the relative path from src_folder to the current file + let relative_path = path.strip_prefix(src_folder).unwrap(); + + // Append the file to the archive with the relative path + tar_builder.append_path_with_name(path, relative_path)?; + } + } + } + + match tar_builder.into_inner()?.finish() { + Ok(_) => { + println!("Archive created successfully."); + Ok(()) + } + Err(err) => { + println!("Error closing the archive: {:?}", err); + Err(err.into()) + } + } +}