diff --git a/crates/core/src/filter.rs b/crates/core/src/filter.rs index ef48802..4474571 100644 --- a/crates/core/src/filter.rs +++ b/crates/core/src/filter.rs @@ -6,47 +6,55 @@ pub(crate) struct CopyFilter; impl CopyFilter { pub(crate) fn excludes(self, path: &Path) -> bool { - let parts = path - .components() - .filter_map(|component| match component { - Component::Normal(part) => Some(part), - _ => None, - }) - .collect::>(); + let mut parts = path.components().filter_map(|component| match component { + Component::Normal(part) => Some(part), + _ => None, + }); - parts.iter().any(|part| excludes_component(part)) - || parts - .windows(2) - .any(|parts| matches_yarn_artifact(parts[0], parts[1])) + let first = match parts.next() { + Some(p) => p, + None => return false, + }; + + if excludes_component(first) { + return true; + } + + let mut prev = first; + parts.any(|part| { + let result = excludes_component(part) || matches_yarn_artifact(prev, part); + prev = part; + result + }) } } fn excludes_component(part: &OsStr) -> bool { - [ - "node_modules", - ".pnpm-store", - "target", - ".venv", - "venv", - ".tox", - ".nox", - "__pycache__", - ".pytest_cache", - ".mypy_cache", - ".ruff_cache", - ".next", - ".nuxt", - ".svelte-kit", - ".turbo", - ".vite", - ".parcel-cache", - ".cache", - "dist", - "build", - "coverage", - ] - .into_iter() - .any(|excluded| part == excluded) + let Some(s) = part.to_str() else { return false }; + matches!( + s, + "node_modules" + | "target" + | ".pnpm-store" + | ".venv" + | "venv" + | ".tox" + | ".nox" + | "__pycache__" + | ".pytest_cache" + | ".mypy_cache" + | ".ruff_cache" + | ".next" + | ".nuxt" + | ".svelte-kit" + | ".turbo" + | ".vite" + | ".parcel-cache" + | ".cache" + | "dist" + | "build" + | "coverage" + ) } fn matches_yarn_artifact(first: &OsStr, second: &OsStr) -> bool { diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index e024b73..1c2b901 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -207,9 +207,6 @@ impl Manager { None => default_storage(&root.path)?, }; let name = RiftName::from_optional(input.name)?; - if destination_parent.join(name.as_str()).starts_with(&from) { - return Err(Error::InsideSource(destination_parent.join(name.as_str()))); - } fs::create_dir_all(&destination_parent)?; let destination_parent = fs::canonicalize(destination_parent)?; let destination = destination_parent.join(name.as_str());