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> {
|
pub(crate) fn build_glob_set<S: AsRef<str> + Debug>(globs: &[S]) -> anyhow::Result<NxGlobSet> {
|
||||||
let result = globs
|
let result = globs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.flat_map(|s| potential_glob_split(s.as_ref()))
|
||||||
let glob = s.as_ref();
|
.map(|glob| {
|
||||||
if glob.contains('!') || glob.contains('|') || glob.contains('(') {
|
if glob.contains('!') || glob.contains('|') || glob.contains('(') {
|
||||||
convert_glob(glob)
|
convert_glob(glob)
|
||||||
} else {
|
} 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"));
|
||||||
assert!(!glob_set.is_match("packages/package-a-b/nested"));
|
assert!(!glob_set.is_match("packages/package-a-b/nested"));
|
||||||
assert!(!glob_set.is_match("packages/package-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]
|
#[test]
|
||||||
@ -283,4 +300,24 @@ mod test {
|
|||||||
assert!(!glob_set.is_match("test.module.spec.tsx"));
|
assert!(!glob_set.is_match("test.module.spec.tsx"));
|
||||||
assert!(!glob_set.is_match("nested/comp.test.component.spec.ts"));
|
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>),
|
ExactOne(Cow<'a, str>),
|
||||||
// !(a|b|c)
|
// !(a|b|c)
|
||||||
Negated(Cow<'a, str>),
|
Negated(Cow<'a, str>),
|
||||||
|
// !(a|b|c).js
|
||||||
NegatedFileName(Cow<'a, str>),
|
NegatedFileName(Cow<'a, str>),
|
||||||
|
// !(a|b|c)*
|
||||||
|
NegatedWildcard(Cow<'a, str>),
|
||||||
NonSpecialGroup(Cow<'a, str>),
|
NonSpecialGroup(Cow<'a, str>),
|
||||||
NonSpecial(Cow<'a, str>),
|
NonSpecial(Cow<'a, str>),
|
||||||
}
|
}
|
||||||
@ -40,6 +43,13 @@ impl<'a> Display for GlobGroup<'a> {
|
|||||||
write!(f, "{}.", s)
|
write!(f, "{}.", s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GlobGroup::NegatedWildcard(s) => {
|
||||||
|
if s.contains(',') {
|
||||||
|
write!(f, "{{{}}}*", s)
|
||||||
|
} else {
|
||||||
|
write!(f, "{}*", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
GlobGroup::NonSpecial(s) => 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)
|
})(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>> {
|
fn non_special_character(input: &str) -> IResult<&str, GlobGroup, VerboseError<&str>> {
|
||||||
context(
|
context(
|
||||||
"non_special_character",
|
"non_special_character",
|
||||||
@ -107,6 +115,7 @@ fn parse_segment(input: &str) -> IResult<&str, Vec<GlobGroup>, VerboseError<&str
|
|||||||
one_or_more_group,
|
one_or_more_group,
|
||||||
exact_one_group,
|
exact_one_group,
|
||||||
negated_file_group,
|
negated_file_group,
|
||||||
|
negated_wildcard,
|
||||||
negated_group,
|
negated_group,
|
||||||
non_special_character,
|
non_special_character,
|
||||||
)),
|
)),
|
||||||
@ -149,6 +158,7 @@ pub fn parse_glob(input: &str) -> anyhow::Result<(bool, Vec<Vec<GlobGroup>>)> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use crate::native::glob::glob_group::GlobGroup;
|
use crate::native::glob::glob_group::GlobGroup;
|
||||||
use crate::native::glob::glob_parser::parse_glob;
|
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);
|
let on_group = build_segment(&built_glob, &group[1..], is_last_segment, true);
|
||||||
off_group.into_iter().chain(on_group).collect::<Vec<_>>()
|
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::OneOrMore(_)
|
||||||
| GlobGroup::ExactOne(_)
|
| GlobGroup::ExactOne(_)
|
||||||
| GlobGroup::NonSpecial(_)
|
| GlobGroup::NonSpecial(_)
|
||||||
@ -153,6 +158,15 @@ mod test {
|
|||||||
assert_eq!(negative_single_dir, ["!packages/package-a*", "packages/*"]);
|
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]
|
#[test]
|
||||||
fn test_transforming_globs() {
|
fn test_transforming_globs() {
|
||||||
let globs = convert_glob("!(test|e2e)/?(*.)+(spec|test).[jt]s!(x)?(.snap)").unwrap();
|
let globs = convert_glob("!(test|e2e)/?(*.)+(spec|test).[jt]s!(x)?(.snap)").unwrap();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user