@@ -43,97 +43,19 @@ pub fn for_file(run_config: &RunConfig, file_path: &str, from_codeowners: bool)
4343 for_file_optimized ( run_config, file_path)
4444}
4545
46- fn for_file_codeowners_only ( run_config : & RunConfig , file_path : & str ) -> RunResult {
47- match team_for_file_from_codeowners ( run_config, file_path) {
48- Ok ( Some ( team) ) => {
49- let relative_team_path = team
50- . path
51- . strip_prefix ( & run_config. project_root )
52- . unwrap_or ( team. path . as_path ( ) )
53- . to_string_lossy ( )
54- . to_string ( ) ;
55- RunResult {
56- info_messages : vec ! [ format!(
57- "Team: {}\n Github Team: {}\n Team YML: {}\n Description:\n - Owner inferred from codeowners file" ,
58- team. name, team. github_team, relative_team_path
59- ) ] ,
60- ..Default :: default ( )
61- }
62- }
63- Ok ( None ) => RunResult :: default ( ) ,
64- Err ( err) => RunResult {
65- io_errors : vec ! [ err. to_string( ) ] ,
66- ..Default :: default ( )
67- } ,
68- }
69- }
70- pub fn team_for_file_from_codeowners ( run_config : & RunConfig , file_path : & str ) -> Result < Option < Team > , Error > {
46+ pub fn file_owners_for_file ( run_config : & RunConfig , file_path : & str ) -> Result < Vec < FileOwner > , Error > {
7147 let config = config_from_path ( & run_config. config_path ) ?;
72- let relative_file_path = Path :: new ( file_path)
73- . strip_prefix ( & run_config. project_root )
74- . unwrap_or ( Path :: new ( file_path) ) ;
48+ use crate :: ownership:: for_file_fast:: find_file_owners;
49+ let owners = find_file_owners ( & run_config. project_root , & config, std:: path:: Path :: new ( file_path) ) . map_err ( Error :: Io ) ?;
7550
76- let parser = crate :: ownership:: parser:: Parser {
77- project_root : run_config. project_root . clone ( ) ,
78- codeowners_file_path : run_config. codeowners_file_path . clone ( ) ,
79- team_file_globs : config. team_file_glob . clone ( ) ,
80- } ;
81- Ok ( parser
82- . team_from_file_path ( Path :: new ( relative_file_path) )
83- . map_err ( |e| Error :: Io ( e. to_string ( ) ) ) ?)
51+ Ok ( owners)
8452}
8553
8654pub fn team_for_file ( run_config : & RunConfig , file_path : & str ) -> Result < Option < Team > , Error > {
87- let config = config_from_path ( & run_config. config_path ) ?;
88- use crate :: ownership:: for_file_fast:: find_file_owners;
89- let owners = find_file_owners ( & run_config. project_root , & config, std:: path:: Path :: new ( file_path) ) . map_err ( Error :: Io ) ?;
90-
55+ let owners = file_owners_for_file ( run_config, file_path) ?;
9156 Ok ( owners. first ( ) . map ( |fo| fo. team . clone ( ) ) )
9257}
9358
94- // (imports below intentionally trimmed after refactor)
95-
96- fn for_file_optimized ( run_config : & RunConfig , file_path : & str ) -> RunResult {
97- let config = match config_from_path ( & run_config. config_path ) {
98- Ok ( c) => c,
99- Err ( err) => {
100- return RunResult {
101- io_errors : vec ! [ err. to_string( ) ] ,
102- ..Default :: default ( )
103- } ;
104- }
105- } ;
106-
107- use crate :: ownership:: for_file_fast:: find_file_owners;
108- let file_owners = match find_file_owners ( & run_config. project_root , & config, std:: path:: Path :: new ( file_path) ) {
109- Ok ( v) => v,
110- Err ( err) => {
111- return RunResult {
112- io_errors : vec ! [ err] ,
113- ..Default :: default ( )
114- } ;
115- }
116- } ;
117-
118- let info_messages: Vec < String > = match file_owners. len ( ) {
119- 0 => vec ! [ format!( "{}" , FileOwner :: default ( ) ) ] ,
120- 1 => vec ! [ format!( "{}" , file_owners[ 0 ] ) ] ,
121- _ => {
122- let mut error_messages = vec ! [ "Error: file is owned by multiple teams!" . to_string( ) ] ;
123- for file_owner in file_owners {
124- error_messages. push ( format ! ( "\n {}" , file_owner) ) ;
125- }
126- return RunResult {
127- validation_errors : error_messages,
128- ..Default :: default ( )
129- } ;
130- }
131- } ;
132- RunResult {
133- info_messages,
134- ..Default :: default ( )
135- }
136- }
13759
13860pub fn version ( ) -> String {
13961 env ! ( "CARGO_PKG_VERSION" ) . to_string ( )
@@ -336,12 +258,137 @@ impl Runner {
336258 }
337259}
338260
261+
262+ fn for_file_codeowners_only ( run_config : & RunConfig , file_path : & str ) -> RunResult {
263+ match team_for_file_from_codeowners ( run_config, file_path) {
264+ Ok ( Some ( team) ) => {
265+ let relative_team_path = team
266+ . path
267+ . strip_prefix ( & run_config. project_root )
268+ . unwrap_or ( team. path . as_path ( ) )
269+ . to_string_lossy ( )
270+ . to_string ( ) ;
271+ RunResult {
272+ info_messages : vec ! [ format!(
273+ "Team: {}\n Github Team: {}\n Team YML: {}\n Description:\n - Owner inferred from codeowners file" ,
274+ team. name, team. github_team, relative_team_path
275+ ) ] ,
276+ ..Default :: default ( )
277+ }
278+ }
279+ Ok ( None ) => RunResult :: default ( ) ,
280+ Err ( err) => RunResult {
281+ io_errors : vec ! [ err. to_string( ) ] ,
282+ ..Default :: default ( )
283+ } ,
284+ }
285+ }
286+ pub fn team_for_file_from_codeowners ( run_config : & RunConfig , file_path : & str ) -> Result < Option < Team > , Error > {
287+ let config = config_from_path ( & run_config. config_path ) ?;
288+ let relative_file_path = Path :: new ( file_path)
289+ . strip_prefix ( & run_config. project_root )
290+ . unwrap_or ( Path :: new ( file_path) ) ;
291+
292+ let parser = crate :: ownership:: parser:: Parser {
293+ project_root : run_config. project_root . clone ( ) ,
294+ codeowners_file_path : run_config. codeowners_file_path . clone ( ) ,
295+ team_file_globs : config. team_file_glob . clone ( ) ,
296+ } ;
297+ Ok ( parser
298+ . team_from_file_path ( Path :: new ( relative_file_path) )
299+ . map_err ( |e| Error :: Io ( e. to_string ( ) ) ) ?)
300+ }
301+
302+ fn for_file_optimized ( run_config : & RunConfig , file_path : & str ) -> RunResult {
303+ let config = match config_from_path ( & run_config. config_path ) {
304+ Ok ( c) => c,
305+ Err ( err) => {
306+ return RunResult {
307+ io_errors : vec ! [ err. to_string( ) ] ,
308+ ..Default :: default ( )
309+ } ;
310+ }
311+ } ;
312+
313+ use crate :: ownership:: for_file_fast:: find_file_owners;
314+ let file_owners = match find_file_owners ( & run_config. project_root , & config, std:: path:: Path :: new ( file_path) ) {
315+ Ok ( v) => v,
316+ Err ( err) => {
317+ return RunResult {
318+ io_errors : vec ! [ err] ,
319+ ..Default :: default ( )
320+ } ;
321+ }
322+ } ;
323+
324+ let info_messages: Vec < String > = match file_owners. len ( ) {
325+ 0 => vec ! [ format!( "{}" , FileOwner :: default ( ) ) ] ,
326+ 1 => vec ! [ format!( "{}" , file_owners[ 0 ] ) ] ,
327+ _ => {
328+ let mut error_messages = vec ! [ "Error: file is owned by multiple teams!" . to_string( ) ] ;
329+ for file_owner in file_owners {
330+ error_messages. push ( format ! ( "\n {}" , file_owner) ) ;
331+ }
332+ return RunResult {
333+ validation_errors : error_messages,
334+ ..Default :: default ( )
335+ } ;
336+ }
337+ } ;
338+ RunResult {
339+ info_messages,
340+ ..Default :: default ( )
341+ }
342+ }
343+
339344#[ cfg( test) ]
340345mod tests {
346+ use tempfile:: tempdir;
347+
348+ use crate :: { common_test, ownership:: mapper:: Source } ;
349+
341350 use super :: * ;
342351
343352 #[ test]
344353 fn test_version ( ) {
345354 assert_eq ! ( version( ) , env!( "CARGO_PKG_VERSION" ) . to_string( ) ) ;
346355 }
356+ fn write_file ( temp_dir : & Path , file_path : & str , content : & str ) {
357+ let file_path = temp_dir. join ( file_path) ;
358+ let _ = std:: fs:: create_dir_all ( file_path. parent ( ) . unwrap ( ) ) ;
359+ std:: fs:: write ( file_path, content) . unwrap ( ) ;
360+ }
361+
362+ #[ test]
363+ fn test_file_owners_for_file ( ) {
364+ let temp_dir = tempdir ( ) . unwrap ( ) ;
365+ write_file ( & temp_dir. path ( ) , "config/code_ownership.yml" , & common_test:: tests:: DEFAULT_CODE_OWNERSHIP_YML ) ;
366+ [ "a" , "b" , "c" ] . iter ( ) . for_each ( |name| {
367+ let team_yml = format ! ( "name: {}\n github:\n team: \" @{}\" \n members:\n - {}member\n " , name, name, name) ;
368+ write_file ( & temp_dir. path ( ) , & format ! ( "config/teams/{}.yml" , name) , & team_yml) ;
369+ } ) ;
370+ write_file ( & temp_dir. path ( ) , "app/consumers/deep/nesting/nestdir/deep_file.rb" , "# @team b\n class DeepFile end;" ) ;
371+
372+ let run_config = RunConfig {
373+ project_root : temp_dir. path ( ) . to_path_buf ( ) ,
374+ codeowners_file_path : temp_dir. path ( ) . join ( ".github/CODEOWNERS" ) . to_path_buf ( ) ,
375+ config_path : temp_dir. path ( ) . join ( "config/code_ownership.yml" ) . to_path_buf ( ) ,
376+ no_cache : false ,
377+ } ;
378+
379+
380+ let file_owners = file_owners_for_file ( & run_config, "app/consumers/deep/nesting/nestdir/deep_file.rb" ) . unwrap ( ) ;
381+ assert_eq ! ( file_owners. len( ) , 1 ) ;
382+ assert_eq ! ( file_owners[ 0 ] . team. name, "b" ) ;
383+ assert_eq ! ( file_owners[ 0 ] . team. github_team, "@b" ) ;
384+ assert_eq ! ( file_owners[ 0 ] . team. path. to_string_lossy( ) . ends_with( "config/teams/b.yml" ) , true ) ;
385+ assert_eq ! ( file_owners[ 0 ] . sources. len( ) , 1 ) ;
386+ assert_eq ! ( file_owners[ 0 ] . sources, vec![ Source :: AnnotatedFile ] ) ;
387+
388+
389+ let team = team_for_file ( & run_config, "app/consumers/deep/nesting/nestdir/deep_file.rb" ) . unwrap ( ) . unwrap ( ) ;
390+ assert_eq ! ( team. name, "b" ) ;
391+ assert_eq ! ( team. github_team, "@b" ) ;
392+ assert_eq ! ( team. path. to_string_lossy( ) . ends_with( "config/teams/b.yml" ) , true ) ;
393+ }
347394}
0 commit comments