Skip to content

Commit

Permalink
test: add bun workspace test and fix glob
Browse files Browse the repository at this point in the history
  • Loading branch information
nokazn committed Feb 11, 2024
1 parent d82bc05 commit 053057b
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 38 deletions.
67 changes: 30 additions & 37 deletions src/utils/glob.rs
Original file line number Diff line number Diff line change
@@ -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 = '!';

Expand All @@ -13,45 +12,39 @@ pub fn collect(
patterns: Option<Vec<String>>,
enable_negate: bool,
) -> Vec<PathBuf> {
let mut entries = Vec::<PathBuf>::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::<Vec<_>>();
} else {
entries.extend(matched);
let collect = || {
let mut entries = Vec::<PathBuf>::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::<Vec<_>>();
} else {
entries.extend(matched);
}
}
}
}
let result = entries
.iter()
.unique()
.filter_map(|entry| to_absolute_path(entry).ok())
.collect::<Vec<_>>();
result
let result = entries
.iter()
.unique()
.filter_map(|entry| to_absolute_path(entry).ok())
.collect::<Vec<_>>();
result
};

run_in_base_dir(&base_dir, collect, None)
}

fn resolve_glob(
base_dir: &PathBuf,
pattern: String,
enable_negate: bool,
) -> (Option<Vec<PathBuf>>, 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<Vec<PathBuf>>, bool) {
let (pattern, negate) = parse_negate(pattern, enable_negate);
match glob(&pattern) {
Ok(entries) => {
Expand Down
37 changes: 36 additions & 1 deletion src/utils/path.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use path_clean::PathClean;
use std::{
env::current_dir,
env::{current_dir, set_current_dir},
io,
path::{Path, PathBuf},
};

Expand All @@ -22,3 +23,37 @@ pub fn to_absolute_path<T: AsRef<Path>>(path: T) -> Result<PathBuf, Error> {
};
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<T, U, F>(base_dir: T, f: F, fallback: Option<U>) -> F::Output
where
T: AsRef<Path>,
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
}
49 changes: 49 additions & 0 deletions src/workspaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<String>>),
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::<Vec<_>>()
);
}

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"),
],
},
},
);
}
Binary file added tests/fixtures/workspaces/bun/bun.lockb
Binary file not shown.
9 changes: 9 additions & 0 deletions tests/fixtures/workspaces/bun/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"dependencies": {
"typescript": "^5.3.3"
},
"workspaces": [
"packages/*",
"packages/c"
]
}
1 change: 1 addition & 0 deletions tests/fixtures/workspaces/bun/packages/a/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions tests/fixtures/workspaces/bun/packages/b/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions tests/fixtures/workspaces/bun/packages/c/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}

0 comments on commit 053057b

Please sign in to comment.