From 053057b496481e9dd6c729a2a1856bf8e19707ad Mon Sep 17 00:00:00 2001 From: nokazn <41154684+nokazn@users.noreply.github.com> Date: Sun, 11 Feb 2024 16:37:13 +0900 Subject: [PATCH] test: add bun workspace test and fix glob --- src/utils/glob.rs | 67 ++++++++---------- src/utils/path.rs | 37 +++++++++- src/workspaces.rs | 49 +++++++++++++ tests/fixtures/workspaces/bun/bun.lockb | Bin 0 -> 1322 bytes tests/fixtures/workspaces/bun/package.json | 9 +++ .../workspaces/bun/packages/a/package.json | 1 + .../workspaces/bun/packages/b/package.json | 1 + .../workspaces/bun/packages/c/package.json | 1 + 8 files changed, 127 insertions(+), 38 deletions(-) create mode 100755 tests/fixtures/workspaces/bun/bun.lockb create mode 100644 tests/fixtures/workspaces/bun/package.json create mode 100644 tests/fixtures/workspaces/bun/packages/a/package.json create mode 100644 tests/fixtures/workspaces/bun/packages/b/package.json create mode 100644 tests/fixtures/workspaces/bun/packages/c/package.json diff --git a/src/utils/glob.rs b/src/utils/glob.rs index 0185f8b..0e42d73 100644 --- a/src/utils/glob.rs +++ b/src/utils/glob.rs @@ -1,10 +1,9 @@ use glob::glob; use itertools::Itertools; -use std::env::set_current_dir; use std::path::PathBuf; use crate::errors::{Error, Paths}; -use crate::utils::path::to_absolute_path; +use crate::utils::path::{run_in_base_dir, to_absolute_path}; const NEGATE: char = '!'; @@ -13,45 +12,39 @@ pub fn collect( patterns: Option>, enable_negate: bool, ) -> Vec { - let mut entries = Vec::::new(); - for pattern in patterns.unwrap_or_default() { - if let (Some(matched), negate) = resolve_glob(&base_dir, pattern, enable_negate) { - if negate { - entries = entries - .iter() - .filter_map(|entry| { - if matched.iter().any(|p| entry.starts_with(p)) { - None - } else { - Some(entry) - } - }) - .cloned() - .collect::>(); - } else { - entries.extend(matched); + let collect = || { + let mut entries = Vec::::new(); + for pattern in patterns.unwrap_or_default() { + if let (Some(matched), negate) = resolve_glob(pattern, enable_negate) { + if negate { + entries = entries + .iter() + .filter_map(|entry| { + if matched.iter().any(|p| entry.starts_with(p)) { + None + } else { + Some(entry) + } + }) + .cloned() + .collect::>(); + } else { + entries.extend(matched); + } } } - } - let result = entries - .iter() - .unique() - .filter_map(|entry| to_absolute_path(entry).ok()) - .collect::>(); - result + let result = entries + .iter() + .unique() + .filter_map(|entry| to_absolute_path(entry).ok()) + .collect::>(); + result + }; + + run_in_base_dir(&base_dir, collect, None) } -fn resolve_glob( - base_dir: &PathBuf, - pattern: String, - enable_negate: bool, -) -> (Option>, bool) { - if let Err(error) = set_current_dir(&base_dir) { - Error::NotAccessibleError(Paths::One(base_dir.clone())) - .log_debug(error) - .log_warn(None); - return (None, false); - } +fn resolve_glob(pattern: String, enable_negate: bool) -> (Option>, bool) { let (pattern, negate) = parse_negate(pattern, enable_negate); match glob(&pattern) { Ok(entries) => { diff --git a/src/utils/path.rs b/src/utils/path.rs index 0d7b425..b1165a5 100644 --- a/src/utils/path.rs +++ b/src/utils/path.rs @@ -1,6 +1,7 @@ use path_clean::PathClean; use std::{ - env::current_dir, + env::{current_dir, set_current_dir}, + io, path::{Path, PathBuf}, }; @@ -22,3 +23,37 @@ pub fn to_absolute_path>(path: T) -> Result { }; Ok(PathClean::clean(&absolute_path)) } + +/// Run a function `f` in the base directory `base_dir`, and go back to the original cwd. +pub fn run_in_base_dir(base_dir: T, f: F, fallback: Option) -> F::Output +where + T: AsRef, + F: FnOnce() -> U, + U: Default, +{ + let on_io_error = |error: io::Error| { + Error::NotAccessibleError(Paths::One(base_dir.as_ref().to_path_buf())) + .log_debug(&error) + .log_error(None); + fallback.unwrap_or_default() + }; + + let cwd = match current_dir() { + Ok(cwd) => cwd, + Err(error) => { + return on_io_error(error); + } + }; + + if let Err(error) = set_current_dir(&base_dir) { + return on_io_error(error); + }; + + let result = f(); + + if let Err(error) = set_current_dir(&cwd) { + on_io_error(error); + } + + result +} diff --git a/src/workspaces.rs b/src/workspaces.rs index 5441f35..5b51e93 100644 --- a/src/workspaces.rs +++ b/src/workspaces.rs @@ -88,3 +88,52 @@ impl PnpmWorkspace { Err(Error::NoEntryError(Paths::Multiple(file_paths.to_vec()))) } } + +#[cfg(test)] +mod tests { + use crate::test_each_serial; + + use super::*; + + struct NewTestCase { + input: (PathBuf, PackageManagerKind, Option>), + expected: Workspaces, + } + + fn test_new_each(case: NewTestCase) { + let base_dir = case.input.0; + let workspaces = Workspaces::new(base_dir.clone(), case.input.1, case.input.2); + assert_eq!(workspaces.kind, case.expected.kind); + assert_eq!( + workspaces.packages, + case + .expected + .packages + .iter() + .map(|path| base_dir.join(path).canonicalize().unwrap()) + .collect::>() + ); + } + + test_each_serial!( + test_new, + "bun" => NewTestCase { + input: ( + PathBuf::from("tests/fixtures/workspaces/bun"), + PackageManagerKind::Bun, + Some(vec![ + String::from("packages/*"), + String::from("!packages/c"), + ]), + ), + expected: Workspaces { + kind: PackageManagerKind::Bun, + packages: vec![ + PathBuf::from("./packages/a"), + PathBuf::from("./packages/b"), + PathBuf::from("./packages/c"), + ], + }, + }, + ); +} diff --git a/tests/fixtures/workspaces/bun/bun.lockb b/tests/fixtures/workspaces/bun/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..da2a398e37e9d3abc2743001c8ae960bf18c7b6b GIT binary patch literal 1322 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p-k54)DF z+jTwLvvrBA_#=-8yPFq&@-h=Ckl))qonQFI`B^MLML+;j3j!Pv3Qjjb`Bg9lP(Fm> zVqkzNV3@DkprhTIn#72rf^-hdA~B#=8=(2DK$;nfi8T%624r`j^8fMwLzX1gPy*^0 z86f5&8_lw`bk5o}K9}A&c)#|&z__0!cJir}?bf~(>3&~=4%ID*zOhqe)rWlrgJT!5M)01bZBa41gAElVxZbFC;zEy_#G2`(wh%uBaZFhp2nfnrffaWdHN z2Y!nzEt)bx1eCEsV*K|O+q{!4+*MLsoLU4lG4`@TV^Es+4^SZT0NvGMVS0wKg72RL z)D@H9t^xVW5U00FDhpDJlZ!G7N+32tOwTAODJZtm*Dp#<&nzw}s?^IX$jvI&%P&gT XM`+O3MdIj!Lqo45y$bC7K}Y}qIj-0j literal 0 HcmV?d00001 diff --git a/tests/fixtures/workspaces/bun/package.json b/tests/fixtures/workspaces/bun/package.json new file mode 100644 index 0000000..ce1e347 --- /dev/null +++ b/tests/fixtures/workspaces/bun/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "typescript": "^5.3.3" + }, + "workspaces": [ + "packages/*", + "packages/c" + ] +} diff --git a/tests/fixtures/workspaces/bun/packages/a/package.json b/tests/fixtures/workspaces/bun/packages/a/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/workspaces/bun/packages/a/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/workspaces/bun/packages/b/package.json b/tests/fixtures/workspaces/bun/packages/b/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/workspaces/bun/packages/b/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/workspaces/bun/packages/c/package.json b/tests/fixtures/workspaces/bun/packages/c/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/workspaces/bun/packages/c/package.json @@ -0,0 +1 @@ +{}