11use core:: fmt;
22use std:: collections:: HashMap ;
3+ use std:: collections:: HashSet ;
34use std:: fmt:: Display ;
45use std:: path:: Path ;
56
@@ -32,6 +33,7 @@ struct Owner {
3233
3334#[ derive( Debug ) ]
3435enum Error {
36+ InvalidTeam { name : String , path : PathBuf } ,
3537 FileWithoutOwner { path : PathBuf } ,
3638 FileWithMultipleOwners { path : PathBuf , owners : Vec < Owner > } ,
3739 CodeownershipFileIsStale ,
@@ -45,6 +47,9 @@ impl Validator {
4547 pub fn validate ( & self ) -> Result < ( ) , Errors > {
4648 let mut validation_errors = Vec :: new ( ) ;
4749
50+ debug ! ( "validate_invalid_team" ) ;
51+ validation_errors. append ( & mut self . validate_invalid_team ( ) ) ;
52+
4853 debug ! ( "validate_file_ownership" ) ;
4954 validation_errors. append ( & mut self . validate_file_ownership ( ) ) ;
5055
@@ -58,6 +63,54 @@ impl Validator {
5863 }
5964 }
6065
66+ fn validate_invalid_team ( & self ) -> Vec < Error > {
67+ debug ! ( "validating project" ) ;
68+ let mut errors: Vec < Error > = Vec :: new ( ) ;
69+
70+ let team_names: HashSet < & String > = self . project . teams . iter ( ) . map ( |team| & team. name ) . collect ( ) ;
71+
72+ errors. append ( & mut self . invalid_team_annotation ( & team_names) ) ;
73+ errors. append ( & mut self . invalid_package_ownership ( & team_names) ) ;
74+
75+ errors
76+ }
77+
78+ fn invalid_team_annotation ( & self , team_names : & HashSet < & String > ) -> Vec < Error > {
79+ self . project
80+ . files
81+ . par_iter ( )
82+ . flat_map ( |file| {
83+ if let Some ( owner) = & file. owner {
84+ if !team_names. contains ( owner) {
85+ return Some ( Error :: InvalidTeam {
86+ name : owner. clone ( ) ,
87+ path : file. path . clone ( ) ,
88+ } ) ;
89+ }
90+ }
91+
92+ None
93+ } )
94+ . collect ( )
95+ }
96+
97+ fn invalid_package_ownership ( & self , team_names : & HashSet < & String > ) -> Vec < Error > {
98+ self . project
99+ . packages
100+ . iter ( )
101+ . flat_map ( |package| {
102+ if !team_names. contains ( & package. owner ) {
103+ Some ( Error :: InvalidTeam {
104+ name : package. owner . clone ( ) ,
105+ path : package. path . clone ( ) ,
106+ } )
107+ } else {
108+ None
109+ }
110+ } )
111+ . collect ( )
112+ }
113+
61114 fn validate_file_ownership ( & self ) -> Vec < Error > {
62115 let mut validation_errors = Vec :: new ( ) ;
63116
@@ -135,6 +188,7 @@ impl Error {
135188 Error :: CodeownershipFileIsStale => {
136189 "CODEOWNERS out of date. Run `codeownership generate` to update the CODEOWNERS file" . to_owned ( )
137190 }
191+ Error :: InvalidTeam { name : _, path : _ } => "Found invalid team annotaitons." . to_owned ( ) ,
138192 }
139193 }
140194
@@ -152,6 +206,7 @@ impl Error {
152206 } )
153207 . collect_vec ( ) ,
154208 Error :: CodeownershipFileIsStale => vec ! [ ] ,
209+ Error :: InvalidTeam { name, path } => vec ! [ format!( "- {} is referencing an invalid team - '{}'" , path. to_string_lossy( ) , name) ] ,
155210 }
156211 }
157212}
0 commit comments