Skip to content

Commit 24666bb

Browse files
Handle special codeowners glob (#722)
Github expands codeowners to match `file**` as `file*` and `file*/**`, so we need to handle that expansion.
1 parent 6687f97 commit 24666bb

File tree

1 file changed

+55
-16
lines changed

1 file changed

+55
-16
lines changed

codeowners/src/github.rs

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -194,23 +194,38 @@ pub struct PatternWithFallback {
194194

195195
impl PatternWithFallback {
196196
pub fn new(base: &str) -> anyhow::Result<Self> {
197-
// Matches anything that ends with neither a slash nor a period nor an asterisk,
198-
// see test pattern_with_fallback for cases
199-
static FALLBACK_NEEDED_REGEX: Lazy<Regex> =
200-
Lazy::new(|| Regex::new(r"^\/?(.*\/)*((\.?)[^\/\.\*]+)$").unwrap());
201-
202-
let base_pattern = Pattern::new(base).map_err(anyhow::Error::msg)?;
203-
let mut fallback_pattern = None;
204-
if FALLBACK_NEEDED_REGEX.is_match(base) {
205-
let mut subdir_match = base.to_string();
206-
subdir_match.push_str("/**");
207-
fallback_pattern = Pattern::new(&subdir_match).ok();
208-
}
197+
let result = if base.ends_with("**") && !base.ends_with("/**") && base.len() > 2 {
198+
let un_wildcarded = base.strip_suffix("**").unwrap_or(base);
199+
let base_pattern =
200+
Pattern::new(format!("{}*", un_wildcarded).as_str()).map_err(anyhow::Error::msg)?;
201+
let fallback_pattern = Pattern::new(format!("{}*/**", un_wildcarded).as_str())
202+
.map_err(anyhow::Error::msg)?;
203+
204+
Self {
205+
base: base_pattern,
206+
fallback: Some(fallback_pattern),
207+
}
208+
} else {
209+
// Matches anything that ends with neither a slash nor a period nor an asterisk,
210+
// see test pattern_with_fallback for cases
211+
static FALLBACK_NEEDED_REGEX: Lazy<Regex> =
212+
Lazy::new(|| Regex::new(r"^\/?(.*\/)*((\.?)[^\/\.\*]+)$").unwrap());
213+
214+
let base_pattern = Pattern::new(base).map_err(anyhow::Error::msg)?;
215+
let mut fallback_pattern = None;
216+
if FALLBACK_NEEDED_REGEX.is_match(base) {
217+
let mut subdir_match = base.to_string();
218+
subdir_match.push_str("/**");
219+
fallback_pattern = Pattern::new(&subdir_match).ok();
220+
}
221+
222+
Self {
223+
base: base_pattern,
224+
fallback: fallback_pattern,
225+
}
226+
};
209227

210-
Ok(Self {
211-
base: base_pattern,
212-
fallback: fallback_pattern,
213-
})
228+
Ok(result)
214229
}
215230

216231
pub fn matches_path_with(&self, path: &Path, options: MatchOptions) -> bool {
@@ -502,6 +517,30 @@ mod tests {
502517
fallback: None,
503518
},
504519
);
520+
521+
assert_eq!(
522+
PatternWithFallback::new("/abc**").unwrap(),
523+
PatternWithFallback {
524+
base: Pattern::new("/abc*").unwrap(),
525+
fallback: Some(Pattern::new("/abc*/**").unwrap()),
526+
},
527+
);
528+
529+
assert_eq!(
530+
PatternWithFallback::new("/**").unwrap(),
531+
PatternWithFallback {
532+
base: Pattern::new("/**").unwrap(),
533+
fallback: None,
534+
},
535+
);
536+
537+
assert_eq!(
538+
PatternWithFallback::new("**").unwrap(),
539+
PatternWithFallback {
540+
base: Pattern::new("**").unwrap(),
541+
fallback: None,
542+
},
543+
);
505544
}
506545

507546
#[test]

0 commit comments

Comments
 (0)