fix(core): change combine glob patterns to use the +() pattern (#20254)
This commit is contained in:
parent
dc8c0edb70
commit
ed77cb0b99
@ -69,11 +69,22 @@ impl NxGlobSet {
|
||||
}
|
||||
}
|
||||
|
||||
fn potential_glob_split(
|
||||
glob: &str,
|
||||
) -> itertools::Either<std::str::Split<char>, std::iter::Once<&str>> {
|
||||
use itertools::Either::*;
|
||||
if glob.starts_with('{') && glob.ends_with('}') {
|
||||
Left(glob.trim_matches('{').trim_end_matches('}').split(','))
|
||||
} else {
|
||||
Right(std::iter::once(glob))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build_glob_set<S: AsRef<str> + Debug>(globs: &[S]) -> anyhow::Result<NxGlobSet> {
|
||||
let result = globs
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let glob = s.as_ref();
|
||||
.flat_map(|s| potential_glob_split(s.as_ref()))
|
||||
.map(|glob| {
|
||||
if glob.contains('!') || glob.contains('|') || glob.contains('(') {
|
||||
convert_glob(glob)
|
||||
} else {
|
||||
@ -214,6 +225,12 @@ mod test {
|
||||
assert!(!glob_set.is_match("packages/package-a-b"));
|
||||
assert!(!glob_set.is_match("packages/package-a-b/nested"));
|
||||
assert!(!glob_set.is_match("packages/package-b/nested"));
|
||||
|
||||
let glob_set = build_glob_set(&["packages/!(package-a)*/package.json"]).unwrap();
|
||||
assert!(glob_set.is_match("packages/package-b/package.json"));
|
||||
assert!(glob_set.is_match("packages/package-c/package.json"));
|
||||
assert!(!glob_set.is_match("packages/package-a/package.json"));
|
||||
assert!(!glob_set.is_match("packages/package/a/package.json"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -283,4 +300,24 @@ mod test {
|
||||
assert!(!glob_set.is_match("test.module.spec.tsx"));
|
||||
assert!(!glob_set.is_match("nested/comp.test.component.spec.ts"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn supports_brace_expansion() {
|
||||
let glob_set = build_glob_set(&["{packages,apps}/*"]).unwrap();
|
||||
assert!(glob_set.is_match("packages/package-a"));
|
||||
assert!(glob_set.is_match("apps/app-a"));
|
||||
assert!(!glob_set.is_match("apps/app-a/nested"));
|
||||
|
||||
let glob_set = build_glob_set(&["{package-lock.json,yarn.lock,pnpm-lock.yaml}"]).unwrap();
|
||||
assert!(glob_set.is_match("package-lock.json"));
|
||||
assert!(glob_set.is_match("yarn.lock"));
|
||||
assert!(glob_set.is_match("pnpm-lock.yaml"));
|
||||
|
||||
let glob_set =
|
||||
build_glob_set(&["{packages/!(package-a)*/package.json,packages/*/package.json}"])
|
||||
.unwrap();
|
||||
assert!(glob_set.is_match("packages/package-b/package.json"));
|
||||
assert!(glob_set.is_match("packages/package-c/package.json"));
|
||||
assert!(!glob_set.is_match("packages/package-a/package.json"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,10 @@ pub enum GlobGroup<'a> {
|
||||
ExactOne(Cow<'a, str>),
|
||||
// !(a|b|c)
|
||||
Negated(Cow<'a, str>),
|
||||
// !(a|b|c).js
|
||||
NegatedFileName(Cow<'a, str>),
|
||||
// !(a|b|c)*
|
||||
NegatedWildcard(Cow<'a, str>),
|
||||
NonSpecialGroup(Cow<'a, str>),
|
||||
NonSpecial(Cow<'a, str>),
|
||||
}
|
||||
@ -40,6 +43,13 @@ impl<'a> Display for GlobGroup<'a> {
|
||||
write!(f, "{}.", s)
|
||||
}
|
||||
}
|
||||
GlobGroup::NegatedWildcard(s) => {
|
||||
if s.contains(',') {
|
||||
write!(f, "{{{}}}*", s)
|
||||
} else {
|
||||
write!(f, "{}*", s)
|
||||
}
|
||||
}
|
||||
GlobGroup::NonSpecial(s) => write!(f, "{}", s),
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,14 @@ fn negated_file_group(input: &str) -> IResult<&str, GlobGroup, VerboseError<&str
|
||||
})(input)
|
||||
}
|
||||
|
||||
fn negated_wildcard(input: &str) -> IResult<&str, GlobGroup, VerboseError<&str>> {
|
||||
context("negated_wildcard", |input| {
|
||||
let (input, result) = preceded(tag("!("), group)(input)?;
|
||||
let (input, _) = tag("*")(input)?;
|
||||
Ok((input, GlobGroup::NegatedWildcard(result)))
|
||||
})(input)
|
||||
}
|
||||
|
||||
fn non_special_character(input: &str) -> IResult<&str, GlobGroup, VerboseError<&str>> {
|
||||
context(
|
||||
"non_special_character",
|
||||
@ -107,6 +115,7 @@ fn parse_segment(input: &str) -> IResult<&str, Vec<GlobGroup>, VerboseError<&str
|
||||
one_or_more_group,
|
||||
exact_one_group,
|
||||
negated_file_group,
|
||||
negated_wildcard,
|
||||
negated_group,
|
||||
non_special_character,
|
||||
)),
|
||||
@ -149,6 +158,7 @@ pub fn parse_glob(input: &str) -> anyhow::Result<(bool, Vec<Vec<GlobGroup>>)> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::native::glob::glob_group::GlobGroup;
|
||||
use crate::native::glob::glob_parser::parse_glob;
|
||||
|
||||
@ -272,5 +282,18 @@ mod test {
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
let result = parse_glob("packages/!(package-a)*/package.json").unwrap();
|
||||
assert_eq!(
|
||||
result,
|
||||
(
|
||||
false,
|
||||
vec![
|
||||
vec![GlobGroup::NonSpecial("packages".into())],
|
||||
vec![GlobGroup::NegatedWildcard("package-a".into()),],
|
||||
vec![GlobGroup::NonSpecial("package.json".into())]
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,6 +88,11 @@ fn build_segment(
|
||||
let on_group = build_segment(&built_glob, &group[1..], is_last_segment, true);
|
||||
off_group.into_iter().chain(on_group).collect::<Vec<_>>()
|
||||
}
|
||||
GlobGroup::NegatedWildcard(_) => {
|
||||
let off_group = build_segment("*", &group[1..], is_last_segment, is_negative);
|
||||
let on_group = build_segment(&built_glob, &group[1..], is_last_segment, true);
|
||||
off_group.into_iter().chain(on_group).collect::<Vec<_>>()
|
||||
}
|
||||
GlobGroup::OneOrMore(_)
|
||||
| GlobGroup::ExactOne(_)
|
||||
| GlobGroup::NonSpecial(_)
|
||||
@ -153,6 +158,15 @@ mod test {
|
||||
assert_eq!(negative_single_dir, ["!packages/package-a*", "packages/*"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn convert_globs_single_negative_wildcard_directory() {
|
||||
let negative_single_dir = convert_glob("packages/!(package-a)*/package.json").unwrap();
|
||||
assert_eq!(
|
||||
negative_single_dir,
|
||||
["!packages/package-a*/", "packages/*/package.json"]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transforming_globs() {
|
||||
let globs = convert_glob("!(test|e2e)/?(*.)+(spec|test).[jt]s!(x)?(.snap)").unwrap();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user