22
33use std:: collections:: HashSet ;
44use std:: path:: Path ;
5+ use std:: sync:: LazyLock ;
56
67use toml:: Value ;
78
89use crate :: diagnostics:: TidyCtx ;
910
11+ static SUBMODULES : LazyLock < Vec < & ' static Path > > = LazyLock :: new ( || {
12+ // WORKSPACES doesn't list all submodules but it's contains the main at least
13+ crate :: deps:: WORKSPACES
14+ . iter ( )
15+ . map ( |ws| ws. submodules . iter ( ) )
16+ . flatten ( )
17+ . map ( |p| Path :: new ( p) )
18+ . collect ( )
19+ } ) ;
20+
1021pub fn check ( path : & Path , tidy_ctx : TidyCtx ) {
1122 let mut check = tidy_ctx. start_check ( "triagebot" ) ;
1223 let triagebot_path = path. join ( "triagebot.toml" ) ;
@@ -39,8 +50,13 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
3950 if !full_path. exists ( ) {
4051 // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder
4152 // to be checked against all the file and directories in the repository.
42- builder. add ( globset:: Glob :: new ( & format ! ( "{clean_path}*" ) ) . unwrap ( ) ) ;
53+ let trimmed_path = clean_path. trim_end_matches ( '/' ) ;
54+ builder. add ( globset:: Glob :: new ( & format ! ( "{trimmed_path}{{,/*}}" ) ) . unwrap ( ) ) ;
4355 glob_entries. push ( clean_path. to_string ( ) ) ;
56+ } else if is_in_submodule ( Path :: new ( clean_path) ) {
57+ check. error ( format ! (
58+ "triagebot.toml [mentions.*] '{clean_path}' cannot match inside a submodule"
59+ ) ) ;
4460 }
4561 }
4662
@@ -49,8 +65,18 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
4965 let mut found = HashSet :: new ( ) ;
5066 let mut matches = Vec :: new ( ) ;
5167
68+ let cloned_path = path. to_path_buf ( ) ;
69+
5270 // Walk the entire repository and match any entry against the remaining paths
53- for entry in ignore:: WalkBuilder :: new ( path) . build ( ) . flatten ( ) {
71+ for entry in ignore:: WalkBuilder :: new ( & path)
72+ . filter_entry ( move |entry| {
73+ // Ignore entries inside submodules as triagebot cannot detect them
74+ let entry_path = entry. path ( ) . strip_prefix ( & cloned_path) . unwrap ( ) ;
75+ is_not_in_submodule ( entry_path)
76+ } )
77+ . build ( )
78+ . flatten ( )
79+ {
5480 // Strip the prefix as mentions entries are always relative to the repo
5581 let entry_path = entry. path ( ) . strip_prefix ( path) . unwrap ( ) ;
5682
@@ -126,3 +152,11 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
126152 }
127153 }
128154}
155+
156+ fn is_not_in_submodule ( path : & Path ) -> bool {
157+ SUBMODULES . contains ( & path) || !SUBMODULES . iter ( ) . any ( |p| path. starts_with ( * p) )
158+ }
159+
160+ fn is_in_submodule ( path : & Path ) -> bool {
161+ !SUBMODULES . contains ( & path) && SUBMODULES . iter ( ) . any ( |p| path. starts_with ( * p) )
162+ }
0 commit comments