@@ -6,8 +6,10 @@ use crate::handlers::docs_update::docs_update;
6
6
use crate :: handlers:: pr_tracking:: get_assigned_prs;
7
7
use crate :: handlers:: project_goals:: { self , ping_project_goals_owners} ;
8
8
use crate :: handlers:: Context ;
9
+ use crate :: team_data:: teams;
9
10
use crate :: utils:: pluralize;
10
11
use anyhow:: { format_err, Context as _} ;
12
+ use rust_team_data:: v1:: TeamKind ;
11
13
use std:: env;
12
14
use std:: fmt:: Write as _;
13
15
use std:: str:: FromStr ;
@@ -183,6 +185,8 @@ fn handle_command<'a>(
183
185
. map_err ( |e| format_err ! ( "Failed to parse movement, expected `move <from> <to>`: {e:?}." ) ) ,
184
186
Some ( "meta" ) => add_meta_notification ( & ctx, gh_id, words) . await
185
187
. map_err ( |e| format_err ! ( "Failed to parse `meta` command. Synopsis: meta <num> <text>: Add <text> to your notification identified by <num> (>0)\n \n Error: {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 \n Error: {e:?}" ) ) ,
186
190
Some ( "work" ) => workqueue_commands ( ctx, gh_id, words) . await
187
191
. map_err ( |e| format_err ! ( "Failed to parse `work` command. Help: {WORKQUEUE_HELP}\n \n Error: {e:?}" ) ) ,
188
192
_ => {
@@ -397,6 +401,64 @@ async fn workqueue_commands(
397
401
Ok ( Some ( response) )
398
402
}
399
403
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
+
400
462
// This does two things:
401
463
// * execute the command for the other user
402
464
// * tell the user executed for that a command was run as them by the user
0 commit comments