@@ -4,16 +4,13 @@ use std::path::Path;
44use crate :: ownership:: FileOwner ;
55use crate :: project:: Team ;
66
7- use super :: { Error , RunConfig , RunResult , Runner , config_from_path, run} ;
7+ use super :: { Error , ForFileResult , RunConfig , RunResult , Runner , config_from_path, run} ;
88
99pub fn for_file ( run_config : & RunConfig , file_path : & str , from_codeowners : bool , json : bool ) -> RunResult {
10- run ( run_config, |runner| {
11- if from_codeowners {
12- runner. for_file_codeowners_only ( file_path, json)
13- } else {
14- runner. for_file_derived ( file_path, json)
15- }
16- } )
10+ if from_codeowners {
11+ return for_file_codeowners_only_fast ( run_config, file_path, json) ;
12+ }
13+ for_file_optimized ( run_config, file_path, json)
1714}
1815
1916pub fn for_team ( run_config : & RunConfig , team_name : & str ) -> RunResult {
@@ -81,3 +78,65 @@ pub fn team_for_file_from_codeowners(run_config: &RunConfig, file_path: &str) ->
8178 . map_err ( Error :: Io ) ?;
8279 Ok ( res)
8380}
81+
82+ // Fast path that avoids creating a full Runner for single file queries
83+ fn for_file_optimized ( run_config : & RunConfig , file_path : & str , json : bool ) -> RunResult {
84+ let config = match config_from_path ( & run_config. config_path ) {
85+ Ok ( c) => c,
86+ Err ( err) => {
87+ return RunResult :: from_io_error ( Error :: Io ( err. to_string ( ) ) , json) ;
88+ }
89+ } ;
90+
91+ use crate :: ownership:: file_owner_resolver:: find_file_owners;
92+ let file_owners = match find_file_owners ( & run_config. project_root , & config, std:: path:: Path :: new ( file_path) ) {
93+ Ok ( v) => v,
94+ Err ( err) => {
95+ return RunResult :: from_io_error ( Error :: Io ( err) , json) ;
96+ }
97+ } ;
98+
99+ match file_owners. as_slice ( ) {
100+ [ ] => RunResult :: from_file_owner ( & crate :: ownership:: FileOwner :: default ( ) , json) ,
101+ [ owner] => RunResult :: from_file_owner ( owner, json) ,
102+ many => {
103+ let mut error_messages = vec ! [ "Error: file is owned by multiple teams!" . to_string( ) ] ;
104+ for owner in many {
105+ error_messages. push ( format ! ( "\n {}" , owner) ) ;
106+ }
107+ RunResult :: from_validation_errors ( error_messages, json)
108+ }
109+ }
110+ }
111+
112+ fn for_file_codeowners_only_fast ( run_config : & RunConfig , file_path : & str , json : bool ) -> RunResult {
113+ match team_for_file_from_codeowners ( run_config, file_path) {
114+ Ok ( Some ( team) ) => {
115+ let team_yml = crate :: path_utils:: relative_to ( & run_config. project_root , team. path . as_path ( ) )
116+ . to_string_lossy ( )
117+ . to_string ( ) ;
118+ let result = ForFileResult {
119+ team_name : team. name . clone ( ) ,
120+ github_team : team. github_team . clone ( ) ,
121+ team_yml,
122+ description : vec ! [ "Owner inferred from codeowners file" . to_string( ) ] ,
123+ } ;
124+ if json {
125+ RunResult :: json_info ( result)
126+ } else {
127+ RunResult {
128+ info_messages : vec ! [ format!(
129+ "Team: {}\n Github Team: {}\n Team YML: {}\n Description:\n - {}" ,
130+ result. team_name,
131+ result. github_team,
132+ result. team_yml,
133+ result. description. join( "\n - " )
134+ ) ] ,
135+ ..Default :: default ( )
136+ }
137+ }
138+ }
139+ Ok ( None ) => RunResult :: from_file_owner ( & crate :: ownership:: FileOwner :: default ( ) , json) ,
140+ Err ( err) => RunResult :: from_io_error ( Error :: Io ( format ! ( "{}" , err) ) , json) ,
141+ }
142+ }
0 commit comments