|
1 | 1 | use crate::data::Data; |
| 2 | +use crate::schema; |
2 | 3 | use crate::schema::{Bot, Email, MergeBot, Permissions, RepoPermission, TeamKind, ZulipMember}; |
3 | 4 | use anyhow::{ensure, Context as _, Error}; |
4 | 5 | use indexmap::IndexMap; |
@@ -162,122 +163,22 @@ impl<'a> Generator<'a> { |
162 | 163 | } |
163 | 164 |
|
164 | 165 | fn generate_teams(&self) -> Result<(), Error> { |
165 | | - let mut teams = IndexMap::new(); |
166 | | - |
167 | | - for team in self.data.teams() { |
168 | | - let mut website_roles = HashMap::new(); |
169 | | - for member in team.explicit_members().iter().cloned() { |
170 | | - website_roles.insert(member.github, member.roles); |
171 | | - } |
172 | | - for alum in team.explicit_alumni().iter().cloned() { |
173 | | - website_roles.insert(alum.github, alum.roles); |
174 | | - } |
175 | | - |
176 | | - let leads = team.leads(); |
177 | | - let mut members = Vec::new(); |
178 | | - for github_name in &team.members(self.data)? { |
179 | | - if let Some(person) = self.data.person(github_name) { |
180 | | - members.push(v1::TeamMember { |
181 | | - name: person.name().into(), |
182 | | - github: (*github_name).into(), |
183 | | - github_id: person.github_id(), |
184 | | - is_lead: leads.contains(github_name), |
185 | | - roles: website_roles.get(*github_name).cloned().unwrap_or_default(), |
186 | | - }); |
187 | | - } |
188 | | - } |
189 | | - members.sort_by_key(|member| member.github.to_lowercase()); |
190 | | - members.sort_by_key(|member| !member.is_lead); |
191 | | - |
192 | | - let mut alumni = Vec::new(); |
193 | | - for alum in team.explicit_alumni() { |
194 | | - if let Some(person) = self.data.person(&alum.github) { |
195 | | - alumni.push(v1::TeamMember { |
196 | | - name: person.name().into(), |
197 | | - github: alum.github.to_string(), |
198 | | - github_id: person.github_id(), |
199 | | - is_lead: false, |
200 | | - roles: website_roles |
201 | | - .get(alum.github.as_str()) |
202 | | - .cloned() |
203 | | - .unwrap_or_default(), |
204 | | - }); |
205 | | - } |
206 | | - } |
207 | | - alumni.sort_by_key(|member| member.github.to_lowercase()); |
208 | | - |
209 | | - let mut github_teams = team.github_teams(self.data)?; |
210 | | - github_teams.sort(); |
211 | | - |
212 | | - let mut member_discord_ids = team.discord_ids(self.data)?; |
213 | | - member_discord_ids.sort(); |
214 | | - |
215 | | - let team_data = v1::Team { |
216 | | - name: team.name().into(), |
217 | | - kind: match team.kind() { |
218 | | - TeamKind::Team => v1::TeamKind::Team, |
219 | | - TeamKind::WorkingGroup => v1::TeamKind::WorkingGroup, |
220 | | - TeamKind::ProjectGroup => v1::TeamKind::ProjectGroup, |
221 | | - TeamKind::MarkerTeam => v1::TeamKind::MarkerTeam, |
222 | | - }, |
223 | | - subteam_of: team.subteam_of().map(|st| st.into()), |
224 | | - top_level: team.top_level(), |
225 | | - members, |
226 | | - alumni, |
227 | | - github: Some(v1::TeamGitHub { |
228 | | - teams: github_teams |
229 | | - .into_iter() |
230 | | - .map(|team| v1::GitHubTeam { |
231 | | - org: team.org.to_string(), |
232 | | - name: team.name.to_string(), |
233 | | - members: team.members.into_iter().map(|(_, id)| id).collect(), |
234 | | - }) |
235 | | - .collect::<Vec<_>>(), |
236 | | - }) |
237 | | - .filter(|gh| !gh.teams.is_empty()), |
238 | | - website_data: team.website_data().map(|ws| v1::TeamWebsite { |
239 | | - name: ws.name().into(), |
240 | | - description: ws.description().into(), |
241 | | - page: ws.page().unwrap_or_else(|| team.name()).into(), |
242 | | - email: ws.email().map(|e| e.into()), |
243 | | - repo: ws.repo().map(|e| e.into()), |
244 | | - discord: ws.discord().map(|i| v1::DiscordInvite { |
245 | | - channel: i.channel.into(), |
246 | | - url: i.url.into(), |
247 | | - }), |
248 | | - zulip_stream: ws.zulip_stream().map(|s| s.into()), |
249 | | - matrix_room: ws.matrix_room().map(|s| s.into()), |
250 | | - weight: ws.weight(), |
251 | | - }), |
252 | | - roles: team |
253 | | - .roles() |
254 | | - .iter() |
255 | | - .map(|role| v1::MemberRole { |
256 | | - id: role.id.clone(), |
257 | | - description: role.description.clone(), |
258 | | - }) |
259 | | - .collect(), |
260 | | - discord: team |
261 | | - .discord_roles() |
262 | | - .map(|roles| { |
263 | | - roles |
264 | | - .iter() |
265 | | - .map(|role| v1::TeamDiscord { |
266 | | - name: role.name().into(), |
267 | | - color: role.color().map(String::from), |
268 | | - members: member_discord_ids.clone(), |
269 | | - }) |
270 | | - .collect() |
271 | | - }) |
272 | | - .unwrap_or_else(Vec::new), |
273 | | - }; |
274 | | - |
275 | | - self.add(&format!("v1/teams/{}.json", team.name()), &team_data)?; |
276 | | - teams.insert(team.name().into(), team_data); |
| 166 | + let teams = convert_teams(self.data, self.data.teams())?; |
| 167 | + for (name, team) in &teams { |
| 168 | + self.add(&format!("v1/teams/{name}.json"), team)?; |
277 | 169 | } |
278 | | - |
279 | | - teams.sort_keys(); |
280 | 170 | self.add("v1/teams.json", &v1::Teams { teams })?; |
| 171 | + |
| 172 | + let archived_teams = convert_teams(self.data, self.data.archived_teams())?; |
| 173 | + for (name, team) in &archived_teams { |
| 174 | + self.add(&format!("v1/archived-teams/{name}.json"), team)?; |
| 175 | + } |
| 176 | + self.add( |
| 177 | + "v1/archived-teams.json", |
| 178 | + &v1::Teams { |
| 179 | + teams: archived_teams, |
| 180 | + }, |
| 181 | + )?; |
281 | 182 | Ok(()) |
282 | 183 | } |
283 | 184 |
|
@@ -529,3 +430,123 @@ impl<'a> Generator<'a> { |
529 | 430 | Ok(()) |
530 | 431 | } |
531 | 432 | } |
| 433 | + |
| 434 | +fn convert_teams<'a>( |
| 435 | + data: &Data, |
| 436 | + teams: impl Iterator<Item = &'a schema::Team>, |
| 437 | +) -> anyhow::Result<IndexMap<String, v1::Team>> { |
| 438 | + let mut team_map = IndexMap::new(); |
| 439 | + |
| 440 | + for team in teams { |
| 441 | + let mut website_roles = HashMap::new(); |
| 442 | + for member in team.explicit_members().iter().cloned() { |
| 443 | + website_roles.insert(member.github, member.roles); |
| 444 | + } |
| 445 | + for alum in team.explicit_alumni().iter().cloned() { |
| 446 | + website_roles.insert(alum.github, alum.roles); |
| 447 | + } |
| 448 | + |
| 449 | + let leads = team.leads(); |
| 450 | + let mut members = Vec::new(); |
| 451 | + for github_name in &team.members(data)? { |
| 452 | + if let Some(person) = data.person(github_name) { |
| 453 | + members.push(v1::TeamMember { |
| 454 | + name: person.name().into(), |
| 455 | + github: (*github_name).into(), |
| 456 | + github_id: person.github_id(), |
| 457 | + is_lead: leads.contains(github_name), |
| 458 | + roles: website_roles.get(*github_name).cloned().unwrap_or_default(), |
| 459 | + }); |
| 460 | + } |
| 461 | + } |
| 462 | + members.sort_by_key(|member| member.github.to_lowercase()); |
| 463 | + members.sort_by_key(|member| !member.is_lead); |
| 464 | + |
| 465 | + let mut alumni = Vec::new(); |
| 466 | + for alum in team.explicit_alumni() { |
| 467 | + if let Some(person) = data.person(&alum.github) { |
| 468 | + alumni.push(v1::TeamMember { |
| 469 | + name: person.name().into(), |
| 470 | + github: alum.github.to_string(), |
| 471 | + github_id: person.github_id(), |
| 472 | + is_lead: false, |
| 473 | + roles: website_roles |
| 474 | + .get(alum.github.as_str()) |
| 475 | + .cloned() |
| 476 | + .unwrap_or_default(), |
| 477 | + }); |
| 478 | + } |
| 479 | + } |
| 480 | + alumni.sort_by_key(|member| member.github.to_lowercase()); |
| 481 | + |
| 482 | + let mut github_teams = team.github_teams(data)?; |
| 483 | + github_teams.sort(); |
| 484 | + |
| 485 | + let mut member_discord_ids = team.discord_ids(data)?; |
| 486 | + member_discord_ids.sort(); |
| 487 | + |
| 488 | + let team_data = v1::Team { |
| 489 | + name: team.name().into(), |
| 490 | + kind: match team.kind() { |
| 491 | + TeamKind::Team => v1::TeamKind::Team, |
| 492 | + TeamKind::WorkingGroup => v1::TeamKind::WorkingGroup, |
| 493 | + TeamKind::ProjectGroup => v1::TeamKind::ProjectGroup, |
| 494 | + TeamKind::MarkerTeam => v1::TeamKind::MarkerTeam, |
| 495 | + }, |
| 496 | + subteam_of: team.subteam_of().map(|st| st.into()), |
| 497 | + top_level: team.top_level(), |
| 498 | + members, |
| 499 | + alumni, |
| 500 | + github: Some(v1::TeamGitHub { |
| 501 | + teams: github_teams |
| 502 | + .into_iter() |
| 503 | + .map(|team| v1::GitHubTeam { |
| 504 | + org: team.org.to_string(), |
| 505 | + name: team.name.to_string(), |
| 506 | + members: team.members.into_iter().map(|(_, id)| id).collect(), |
| 507 | + }) |
| 508 | + .collect::<Vec<_>>(), |
| 509 | + }) |
| 510 | + .filter(|gh| !gh.teams.is_empty()), |
| 511 | + website_data: team.website_data().map(|ws| v1::TeamWebsite { |
| 512 | + name: ws.name().into(), |
| 513 | + description: ws.description().into(), |
| 514 | + page: ws.page().unwrap_or_else(|| team.name()).into(), |
| 515 | + email: ws.email().map(|e| e.into()), |
| 516 | + repo: ws.repo().map(|e| e.into()), |
| 517 | + discord: ws.discord().map(|i| v1::DiscordInvite { |
| 518 | + channel: i.channel.into(), |
| 519 | + url: i.url.into(), |
| 520 | + }), |
| 521 | + zulip_stream: ws.zulip_stream().map(|s| s.into()), |
| 522 | + matrix_room: ws.matrix_room().map(|s| s.into()), |
| 523 | + weight: ws.weight(), |
| 524 | + }), |
| 525 | + roles: team |
| 526 | + .roles() |
| 527 | + .iter() |
| 528 | + .map(|role| v1::MemberRole { |
| 529 | + id: role.id.clone(), |
| 530 | + description: role.description.clone(), |
| 531 | + }) |
| 532 | + .collect(), |
| 533 | + discord: team |
| 534 | + .discord_roles() |
| 535 | + .map(|roles| { |
| 536 | + roles |
| 537 | + .iter() |
| 538 | + .map(|role| v1::TeamDiscord { |
| 539 | + name: role.name().into(), |
| 540 | + color: role.color().map(String::from), |
| 541 | + members: member_discord_ids.clone(), |
| 542 | + }) |
| 543 | + .collect() |
| 544 | + }) |
| 545 | + .unwrap_or_else(Vec::new), |
| 546 | + }; |
| 547 | + team_map.insert(team.name().into(), team_data); |
| 548 | + } |
| 549 | + |
| 550 | + team_map.sort_keys(); |
| 551 | + Ok(team_map) |
| 552 | +} |
0 commit comments