Skip to content

Commit 6792a75

Browse files
Merge pull request #2015 from Kobzol/whoami
Add `whoami` Zulip command
2 parents 874e154 + ff1ba7b commit 6792a75

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/zulip.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use crate::handlers::docs_update::docs_update;
66
use crate::handlers::pr_tracking::get_assigned_prs;
77
use crate::handlers::project_goals::{self, ping_project_goals_owners};
88
use crate::handlers::Context;
9+
use crate::team_data::teams;
910
use crate::utils::pluralize;
1011
use anyhow::{format_err, Context as _};
12+
use rust_team_data::v1::TeamKind;
1113
use std::env;
1214
use std::fmt::Write as _;
1315
use std::str::FromStr;
@@ -183,6 +185,8 @@ fn handle_command<'a>(
183185
.map_err(|e| format_err!("Failed to parse movement, expected `move <from> <to>`: {e:?}.")),
184186
Some("meta") => add_meta_notification(&ctx, gh_id, words).await
185187
.map_err(|e| format_err!("Failed to parse `meta` command. Synopsis: meta <num> <text>: Add <text> to your notification identified by <num> (>0)\n\nError: {e:?}")),
188+
Some("whoami") => whoami_cmd(&ctx, gh_id, words).await
189+
.map_err(|e| format_err!("Failed to run the `whoami` command. Synopsis: whoami: Show to which Rust teams you are a part of\n\nError: {e:?}")),
186190
Some("work") => workqueue_commands(ctx, gh_id, words).await
187191
.map_err(|e| format_err!("Failed to parse `work` command. Help: {WORKQUEUE_HELP}\n\nError: {e:?}")),
188192
_ => {
@@ -397,6 +401,64 @@ async fn workqueue_commands(
397401
Ok(Some(response))
398402
}
399403

404+
/// The `whoami` command displays the user's membership in Rust teams.
405+
async fn whoami_cmd(
406+
ctx: &Context,
407+
gh_id: u64,
408+
mut words: impl Iterator<Item = &str>,
409+
) -> anyhow::Result<Option<String>> {
410+
if words.next().is_some() {
411+
return Err(anyhow::anyhow!("Unexpected argument"));
412+
}
413+
414+
let gh_username = username_from_gh_id(&ctx.github, gh_id)
415+
.await?
416+
.ok_or_else(|| anyhow::anyhow!("Cannot find your GitHub username in the team database"))?;
417+
let teams = teams(&ctx.github)
418+
.await
419+
.context("cannot load team information")?;
420+
let mut entries = teams
421+
.teams
422+
.iter()
423+
.flat_map(|(_, team)| {
424+
team.members
425+
.iter()
426+
.filter(|member| member.github_id == gh_id)
427+
.map(move |member| (team, member))
428+
})
429+
.map(|(team, member)| {
430+
let main_role = if member.is_lead { "lead" } else { "member" };
431+
let mut entry = format!(
432+
"**{}** ({}): {main_role}",
433+
team.name,
434+
match team.kind {
435+
TeamKind::Team => "team",
436+
TeamKind::WorkingGroup => "working group",
437+
TeamKind::ProjectGroup => "project group",
438+
TeamKind::MarkerTeam => "marker team",
439+
TeamKind::Unknown => "unknown team kind",
440+
}
441+
);
442+
if !member.roles.is_empty() {
443+
write!(entry, " (roles: {})", member.roles.join(", ")).unwrap();
444+
}
445+
entry
446+
})
447+
.collect::<Vec<String>>();
448+
entries.sort();
449+
450+
let mut output = format!("You are **{gh_username}**.");
451+
if entries.is_empty() {
452+
output.push_str(" You are not a member of any Rust team.");
453+
} else {
454+
writeln!(output, " You are a member of the following Rust teams:")?;
455+
for entry in entries {
456+
writeln!(output, "- {entry}")?;
457+
}
458+
}
459+
Ok(Some(output))
460+
}
461+
400462
// This does two things:
401463
// * execute the command for the other user
402464
// * tell the user executed for that a command was run as them by the user

0 commit comments

Comments
 (0)