11use crate :: utils:: error:: { Error , Result } ;
22use ignore:: overrides:: { Override , OverrideBuilder } ;
3+
34use std:: path:: { Path , PathBuf } ;
45
5- use super :: types:: { CodeownersEntry , FileEntry , Tag } ;
6+ use super :: {
7+ smart_iter:: SmartIter ,
8+ types:: { CodeownersEntry , FileEntry , Tag } ,
9+ } ;
610
711/// Find all files tagged with a specific tag
812pub fn find_files_for_tag ( files : & [ FileEntry ] , tag : & Tag ) -> Vec < PathBuf > {
913 files
1014 . iter ( )
11- . filter ( |file_entry| file_entry. tags . contains ( tag) )
12- . map ( |file_entry| file_entry. path . clone ( ) )
15+ . filter_map ( |file_entry| {
16+ if file_entry. tags . contains ( tag) {
17+ Some ( file_entry. path . clone ( ) )
18+ } else {
19+ None
20+ }
21+ } )
1322 . collect ( )
1423}
1524
@@ -22,64 +31,63 @@ pub fn find_tags_for_file(file_path: &Path, entries: &[CodeownersEntry]) -> Resu
2231 )
2332 } ) ?;
2433
25- let mut candidates = Vec :: new ( ) ;
26-
27- for entry in entries {
28- let codeowners_dir = match entry. source_file . parent ( ) {
29- Some ( dir) => dir,
30- None => {
31- eprintln ! (
32- "CODEOWNERS entry has no parent directory: {}" ,
33- entry. source_file. display( )
34- ) ;
35- continue ;
34+ let mut candidates = entries
35+ . smart_iter ( 3 )
36+ . filter_map ( |entry| {
37+ let codeowners_dir = match entry. source_file . parent ( ) {
38+ Some ( dir) => dir,
39+ None => {
40+ eprintln ! (
41+ "CODEOWNERS entry has no parent directory: {}" ,
42+ entry. source_file. display( )
43+ ) ;
44+ return None ;
45+ }
46+ } ;
47+
48+ // Check if the CODEOWNERS directory is an ancestor of the target directory
49+ if !target_dir. starts_with ( codeowners_dir) {
50+ return None ;
3651 }
37- } ;
3852
39- // Check if the CODEOWNERS directory is an ancestor of the target directory
40- if !target_dir. starts_with ( codeowners_dir) {
41- continue ;
42- }
53+ // Calculate the depth as the number of components in the relative path from codeowners_dir to target_dir
54+ let rel_path = match target_dir. strip_prefix ( codeowners_dir) {
55+ Ok ( p) => p,
56+ Err ( _) => return None , // Should not happen due to starts_with check
57+ } ;
58+ let depth = rel_path. components ( ) . count ( ) ;
4359
44- // Calculate the depth as the number of components in the relative path from codeowners_dir to target_dir
45- let rel_path = match target_dir. strip_prefix ( codeowners_dir) {
46- Ok ( p) => p,
47- Err ( _) => continue , // Should not happen due to starts_with check
48- } ;
49- let depth = rel_path. components ( ) . count ( ) ;
50-
51- // Check if the pattern matches the target file
52- let matches = {
53- let mut builder = OverrideBuilder :: new ( codeowners_dir) ;
54- if let Err ( e) = builder. add ( & entry. pattern ) {
55- eprintln ! (
56- "Invalid pattern '{}' in {}: {}" ,
57- entry. pattern,
58- entry. source_file. display( ) ,
59- e
60- ) ;
61- continue ;
62- }
63- let over: Override = match builder. build ( ) {
64- Ok ( o) => o,
65- Err ( e) => {
60+ // Check if the pattern matches the target file
61+ let matches = {
62+ let mut builder = OverrideBuilder :: new ( codeowners_dir) ;
63+ if let Err ( e) = builder. add ( & entry. pattern ) {
6664 eprintln ! (
67- "Failed to build override for pattern '{}': {}" ,
68- entry. pattern, e
65+ "Invalid pattern '{}' in {}: {}" ,
66+ entry. pattern,
67+ entry. source_file. display( ) ,
68+ e
6969 ) ;
70- continue ;
70+ return None ;
7171 }
72+ let over: Override = match builder. build ( ) {
73+ Ok ( o) => o,
74+ Err ( e) => {
75+ eprintln ! (
76+ "Failed to build override for pattern '{}': {}" ,
77+ entry. pattern, e
78+ ) ;
79+ return None ;
80+ }
81+ } ;
82+ over. matched ( file_path, false ) . is_whitelist ( )
7283 } ;
73- over. matched ( file_path, false ) . is_whitelist ( )
74- } ;
7584
76- if matches {
77- candidates. push ( ( entry, depth) ) ;
78- }
79- }
85+ if matches { Some ( ( entry, depth) ) } else { None }
86+ } )
87+ . collect ( ) ;
8088
8189 // Sort the candidates by depth, source file, and line number
82- candidates. sort_by ( |a, b| {
90+ candidates. sort_unstable_by ( |a, b| {
8391 let a_entry = a. 0 ;
8492 let a_depth = a. 1 ;
8593 let b_entry = b. 0 ;
0 commit comments