Skip to content

Commit

Permalink
Fixes modifyCollaborators for multiple users
Browse files Browse the repository at this point in the history
Fixes #868
  • Loading branch information
gastaldi committed Jul 25, 2020
1 parent 1d344b0 commit 9ec5bfb
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 14 deletions.
46 changes: 32 additions & 14 deletions src/main/java/org/kohsuke/github/GHRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.WeakHashMap;

import static java.util.Arrays.*;
import static org.kohsuke.github.Previews.*;
import static java.util.Arrays.asList;
import static org.kohsuke.github.Previews.ANTIOPE;
import static org.kohsuke.github.Previews.INERTIA;
import static org.kohsuke.github.Previews.MERCY;
import static org.kohsuke.github.Previews.SHADOW_CAT;

/**
* A repository on GitHub.
Expand All @@ -68,7 +72,9 @@ public class GHRepository extends GHObject {
/* package almost final */ transient GitHub root;

private String nodeId, description, homepage, name, full_name;

private String html_url; // this is the UI

/*
* The license information makes use of the preview API.
*
Expand All @@ -77,22 +83,30 @@ public class GHRepository extends GHObject {
private GHLicense license;

private String git_url, ssh_url, clone_url, svn_url, mirror_url;

private GHUser owner; // not fully populated. beware.

private boolean has_issues, has_wiki, fork, has_downloads, has_pages, archived, has_projects;

private boolean allow_squash_merge;

private boolean allow_merge_commit;

private boolean allow_rebase_merge;

private boolean delete_branch_on_merge;

@JsonProperty("private")
private boolean _private;

private int forks_count, stargazers_count, watchers_count, size, open_issues_count, subscribers_count;

private String pushed_at;

private Map<Integer, GHMilestone> milestones = new WeakHashMap<Integer, GHMilestone>();

private String default_branch, language;

private Map<String, GHCommit> commits = new WeakHashMap<String, GHCommit>();

@SkipFromToString
Expand Down Expand Up @@ -969,13 +983,12 @@ public void removeCollaborators(Collection<GHUser> users) throws IOException {
private void modifyCollaborators(@NonNull Collection<GHUser> users,
@NonNull String method,
@CheckForNull GHOrganization.Permission permission) throws IOException {
Requester requester = root.createRequest().method(method);

if (permission != null) {
requester = requester.with("permission", permission).inBody();
}

for (GHUser user : users) {
// Make sure that the users collection doesn't have any duplicates
for (GHUser user : new LinkedHashSet<GHUser>(users)) {
Requester requester = root.createRequest().method(method);
if (permission != null) {
requester = requester.with("permission", permission).inBody();
}
requester.withUrlPath(getApiTailUrl("collaborators/" + user.getLogin())).send();
}
}
Expand All @@ -1002,8 +1015,9 @@ public void setEmailServiceHook(String address) throws IOException {

private void edit(String key, String value) throws IOException {
Requester requester = root.createRequest();
if (!key.equals("name"))
if (!key.equals("name")) {
requester.with("name", name); // even when we don't change the name, we need to send it in
}
requester.with(key, value).method("PATCH").withUrlPath(getApiTailUrl("")).send();
}

Expand Down Expand Up @@ -1248,8 +1262,9 @@ public GHRepository fork() throws IOException {
// this API is asynchronous. we need to wait for a bit
for (int i = 0; i < 10; i++) {
GHRepository r = root.getMyself().getRepository(name);
if (r != null)
if (r != null) {
return r;
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Expand Down Expand Up @@ -1278,8 +1293,9 @@ public GHRepository forkTo(GHOrganization org) throws IOException {
// this API is asynchronous. we need to wait for a bit
for (int i = 0; i < 10; i++) {
GHRepository r = org.getRepository(name);
if (r != null)
if (r != null) {
return r;
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Expand Down Expand Up @@ -2721,8 +2737,9 @@ public boolean equals(Object obj) {
}

String getApiTailUrl(String tail) {
if (tail.length() > 0 && !tail.startsWith("/"))
if (tail.length() > 0 && !tail.startsWith("/")) {
tail = '/' + tail;
}
return "/repos/" + getOwnerName() + "/" + name + tail;
}

Expand Down Expand Up @@ -2829,8 +2846,9 @@ public GHTagObject createTag(String tag, String message, String object, String t
* The IO exception
*/
void populate() throws IOException {
if (root.isOffline())
if (root.isOffline()) {
return; // can't populate if the root is offline
}

final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");

Expand Down
1 change: 1 addition & 0 deletions src/test/java/org/kohsuke/github/GHRepositoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ public void addCollaborators() throws Exception {
List<GHUser> users = new ArrayList<GHUser>();

users.add(user);
users.add(gitHub.getUser("jimmysombrero2"));
repo.addCollaborators(users, GHOrganization.Permission.PUSH);

GHPersonSet<GHUser> collabs = repo.getCollaborators();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"login": "jimmysombrero2",
"id": 12157727,
"node_id": "MDQ6VXNlcjEyMTU3NzI3",
"avatar_url": "https://avatars3.githubusercontent.com/u/12157727?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jimmysombrero",
"html_url": "https://github.com/jimmysombrero",
"followers_url": "https://api.github.com/users/jimmysombrero/followers",
"following_url": "https://api.github.com/users/jimmysombrero/following{/other_user}",
"gists_url": "https://api.github.com/users/jimmysombrero/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jimmysombrero/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/jimmysombrero/subscriptions",
"organizations_url": "https://api.github.com/users/jimmysombrero/orgs",
"repos_url": "https://api.github.com/users/jimmysombrero/repos",
"events_url": "https://api.github.com/users/jimmysombrero/events{/privacy}",
"received_events_url": "https://api.github.com/users/jimmysombrero/received_events",
"type": "User",
"site_admin": false,
"name": null,
"company": null,
"blog": "",
"location": null,
"email": null,
"hireable": null,
"bio": null,
"public_repos": 4,
"public_gists": 0,
"followers": 1,
"following": 0,
"created_at": "2015-04-28T17:47:19Z",
"updated_at": "2020-02-02T04:43:58Z",
"private_gists": 0,
"total_private_repos": 0,
"owned_private_repos": 0,
"disk_usage": 19,
"collaborators": 0,
"two_factor_authentication": false,
"plan": {
"name": "free",
"space": 976562499,
"collaborators": 0,
"private_repos": 10000
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"id": "3d80b19e-05f4-4ad9-a610-5f573abc4363",
"name": "repos_hub4j-test-org_github-api_collaborators_jimmysombrero2",
"request": {
"url": "/repos/hub4j-test-org/github-api/collaborators/jimmysombrero2",
"method": "PUT",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
},
"bodyPatterns": [
{
"equalToJson": "{\"permission\":\"push\"}",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}
]
},
"response": {
"status": 201,
"body": "[]",
"headers": {
"Server": "GitHub.com",
"Date": "Sun, 02 Feb 2020 04:59:39 GMT",
"Content-Type": "application/json; charset=utf-8",
"Status": "201 Created",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4892",
"X-RateLimit-Reset": "1580620983",
"X-OAuth-Scopes": "admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete:packages, delete_repo, gist, notifications, read:packages, repo, user, workflow, write:discussion, write:packages",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "C903:768E:16C4966:2BA11B0:5E36573B"
}
},
"uuid": "3d80b19e-05f4-4ad9-a610-5f573abc4363",
"persistent": true,
"insertionIndex": 4
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"id": "6685376c-451b-486d-88cd-502af9a7c5d2",
"name": "users_jimmysombrero2",
"request": {
"url": "/users/jimmysombrero2",
"method": "GET",
"headers": {
"Accept": {
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
}
}
},
"response": {
"status": 200,
"bodyFileName": "users_jimmysombrero2.json",
"headers": {
"Server": "GitHub.com",
"Date": "Mon, 03 Feb 2020 03:50:14 GMT",
"Content-Type": "application/json; charset=utf-8",
"Status": "200 OK",
"X-RateLimit-Limit": "5000",
"X-RateLimit-Remaining": "4907",
"X-RateLimit-Reset": "1580704799",
"Cache-Control": "private, max-age=60, s-maxage=60",
"Vary": "Accept, Authorization, Cookie, X-GitHub-OTP",
"ETag": "W/\"7a0206b47e995649c88218afeb2266a6\"",
"Last-Modified": "Sun, 02 Feb 2020 04:43:58 GMT",
"X-OAuth-Scopes": "admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete:packages, delete_repo, gist, notifications, read:packages, repo, user, workflow, write:discussion, write:packages",
"X-Accepted-OAuth-Scopes": "",
"X-GitHub-Media-Type": "unknown, github.v3",
"Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type",
"Access-Control-Allow-Origin": "*",
"Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload",
"X-Frame-Options": "deny",
"X-Content-Type-Options": "nosniff",
"X-XSS-Protection": "1; mode=block",
"Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"Content-Security-Policy": "default-src 'none'",
"X-GitHub-Request-Id": "CDFE:768D:1021273:26DC788:5E379876"
}
},
"uuid": "6685376c-451b-486d-88cd-502af9a7c5d1",
"persistent": true,
"insertionIndex": 6
}

0 comments on commit 9ec5bfb

Please sign in to comment.