@@ -18,8 +18,9 @@ pub(crate) fn create_diff(
1818 github : Box < dyn GithubRead > ,
1919 teams : Vec < rust_team_data:: v1:: Team > ,
2020 repos : Vec < rust_team_data:: v1:: Repo > ,
21+ config : rust_team_data:: v1:: Config ,
2122) -> anyhow:: Result < Diff > {
22- let github = SyncGitHub :: new ( github, teams, repos) ?;
23+ let github = SyncGitHub :: new ( github, teams, repos, config ) ?;
2324 github. diff_all ( )
2425}
2526
@@ -29,6 +30,7 @@ struct SyncGitHub {
2930 github : Box < dyn GithubRead > ,
3031 teams : Vec < rust_team_data:: v1:: Team > ,
3132 repos : Vec < rust_team_data:: v1:: Repo > ,
33+ config : rust_team_data:: v1:: Config ,
3234 usernames_cache : HashMap < u64 , String > ,
3335 org_owners : HashMap < OrgName , HashSet < u64 > > ,
3436 org_members : HashMap < OrgName , HashMap < u64 , String > > ,
@@ -39,6 +41,7 @@ impl SyncGitHub {
3941 github : Box < dyn GithubRead > ,
4042 teams : Vec < rust_team_data:: v1:: Team > ,
4143 repos : Vec < rust_team_data:: v1:: Repo > ,
44+ config : rust_team_data:: v1:: Config ,
4245 ) -> anyhow:: Result < Self > {
4346 debug ! ( "caching mapping between user ids and usernames" ) ;
4447 let users = teams
@@ -72,6 +75,7 @@ impl SyncGitHub {
7275 github,
7376 teams,
7477 repos,
78+ config,
7579 usernames_cache,
7680 org_owners,
7781 org_members,
@@ -118,11 +122,7 @@ impl SyncGitHub {
118122 panic ! ( "GitHub organization {org} not found" ) ;
119123 } ;
120124
121- // Remove all members that are in TOML teams
122- let mut members_to_remove = gh_org_members. clone ( ) ;
123- for member in toml_members {
124- members_to_remove. remove ( & member) ;
125- }
125+ let members_to_remove = self . members_to_remove ( toml_members, gh_org_members) ;
126126
127127 // The rest are members that should be removed
128128 if !members_to_remove. is_empty ( ) {
@@ -142,6 +142,34 @@ impl SyncGitHub {
142142 Ok ( org_diffs. into_values ( ) . collect ( ) )
143143 }
144144
145+ /// Return GitHub members that should be removed from the organization.
146+ fn members_to_remove (
147+ & self ,
148+ toml_members : HashSet < u64 > ,
149+ gh_org_members : & HashMap < u64 , String > ,
150+ ) -> HashMap < u64 , String > {
151+ // Initialize `members_to_remove` to all GitHub members in the org.
152+ // Next, we'll delete members from `members_to_remove` that don't respect certain criteria.
153+ let mut members_to_remove = gh_org_members. clone ( ) ;
154+
155+ // People who belong to a team should stay in the org.
156+ for member in toml_members {
157+ members_to_remove. remove ( & member) ;
158+ }
159+
160+ // Members that are explicitly allowed in the `config.toml` file should stay in the org.
161+ for allowed_member in & self . config . allowed_org_members {
162+ if let Some ( member_to_retain) = members_to_remove
163+ . iter ( )
164+ . find ( |( _, username) | username == & allowed_member)
165+ . map ( |( id, _) | * id)
166+ {
167+ members_to_remove. remove ( & member_to_retain) ;
168+ }
169+ }
170+ members_to_remove
171+ }
172+
145173 fn diff_teams ( & self ) -> anyhow:: Result < Vec < TeamDiff > > {
146174 let mut diffs = Vec :: new ( ) ;
147175 let mut unseen_github_teams = HashMap :: new ( ) ;
@@ -735,7 +763,7 @@ struct OrgMembershipDiff {
735763impl OrgMembershipDiff {
736764 fn apply ( self , sync : & GitHubWrite ) -> anyhow:: Result < ( ) > {
737765 for member in & self . members_to_remove {
738- sync. remove_gh_member_from_org ( & self . org , & member) ?;
766+ sync. remove_gh_member_from_org ( & self . org , member) ?;
739767 }
740768
741769 Ok ( ( ) )
0 commit comments