diff --git a/crates/huak_ops/src/fs.rs b/crates/huak_ops/src/fs.rs index b9ef75f0..db3bc96d 100644 --- a/crates/huak_ops/src/fs.rs +++ b/crates/huak_ops/src/fs.rs @@ -5,41 +5,39 @@ use std::{ }; #[allow(dead_code)] -/// Copy contents from one directory into a new directory at a provided `to` full path. -/// If the `to` directory doesn't exist this function creates it. -pub fn copy_dir>(from: T, to: T) -> HuakResult<()> { - let (from, to) = (from.as_ref(), to.as_ref()); - let mut stack = Vec::new(); - stack.push(PathBuf::from(from)); - let target_root = to.to_path_buf(); - let from_component_count = from.to_path_buf().components().count(); - while let Some(working_path) = stack.pop() { - // Collects the trailing components of the path - let src: PathBuf = working_path - .components() - .skip(from_component_count) - .collect(); - let dest = if src.components().count() == 0 { - target_root.clone() - } else { - target_root.join(&src) - }; - if !dest.exists() { - fs::create_dir_all(&dest)?; - } - for entry in fs::read_dir(working_path)? { - let path = entry?.path(); - if path.is_dir() { - stack.push(path); - } else if let Some(filename) = path.file_name() { - fs::copy(&path, dest.join(filename))?; +pub fn copy_dir>( + from: T, + to: T, + options: &CopyDirOptions, +) -> Result<(), Error> { + let from = from.as_ref(); + let to = to.as_ref(); + + if from.is_dir() { + for entry in fs::read_dir(from)?.filter_map(|e| e.ok()) { + let entry_path = entry.path(); + if options.exclude.contains(&entry_path) { + continue; + } + + let destination = to.join(entry.file_name()); + if entry.file_type()?.is_dir() { + fs::create_dir_all(&destination)?; + copy_dir(entry.path(), destination, options)?; + } else { + fs::copy(entry.path(), &destination)?; } } } - Ok(()) } +#[derive(Default)] +pub struct CopyDirOptions { + /// Exclude paths + pub exclude: Vec, +} + /// Get an iterator over all paths found in each directory. pub fn flatten_directories( directories: impl IntoIterator, @@ -125,7 +123,8 @@ mod tests { fn test_copy_dir() { let to = tempdir().unwrap().into_path(); let from = crate::test_resources_dir_path().join("mock-project"); - copy_dir(from, to.join("mock-project")).unwrap(); + copy_dir(from, to.join("mock-project"), &CopyDirOptions::default()) + .unwrap(); assert!(to.join("mock-project").exists()); assert!(to.join("mock-project").join("pyproject.toml").exists()); @@ -135,7 +134,8 @@ mod tests { fn test_find_root_file_bottom_up() { let tmp = tempdir().unwrap().into_path(); let from = crate::test_resources_dir_path().join("mock-project"); - copy_dir(&from, &tmp.join("mock-project")).unwrap(); + copy_dir(&from, &tmp.join("mock-project"), &CopyDirOptions::default()) + .unwrap(); let res = find_root_file_bottom_up( "pyproject.toml", tmp.join("mock-project").as_path(), diff --git a/crates/huak_ops/src/ops/add.rs b/crates/huak_ops/src/ops/add.rs index d15f4e58..b9912220 100644 --- a/crates/huak_ops/src/ops/add.rs +++ b/crates/huak_ops/src/ops/add.rs @@ -132,7 +132,7 @@ pub fn add_project_optional_dependencies( mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, test_resources_dir_path, Verbosity, }; @@ -144,6 +144,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); @@ -172,6 +173,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let group = "dev"; diff --git a/crates/huak_ops/src/ops/build.rs b/crates/huak_ops/src/ops/build.rs index 1a263cfe..66388491 100644 --- a/crates/huak_ops/src/ops/build.rs +++ b/crates/huak_ops/src/ops/build.rs @@ -61,7 +61,7 @@ pub fn build_project( mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, test_resources_dir_path, Verbosity, }; @@ -73,6 +73,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/clean.rs b/crates/huak_ops/src/ops/clean.rs index 50d698eb..30b7ca8f 100644 --- a/crates/huak_ops/src/ops/clean.rs +++ b/crates/huak_ops/src/ops/clean.rs @@ -54,7 +54,11 @@ pub fn clean_project( #[cfg(test)] mod tests { use super::*; - use crate::{fs, ops::test_config, test_resources_dir_path, Verbosity}; + use crate::{ + fs::{self, CopyDirOptions}, + ops::test_config, + test_resources_dir_path, Verbosity, + }; use tempfile::tempdir; #[test] @@ -63,6 +67,7 @@ mod tests { fs::copy_dir( test_resources_dir_path().join("mock-project"), dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/format.rs b/crates/huak_ops/src/ops/format.rs index 26d26aec..f7659d86 100644 --- a/crates/huak_ops/src/ops/format.rs +++ b/crates/huak_ops/src/ops/format.rs @@ -95,7 +95,7 @@ pub fn format_project( mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, test_resources_dir_path, Verbosity, }; @@ -107,6 +107,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/install.rs b/crates/huak_ops/src/ops/install.rs index 960d3b9a..09d8102b 100644 --- a/crates/huak_ops/src/ops/install.rs +++ b/crates/huak_ops/src/ops/install.rs @@ -65,7 +65,7 @@ pub fn install_project_dependencies( mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, package::Package, test_resources_dir_path, Verbosity, @@ -79,6 +79,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); @@ -103,6 +104,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/lint.rs b/crates/huak_ops/src/ops/lint.rs index 474793dc..91ea1176 100644 --- a/crates/huak_ops/src/ops/lint.rs +++ b/crates/huak_ops/src/ops/lint.rs @@ -102,6 +102,7 @@ pub fn lint_project(config: &Config, options: &LintOptions) -> HuakResult<()> { #[cfg(test)] mod tests { use super::*; + use crate::fs::CopyDirOptions; use crate::ops::{test_config, test_venv}; use crate::{fs, test_resources_dir_path, Verbosity}; use tempfile::tempdir; @@ -112,6 +113,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); @@ -132,6 +134,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/remove.rs b/crates/huak_ops/src/ops/remove.rs index 20028ac8..7a6c3f1c 100644 --- a/crates/huak_ops/src/ops/remove.rs +++ b/crates/huak_ops/src/ops/remove.rs @@ -62,7 +62,7 @@ mod tests { use super::*; use crate::{ dependency::Dependency, - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, package::Package, test_resources_dir_path, Verbosity, @@ -76,6 +76,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); @@ -117,6 +118,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/run.rs b/crates/huak_ops/src/ops/run.rs index 9c75a430..ec0a53e7 100644 --- a/crates/huak_ops/src/ops/run.rs +++ b/crates/huak_ops/src/ops/run.rs @@ -20,7 +20,9 @@ pub fn run_command_str(command: &str, config: &Config) -> HuakResult<()> { mod tests { use super::*; use crate::{ - environment::env_path_string, fs, ops::test_config, + environment::env_path_string, + fs::{self, CopyDirOptions}, + ops::test_config, test_resources_dir_path, Verbosity, }; use tempfile::tempdir; @@ -31,6 +33,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/test.rs b/crates/huak_ops/src/ops/test.rs index 933fd7a5..45841e25 100644 --- a/crates/huak_ops/src/ops/test.rs +++ b/crates/huak_ops/src/ops/test.rs @@ -64,7 +64,7 @@ pub fn test_project(config: &Config, options: &TestOptions) -> HuakResult<()> { mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, test_resources_dir_path, Verbosity, }; @@ -76,6 +76,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); diff --git a/crates/huak_ops/src/ops/update.rs b/crates/huak_ops/src/ops/update.rs index 80561eca..07b21c9b 100644 --- a/crates/huak_ops/src/ops/update.rs +++ b/crates/huak_ops/src/ops/update.rs @@ -90,7 +90,7 @@ pub fn update_project_dependencies( mod tests { use super::*; use crate::{ - fs, + fs::{self, CopyDirOptions}, ops::{test_config, test_venv}, test_resources_dir_path, Verbosity, }; @@ -102,6 +102,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project"); @@ -122,6 +123,7 @@ mod tests { fs::copy_dir( &test_resources_dir_path().join("mock-project"), &dir.path().join("mock-project"), + &CopyDirOptions::default(), ) .unwrap(); let root = dir.path().join("mock-project");