Skip to content

Commit 3bd87f4

Browse files
committed
Create TeamApiClient and route all team data requests through it
1 parent 45b12cb commit 3bd87f4

18 files changed

+174
-112
lines changed

src/actions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize};
77
use tera::{Context, Tera};
88

99
use crate::github::{self, GithubClient, Repository};
10+
use crate::team_data::TeamApiClient;
1011

1112
#[async_trait]
1213
pub trait Action {
@@ -106,6 +107,7 @@ impl<'a> Action for Step<'a> {
106107
async fn call(&self) -> anyhow::Result<String> {
107108
let mut gh = GithubClient::new_from_env();
108109
gh.set_retry_rate_limit(true);
110+
let team_api = TeamApiClient::new_from_env();
109111

110112
let mut context = Context::new();
111113
let mut results = HashMap::new();
@@ -130,6 +132,7 @@ impl<'a> Action for Step<'a> {
130132
let kind = *kind;
131133
let repository = repository.clone();
132134
let gh = gh.clone();
135+
let team_api = team_api.clone();
133136
let query = query.clone();
134137
handles.push(tokio::task::spawn(async move {
135138
let _permit = semaphore.acquire().await?;
@@ -148,6 +151,7 @@ impl<'a> Action for Step<'a> {
148151
mcps_groups.contains(&name.as_str())
149152
&& repository.full_name.contains("rust-lang/compiler-team"),
150153
&gh,
154+
&team_api,
151155
)
152156
.await?;
153157
Ok((name, kind, issues))

src/bin/project_goals.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clap::Parser;
2+
use triagebot::team_data::TeamApiClient;
23
use triagebot::zulip::client::ZulipClient;
34
use triagebot::{github::GithubClient, handlers::project_goals};
45

@@ -24,9 +25,11 @@ async fn main() -> anyhow::Result<()> {
2425
let opt = Opt::parse();
2526
let gh = GithubClient::new_from_env();
2627
let zulip = ZulipClient::new_from_env();
28+
let team_api = TeamApiClient::new_from_env();
2729
project_goals::ping_project_goals_owners(
2830
&gh,
2931
&zulip,
32+
&team_api,
3033
opt.dry_run,
3134
opt.days_threshold,
3235
&opt.next_meeting_date,

src/github.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::team_data::TeamApiClient;
12
use anyhow::{anyhow, Context};
23
use async_trait::async_trait;
34
use bytes::Bytes;
@@ -240,9 +241,9 @@ impl User {
240241
.await
241242
}
242243

243-
pub async fn is_team_member<'a>(&'a self, client: &'a GithubClient) -> anyhow::Result<bool> {
244+
pub async fn is_team_member<'a>(&'a self, client: &'a TeamApiClient) -> anyhow::Result<bool> {
244245
log::trace!("Getting team membership for {:?}", self.login);
245-
let permission = crate::team_data::teams(client).await?;
246+
let permission = client.teams().await?;
246247
let map = permission.teams;
247248
let is_triager = map
248249
.get("wg-triage")
@@ -264,10 +265,10 @@ impl User {
264265

265266
// Returns the ID of the given user, if the user is in the `all` team.
266267
pub async fn get_id_for_username(
267-
client: &GithubClient,
268+
client: &TeamApiClient,
268269
login: &str,
269270
) -> anyhow::Result<Option<u64>> {
270-
let permission = crate::team_data::teams(client).await?;
271+
let permission = client.teams().await?;
271272
let map = permission.teams;
272273
let login = login.to_lowercase();
273274
Ok(map["all"]
@@ -278,21 +279,21 @@ pub async fn get_id_for_username(
278279
}
279280

280281
pub async fn get_team(
281-
client: &GithubClient,
282+
client: &TeamApiClient,
282283
team: &str,
283284
) -> anyhow::Result<Option<rust_team_data::v1::Team>> {
284-
let permission = crate::team_data::teams(client).await?;
285+
let permission = client.teams().await?;
285286
let mut map = permission.teams;
286287
Ok(map.swap_remove(team))
287288
}
288289

289290
/// Fetches a Rust team via its GitHub team name.
290291
pub async fn get_team_by_github_name(
291-
client: &GithubClient,
292+
client: &TeamApiClient,
292293
org: &str,
293294
team: &str,
294295
) -> anyhow::Result<Option<rust_team_data::v1::Team>> {
295-
let teams = crate::team_data::teams(client).await?;
296+
let teams = client.teams().await?;
296297
for rust_team in teams.teams.into_values() {
297298
if let Some(github) = &rust_team.github {
298299
for gh_team in &github.teams {
@@ -2055,10 +2056,11 @@ impl<'q> IssuesQuery for Query<'q> {
20552056
repo: &'a Repository,
20562057
include_fcp_details: bool,
20572058
include_mcp_details: bool,
2058-
client: &'a GithubClient,
2059+
gh_client: &'a GithubClient,
2060+
team_api_client: &'a TeamApiClient,
20592061
) -> anyhow::Result<Vec<crate::actions::IssueDecorator>> {
20602062
let issues = repo
2061-
.get_issues(&client, self)
2063+
.get_issues(&gh_client, self)
20622064
.await
20632065
.with_context(|| "Unable to get issues.")?;
20642066

@@ -2071,7 +2073,7 @@ impl<'q> IssuesQuery for Query<'q> {
20712073
};
20722074

20732075
let zulip_map = if include_fcp_details {
2074-
Some(crate::team_data::zulip_map(client).await?)
2076+
Some(team_api_client.zulip_map().await?)
20752077
} else {
20762078
None
20772079
};
@@ -2101,7 +2103,7 @@ impl<'q> IssuesQuery for Query<'q> {
21012103
let fk_initiating_comment = fcp.fcp.fk_initiating_comment;
21022104
let (initiating_comment_html_url, initiating_comment_content) = {
21032105
let comment = issue
2104-
.get_comment(&client, fk_initiating_comment)
2106+
.get_comment(gh_client, fk_initiating_comment)
21052107
.await
21062108
.with_context(|| {
21072109
format!(
@@ -2166,7 +2168,7 @@ impl<'q> IssuesQuery for Query<'q> {
21662168
};
21672169

21682170
let mcp_details = if include_mcp_details {
2169-
let first100_comments = issue.get_first100_comments(&client).await?;
2171+
let first100_comments = issue.get_first100_comments(&gh_client).await?;
21702172
let (zulip_link, concerns) = if !first100_comments.is_empty() {
21712173
let split = re_zulip_link
21722174
.split(&first100_comments[0].body)
@@ -2881,7 +2883,8 @@ pub trait IssuesQuery {
28812883
repo: &'a Repository,
28822884
include_fcp_details: bool,
28832885
include_mcp_details: bool,
2884-
client: &'a GithubClient,
2886+
gh_client: &'a GithubClient,
2887+
team_api_client: &'a TeamApiClient,
28852888
) -> anyhow::Result<Vec<crate::actions::IssueDecorator>>;
28862889
}
28872890

@@ -2894,6 +2897,7 @@ impl IssuesQuery for LeastRecentlyReviewedPullRequests {
28942897
_include_fcp_details: bool,
28952898
_include_mcp_details: bool,
28962899
client: &'a GithubClient,
2900+
_team_api_client: &'a TeamApiClient,
28972901
) -> anyhow::Result<Vec<crate::actions::IssueDecorator>> {
28982902
use cynic::QueryBuilder;
28992903
use github_graphql::queries;
@@ -3112,6 +3116,7 @@ impl IssuesQuery for DesignMeetings {
31123116
_include_fcp_details: bool,
31133117
_include_mcp_details: bool,
31143118
client: &'a GithubClient,
3119+
_team_api_client: &'a TeamApiClient,
31153120
) -> anyhow::Result<Vec<crate::actions::IssueDecorator>> {
31163121
use github_graphql::project_items::ProjectV2ItemContent;
31173122

src/handlers.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::config::{self, Config, ConfigurationError};
22
use crate::github::{Event, GithubClient, IssueCommentAction, IssuesAction, IssuesEvent};
33
use crate::handlers::pr_tracking::ReviewerWorkqueue;
4+
use crate::team_data::TeamApiClient;
45
use crate::zulip::client::ZulipClient;
56
use octocrab::Octocrab;
67
use parser::command::{assign::AssignCommand, Command, Input};
@@ -374,6 +375,7 @@ command_handlers! {
374375
pub struct Context {
375376
pub github: GithubClient,
376377
pub zulip: ZulipClient,
378+
pub team_api: TeamApiClient,
377379
pub db: crate::db::ClientPool,
378380
pub username: String,
379381
pub octocrab: Octocrab,

src/handlers/assign.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ async fn determine_assignee(
331331
diff: &[FileDiff],
332332
) -> anyhow::Result<(Option<ReviewerSelection>, bool)> {
333333
let mut db_client = ctx.db.get().await;
334-
let teams = crate::team_data::teams(&ctx.github).await?;
334+
let teams = &ctx.team_api.teams().await?;
335335
if let Some(name) = assign_command {
336336
// User included `r?` in the opening PR body.
337337
match find_reviewer_from_names(
@@ -510,12 +510,12 @@ pub(super) async fn handle_command(
510510
event: &Event,
511511
cmd: AssignCommand,
512512
) -> anyhow::Result<()> {
513-
let is_team_member = if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.github).await
514-
{
515-
false
516-
} else {
517-
true
518-
};
513+
let is_team_member =
514+
if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.team_api).await {
515+
false
516+
} else {
517+
true
518+
};
519519

520520
// Don't handle commands in comments from the bot. Some of the comments it
521521
// posts contain commands to instruct the user, not things that the bot
@@ -545,7 +545,7 @@ pub(super) async fn handle_command(
545545
return Ok(());
546546
}
547547

548-
let teams = crate::team_data::teams(&ctx.github).await?;
548+
let teams = ctx.team_api.teams().await?;
549549

550550
let assignee = match cmd {
551551
AssignCommand::Claim => event.user().login.clone(),

src/handlers/close.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(super) async fn handle_command(
1212
let issue = event.issue().unwrap();
1313
let is_team_member = event
1414
.user()
15-
.is_team_member(&ctx.github)
15+
.is_team_member(&ctx.team_api)
1616
.await
1717
.unwrap_or(false);
1818
if !is_team_member {

src/handlers/major_change.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ pub(super) async fn handle_command(
247247

248248
let is_team_member = event
249249
.user()
250-
.is_team_member(&ctx.github)
250+
.is_team_member(&ctx.team_api)
251251
.await
252252
.ok()
253253
.unwrap_or(false);

src/handlers/nominate.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ pub(super) async fn handle_command(
1414
event: &Event,
1515
cmd: NominateCommand,
1616
) -> anyhow::Result<()> {
17-
let is_team_member = if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.github).await
18-
{
19-
false
20-
} else {
21-
true
22-
};
17+
let is_team_member =
18+
if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.team_api).await {
19+
false
20+
} else {
21+
true
22+
};
2323

2424
if !is_team_member {
2525
let cmnt = ErrorComment::new(

src/handlers/notification.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub(super) async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> {
6969
//
7070
// If the user intended to ping themselves, they can add the GitHub comment
7171
// via the Zulip interface.
72-
match get_id_for_username(&ctx.github, &event.user().login).await {
72+
match get_id_for_username(&ctx.team_api, &event.user().login).await {
7373
Ok(Some(id)) => {
7474
users_notified.insert(id.try_into().unwrap());
7575
}
@@ -136,7 +136,7 @@ async fn id_from_user(
136136
//
137137
// We may also want to be able to categorize into these buckets
138138
// *after* the ping occurs and is initially processed.
139-
let team = match github::get_team_by_github_name(&ctx.github, org, team).await {
139+
let team = match github::get_team_by_github_name(&ctx.team_api, org, team).await {
140140
Ok(Some(team)) => team,
141141
Ok(None) => {
142142
// If the team is in rust-lang*, then this is probably an error (potentially user
@@ -170,7 +170,7 @@ async fn id_from_user(
170170
Some(team.name),
171171
)))
172172
} else {
173-
let id = get_id_for_username(&ctx.github, login)
173+
let id = get_id_for_username(&ctx.team_api, login)
174174
.await
175175
.with_context(|| format!("failed to get user {} ID", login))?;
176176
let Some(id) = id else {

src/handlers/ping.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ pub(super) async fn handle_command(
1818
event: &Event,
1919
team_name: PingCommand,
2020
) -> anyhow::Result<()> {
21-
let is_team_member = if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.github).await
22-
{
23-
false
24-
} else {
25-
true
26-
};
21+
let is_team_member =
22+
if let Err(_) | Ok(false) = event.user().is_team_member(&ctx.team_api).await {
23+
false
24+
} else {
25+
true
26+
};
2727

2828
if !is_team_member {
2929
let cmnt = ErrorComment::new(
@@ -49,7 +49,7 @@ pub(super) async fn handle_command(
4949
return Ok(());
5050
}
5151
};
52-
let team = github::get_team(&ctx.github, &gh_team).await?;
52+
let team = github::get_team(&ctx.team_api, &gh_team).await?;
5353
let team = match team {
5454
Some(team) => team,
5555
None => {

0 commit comments

Comments
 (0)