11# ' Add GitHub Users to a Team
22# '
3+ # ' This also adds them to the organization that contains the team. All users
4+ # ' will get an invitation by email and on GitHub.com, that they need to accept.
5+ # ' This invitation expires after seven days.
6+ # '
37# ' @param team The name of the team.
48# ' @param members A vector of GitHub usernames.
59# ' @param org The GitHub organization that owns the team and the repository.
610# ' @importFrom purrr map safely map_lgl
11+ # '
12+ # ' @returns list of responses from the GitHub API
13+ # '
714# ' @export
815# ' @examples
916# ' \dontrun{
10- # '
11- # ' kyber::add_team_members("2021-ilm-rotj-team", members = c("erinmr", "seankross"))
17+ # ' add_team_members("2021-ilm-rotj-team", members = c("not-ateucher", "seankross"))
1218# ' }
1319add_team_members <- function (team , members , org = " openscapes" ) {
20+ resp <- add_remove_team_members_impl_(team , members , org , method = " PUT" )
21+ invisible (resp )
22+ }
23+
24+ # ' Remove GitHub Users from a Team
25+ # '
26+ # ' @inheritParams add_team_members
27+ # '
28+ # ' @returns list of responses from the GitHub API
29+ # '
30+ # ' @export
31+ # ' @examples
32+ # ' \dontrun{
33+ # ' remove_team_members("2021-ilm-rotj-team", members = "not-ateucher"))
34+ # ' }
35+ remove_team_members <- function (team , members , org = " openscapes" ) {
36+ resp <- add_remove_team_members_impl_(team , members , org , method = " DELETE" )
37+ invisible (resp )
38+ }
39+
40+ add_remove_team_members_impl_ <- function (
41+ team ,
42+ members ,
43+ org ,
44+ method = c(" PUT" , " DELETE" )
45+ ) {
1446 check_gh_pat()
1547
48+ members <- check_user_names(members )
49+
50+ # role for default `PUT` method when adding members
51+ params <- list (role = " member" )
52+
53+ if (method == " DELETE" ) {
54+ team_members <- list_team_members(team = team , org = org )
55+ missing_members <- setdiff(members , team_members )
56+ if (length(missing_members ) == length(members )) {
57+ cli :: cli_abort(
58+ " None of the specified members are part of the {.val {team}} team"
59+ )
60+ }
61+ if (length(missing_members )) {
62+ cli :: cli_warn(
63+ " User{cli::qty(missing_members)}{?s} {.val {missing_members}} {?is/are} not part of the {.val {team}} team"
64+ )
65+ }
66+ # No role when removing members, so pass empty list of params
67+ params <- list ()
68+ }
69+
70+ responses <- list ()
71+
72+ for (i in seq_along(members )) {
73+ responses [[i ]] <- gh(
74+ " /orgs/{org}/teams/{team_slug}/memberships/{username}" ,
75+ org = org ,
76+ team_slug = team ,
77+ username = members [i ],
78+ .method = method ,
79+ .params = params
80+ )
81+ }
82+
83+ responses
84+ }
85+
86+ # ' Remove GitHub organization members
87+ # '
88+ # ' @inheritParams add_team_members
89+ # '
90+ # ' @returns list of responses from the GitHub API
91+ # '
92+ # ' @export
93+ # ' @examples
94+ # ' \dontrun{
95+ # ' remove_org_members(members = "not-ateucher")
96+ # ' }
97+ remove_org_members <- function (members , org = " openscapes" ) {
98+ check_gh_pat()
99+
100+ members <- check_user_names(members )
101+
102+ responses <- list ()
103+
104+ for (i in seq_along(members )) {
105+ responses [[i ]] <- gh(
106+ " DELETE /orgs/{org}/members/{username}" ,
107+ org = org ,
108+ username = members [i ]
109+ )
110+ }
111+
112+ invisible (responses )
113+ }
114+
115+ # ' Check usernames and return valid usernames
116+ # '
117+ # ' @param members character vector or usernames
118+ # '
119+ # ' @returns valid usernames
120+ # ' @noRd
121+ check_user_names <- function (members ) {
16122 if (! identical(members , gsub(" \\ s" , " " , members ))) {
17123 stop(
18124 " GitHub usernames: " ,
@@ -25,6 +131,7 @@ add_team_members <- function(team, members, org = "openscapes") {
25131 map(safely(~ gh(" /users/{username}" , username = .x )))
26132
27133 invalid_usernames <- responses %> % map_lgl(~ is.null(.x $ " result" ))
134+
28135 if (any(invalid_usernames )) {
29136 warning(
30137 " GitHub username(s): " ,
@@ -35,20 +142,8 @@ add_team_members <- function(team, members, org = "openscapes") {
35142
36143 # All usernames are invalid
37144 if (sum(invalid_usernames ) == length(invalid_usernames )) {
38- return ( invisible ( responses ) )
145+ cli :: cli_abort( " All usernames are invalid " )
39146 }
40147
41- members <- members [! invalid_usernames ]
42-
43- responses <- list ()
44- for (i in seq_along(members )) {
45- responses [[i ]] <- gh(
46- " PUT /orgs/{org}/teams/{team_slug}/memberships/{username}" ,
47- org = org ,
48- team_slug = team ,
49- username = members [i ],
50- role = " member"
51- )
52- }
53- invisible (responses )
148+ members [! invalid_usernames ]
54149}
0 commit comments