11//! Tidy check to ensure paths mentioned in triagebot.toml exist in the project.
22
3+ use std:: collections:: HashSet ;
34use std:: path:: Path ;
45
56use toml:: Value ;
@@ -22,6 +23,9 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
2223
2324 // Check [mentions."*"] sections, i.e. [mentions."compiler/rustc_const_eval/src/"]
2425 if let Some ( Value :: Table ( mentions) ) = config. get ( "mentions" ) {
26+ let mut builder = globset:: GlobSetBuilder :: new ( ) ;
27+ let mut glob_entries = Vec :: new ( ) ;
28+
2529 for ( entry_key, entry_val) in mentions. iter ( ) {
2630 // If the type is set to something other than "filename", then this is not a path.
2731 if entry_val. get ( "type" ) . is_some_and ( |t| t. as_str ( ) . unwrap_or_default ( ) != "filename" ) {
@@ -33,8 +37,37 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
3337 let full_path = path. join ( clean_path) ;
3438
3539 if !full_path. exists ( ) {
40+ // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder
41+ // to be checked against all the file and directories in the repository.
42+ builder. add ( globset:: Glob :: new ( & format ! ( "{clean_path}*" ) ) . unwrap ( ) ) ;
43+ glob_entries. push ( clean_path. to_string ( ) ) ;
44+ }
45+ }
46+
47+ let gs = builder. build ( ) . unwrap ( ) ;
48+
49+ let mut found = HashSet :: new ( ) ;
50+ let mut matches = Vec :: new ( ) ;
51+
52+ // Walk the entire repository and match any entry against the remaining paths
53+ for entry in ignore:: WalkBuilder :: new ( path) . build ( ) . flatten ( ) {
54+ // Strip the prefix as mentions entries are always relative to the repo
55+ let entry_path = entry. path ( ) . strip_prefix ( path) . unwrap ( ) ;
56+
57+ // Find the matches and add them to the found set
58+ gs. matches_into ( entry_path, & mut matches) ;
59+ found. extend ( matches. iter ( ) . copied ( ) ) ;
60+
61+ // Early-exist if all the globs have been matched
62+ if found. len ( ) == glob_entries. len ( ) {
63+ break ;
64+ }
65+ }
66+
67+ for ( i, clean_path) in glob_entries. iter ( ) . enumerate ( ) {
68+ if !found. contains ( & i) {
3669 check. error ( format ! (
37- "triagebot.toml [mentions.*] contains path '{clean_path}' which doesn't exist "
70+ "triagebot.toml [mentions.*] contains '{clean_path}' which doesn't match any file or directory in the repository "
3871 ) ) ;
3972 }
4073 }
0 commit comments