From 8f24f55eb750df48f2588aec0a6164771d0e417c Mon Sep 17 00:00:00 2001 From: vr100 Date: Wed, 19 Mar 2014 11:06:11 +0530 Subject: [PATCH 01/19] Added apis to list commits by author and list the repos of an organization (including the private ones) --- .../org/kohsuke/github/GHOrganization.java | 21 ++++++++++ .../java/org/kohsuke/github/GHRepository.java | 38 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index ec899c0538..657ab93efd 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -173,4 +173,25 @@ protected void wrapUp(GHEventInfo[] page) { } }; } + + /** + * Lists up all the repositories of an organization using the specified page size. (this + * includes private organizations if the caller is authenticated accordingly) + * + * @param pageSize size for each page of items returned by GitHub. Maximum page size is 100. + * + */ + public PagedIterable listRepositories(final int pageSize) { + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(root.retrieve().asIterator("/orgs/" + login + "/repos?per_page=" + pageSize, GHRepository[].class)) { + @Override + protected void wrapUp(GHRepository[] page) { + for (GHRepository c : page) + c.wrap(root); + } + }; + } + }; + } } diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index c1146f8e4b..685ef07fc3 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -487,6 +487,44 @@ protected void wrapUp(GHCommit[] page) { } }; } + + /** + * Lists all the commit by author + */ + public PagedIterable listCommitsByAuthor(final String author) { + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author), GHCommit[].class)) { + protected void wrapUp(GHCommit[] page) { + for (GHCommit c : page) + c.wrapUp(GHRepository.this); + } + }; + } + }; + } + + /** + * Lists all the commit by author for the given branch from the startCommitSha (startCommitSha is optional) + */ + public PagedIterable listCommitsByAuthorAndBranch(final String author, final String branch, final String startCommitSha) { + String url =String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author); + url = url + String.format("&sha=%s", branch); + if (startCommitSha != null && !startCommitSha.isEmpty()) { + url = url + String.format("&sha=%s", startCommitSha); + } + final String finalUrl = url; + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(root.retrieve().asIterator(finalUrl, GHCommit[].class)) { + protected void wrapUp(GHCommit[] page) { + for (GHCommit c : page) + c.wrapUp(GHRepository.this); + } + }; + } + }; + } /** * Lists up all the commit comments in this repository. From 0b74692d62e80d36ce58aaaec10cfa890e6fdf43 Mon Sep 17 00:00:00 2001 From: vr100 Date: Wed, 19 Mar 2014 11:38:03 +0530 Subject: [PATCH 02/19] change in comment --- src/main/java/org/kohsuke/github/GHOrganization.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 657ab93efd..08b4f4c007 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -176,7 +176,7 @@ protected void wrapUp(GHEventInfo[] page) { /** * Lists up all the repositories of an organization using the specified page size. (this - * includes private organizations if the caller is authenticated accordingly) + * includes private repos if the caller is authenticated accordingly) * * @param pageSize size for each page of items returned by GitHub. Maximum page size is 100. * From 15c5c9615e594cdd23aa39e83039a3616bb9bd61 Mon Sep 17 00:00:00 2001 From: vr100 Date: Thu, 20 Mar 2014 15:00:34 +0530 Subject: [PATCH 03/19] Added pagesize parameter to 'Get commits by author and branch' api --- .../java/org/kohsuke/github/GHRepository.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 685ef07fc3..46d79e6c99 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -525,6 +525,30 @@ protected void wrapUp(GHCommit[] page) { } }; } + + /** + * Lists all the commit by author for the given branch from the startCommitSha (startCommitSha is optional) + */ + public PagedIterable listCommitsByAuthorAndBranch(final String author, final String branch, + final String startCommitSha, int pageSize) { + String url =String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author); + url = url + String.format("&sha=%s", branch); + if (startCommitSha != null && !startCommitSha.isEmpty()) { + url = url + String.format("&sha=%s", startCommitSha); + } + url = url + String.format("&per_page=%s", pageSize); + final String finalUrl = url; + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(root.retrieve().asIterator(finalUrl, GHCommit[].class)) { + protected void wrapUp(GHCommit[] page) { + for (GHCommit c : page) + c.wrapUp(GHRepository.this); + } + }; + } + }; + } /** * Lists up all the commit comments in this repository. From 9c02f918c1a09baa730c5b4ea59c1bf035de7dc2 Mon Sep 17 00:00:00 2001 From: vr100 Date: Wed, 26 Mar 2014 09:23:26 +0530 Subject: [PATCH 04/19] In order to handle http based github enterprise vm url, changing https to http --- src/main/java/org/kohsuke/github/Requester.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index fa9bc3191c..dd825e0b12 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -23,9 +23,8 @@ */ package org.kohsuke.github; -import org.apache.commons.io.IOUtils; +import static org.kohsuke.github.GitHub.MAPPER; -import javax.net.ssl.HttpsURLConnection; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -48,7 +47,7 @@ import java.util.Set; import java.util.zip.GZIPInputStream; -import static org.kohsuke.github.GitHub.MAPPER; +import org.apache.commons.io.IOUtils; /** * A builder pattern for making HTTP call and parsing its output. @@ -294,7 +293,7 @@ private void findNextURL(HttpURLConnection uc) throws MalformedURLException { private HttpURLConnection setupConnection(URL url) throws IOException { - HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(); + HttpURLConnection uc = (HttpURLConnection) url.openConnection(); // if the authentication is needed but no credential is given, try it anyway (so that some calls // that do work with anonymous access in the reduced form should still work.) From cc53e0c8ff7d8f6248f4f7c08d363600726e60f8 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 13 Apr 2014 08:58:53 -0700 Subject: [PATCH 05/19] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c61b59b225..e1a496880f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.51 + 1.52-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.51 + HEAD From 8818bf8cf0ab62cc6e15339009c00c5ce5c7ec13 Mon Sep 17 00:00:00 2001 From: Anton Krasov Date: Fri, 18 Apr 2014 17:28:51 +0300 Subject: [PATCH 06/19] add tarball_url and zipball_url to GHRelease --- .../java/org/kohsuke/github/GHRelease.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHRelease.java b/src/main/java/org/kohsuke/github/GHRelease.java index b862477ea7..0c405b33e2 100644 --- a/src/main/java/org/kohsuke/github/GHRelease.java +++ b/src/main/java/org/kohsuke/github/GHRelease.java @@ -32,6 +32,8 @@ public class GHRelease { private boolean prerelease; private Date created_at; private Date published_at; + private String tarball_url; + private String zipball_url; public String getAssetsUrl() { return assets_url; @@ -153,6 +155,22 @@ public void setUrl(String url) { this.url = url; } + public String getZipballUrl() { + return zipball_url; + } + + public void setZipballUrl(String zipballUrl) { + this.zipball_url = zipballUrl; + } + + public String getTarballUrl() { + return tarball_url; + } + + public void setTarballUrl(String tarballUrl) { + this.tarball_url = tarballUrl; + } + GHRelease wrap(GHRepository owner) { this.owner = owner; this.root = owner.root; From d2ac81d7ba4e6ed4424d89c21458b468f4eb46fd Mon Sep 17 00:00:00 2001 From: vr100 Date: Wed, 23 Apr 2014 09:45:11 +0530 Subject: [PATCH 07/19] Using builder pattern to list commits in a repo --- .../java/org/kohsuke/github/GHRepository.java | 92 ++++++++++--------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 46d79e6c99..495bafc4af 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -37,6 +37,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -488,55 +489,60 @@ protected void wrapUp(GHCommit[] page) { }; } - /** - * Lists all the commit by author - */ - public PagedIterable listCommitsByAuthor(final String author) { - return new PagedIterable() { - public PagedIterator iterator() { - return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author), GHCommit[].class)) { - protected void wrapUp(GHCommit[] page) { - for (GHCommit c : page) - c.wrapUp(GHRepository.this); - } - }; - } - }; - } - - /** - * Lists all the commit by author for the given branch from the startCommitSha (startCommitSha is optional) - */ - public PagedIterable listCommitsByAuthorAndBranch(final String author, final String branch, final String startCommitSha) { - String url =String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author); - url = url + String.format("&sha=%s", branch); - if (startCommitSha != null && !startCommitSha.isEmpty()) { - url = url + String.format("&sha=%s", startCommitSha); + public static class GHCommitBuilder { + String author; + String branch; + String startCommitSha; + Integer pageSize; + + public void setAuthor(String author) { + this.author = author; + } + + public void setBranch(String branch) { + this.branch = branch; + } + + public void setStartCommitSha(String startCommitSha) { + this.startCommitSha = startCommitSha; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; } - final String finalUrl = url; - return new PagedIterable() { - public PagedIterator iterator() { - return new PagedIterator(root.retrieve().asIterator(finalUrl, GHCommit[].class)) { - protected void wrapUp(GHCommit[] page) { - for (GHCommit c : page) - c.wrapUp(GHRepository.this); - } - }; - } - }; } /** - * Lists all the commit by author for the given branch from the startCommitSha (startCommitSha is optional) + * Lists all the commit by different builder options */ - public PagedIterable listCommitsByAuthorAndBranch(final String author, final String branch, - final String startCommitSha, int pageSize) { - String url =String.format("/repos/%s/%s/commits?author=%s", owner.login, name, author); - url = url + String.format("&sha=%s", branch); - if (startCommitSha != null && !startCommitSha.isEmpty()) { - url = url + String.format("&sha=%s", startCommitSha); + public PagedIterable listCommits(GHCommitBuilder builder) { + String url = String.format("/repos/%s/%s/commits", owner.login, name); + + List params = new LinkedList(); + if (builder.author != null) { + params.add(String.format("author=%s", builder.author)); + } + if (builder.branch != null) { + params.add(String.format("sha=%s", builder.branch)); + } + if (builder.startCommitSha != null) { + params.add(String.format("sha=%s", builder.startCommitSha)); + } + if (builder.pageSize != null && builder.pageSize > 0) { + params.add(String.format("per_page=%d",builder.pageSize)); + } + + if (params.size() > 0) { + url = url + "?"; + } + for(String p: params) { + url = url + p + "&"; + } + if (params.size() > 0) { + // trimming off the last extra ampersand + url = url.substring(0, url.length() - 1); } - url = url + String.format("&per_page=%s", pageSize); + final String finalUrl = url; return new PagedIterable() { public PagedIterator iterator() { From 3f921b69f661e10c202118b3c5a50fdbcac0d2dd Mon Sep 17 00:00:00 2001 From: Kelly Campbell Date: Fri, 25 Apr 2014 22:23:13 -0400 Subject: [PATCH 08/19] Fix bug in GHMyself.getEmails due to API change --- src/main/java/org/kohsuke/github/GHEmail.java | 69 +++++++++++++++++++ .../java/org/kohsuke/github/GHMyself.java | 4 +- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHEmail.java diff --git a/src/main/java/org/kohsuke/github/GHEmail.java b/src/main/java/org/kohsuke/github/GHEmail.java new file mode 100644 index 0000000000..5f230c5945 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHEmail.java @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + + +/** + * Represents an email of GitHub. + * + * @author Kelly Campbell + */ +public class GHEmail { + + protected String email; + protected boolean primary; + protected boolean verified; + + public String getEmail() { + return email; + } + + public boolean isPrimary() { + return primary; + } + + public boolean isVerified() { + return verified; + } + + + @Override + public String toString() { + return "Email:"+email; + } + + @Override + public int hashCode() { + return email.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof GHEmail) { + GHEmail that = (GHEmail) obj; + return this.email.equals(that.email); + } + return false; + } +} diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java index c770f0449e..1f20686c21 100644 --- a/src/main/java/org/kohsuke/github/GHMyself.java +++ b/src/main/java/org/kohsuke/github/GHMyself.java @@ -26,8 +26,8 @@ public class GHMyself extends GHUser { * @return * Always non-null. */ - public List getEmails() throws IOException { - String[] addresses = root.retrieve().to("/user/emails", String[].class); + public List getEmails() throws IOException { + GHEmail[] addresses = root.retrieve().to("/user/emails", GHEmail[].class); return Collections.unmodifiableList(Arrays.asList(addresses)); } From 60fe143b0749815e8aae80bd8d61d563a1ec30c2 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 30 Apr 2014 13:27:37 -0700 Subject: [PATCH 09/19] detect the common problem If the caller tries to parse a pull event into a pull_request event, we'd choke with NPE. This change avoids that. --- src/main/java/org/kohsuke/github/GHEventPayload.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index e805ef7eb4..704d7f8e81 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -51,6 +51,8 @@ public GHRepository getRepository() { @Override void wrapUp(GitHub root) { super.wrapUp(root); + if (pull_request==null) + throw new IllegalStateException("Expected pull_request payload, but got something else. Maybe we've got another type of event?"); if (repository!=null) { repository.wrap(root); pull_request.wrap(repository); From 51309efd460cad15c8ee2ec2f61065c92c0a5bbc Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:43:27 -0700 Subject: [PATCH 10/19] Graceful error handling --- src/main/java/org/kohsuke/github/GHOrganization.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 8501ba3763..8286088690 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -23,10 +23,15 @@ public class GHOrganization extends GHPerson { * Newly created repository. */ public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException { - return createRepository(name,description,homepage,getTeams().get(team),isPublic); + GHTeam t = getTeams().get(team); + if (t==null) + throw new IllegalArgumentException("No such team: "+team); + return createRepository(name,description,homepage,t,isPublic); } public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException { + if (team==null) + throw new IllegalArgumentException("Invalid team"); // such API doesn't exist, so fall back to HTML scraping return new Requester(root) .with("name", name).with("description", description).with("homepage", homepage) From 145bdacf13757ee8abdd57452014369a38b62183 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:50:19 -0700 Subject: [PATCH 11/19] Added a method to list up teams --- .../java/org/kohsuke/github/GHOrganization.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 8286088690..ff0e7f9595 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -50,6 +50,23 @@ public Map getTeams() throws IOException { return r; } + /** + * List up all the teams. + */ + public PagedIterable listTeams() throws IOException { + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(root.retrieve().asIterator(String.format("/orgs/%s/teams", login), GHTeam[].class)) { + @Override + protected void wrapUp(GHTeam[] page) { + for (GHTeam c : page) + c.wrapUp(GHOrganization.this); + } + }; + } + }; + } + /** * Checks if this organization has the specified user as a member. */ From aaf10aa118cc131a867536a1e4eb1265166c4e49 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:53:08 -0700 Subject: [PATCH 12/19] added a test --- src/test/java/Foo.java | 13 ++++++++++++- src/test/java/org/kohsuke/AppTest.java | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/test/java/Foo.java b/src/test/java/Foo.java index f5a88a34ae..e81431b112 100644 --- a/src/test/java/Foo.java +++ b/src/test/java/Foo.java @@ -1,12 +1,23 @@ +import org.kohsuke.github.GHOrganization; +import org.kohsuke.github.GHTeam; import org.kohsuke.github.GitHub; import java.util.Arrays; +import java.util.Map; /** * @author Kohsuke Kawaguchi */ public class Foo { public static void main(String[] args) throws Exception { - System.out.println(GitHub.connect().getOrganization("cloudbees").getRepository("grandcentral").isPrivate()); + GHOrganization org = GitHub.connect().getOrganization("jenkinsci"); + Map teams = org.getTeams(); + System.out.println(teams.size()); + + int sz = 0; + for (GHTeam t : org.listTeams()) { + sz++; + } + System.out.println(sz); } } diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index 2847c0f8ec..c22558fdce 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -259,6 +259,16 @@ public void testMemberOrgs() throws Exception { System.out.println(o); } + @Test + public void testOrgTeams() throws Exception { + int sz=0; + for (GHTeam t : gitHub.getOrganization("jenkinsci").listTeams()) { + assertNotNull(t.getName()); + sz++; + } + assertTrue(sz>1000); + } + @Test public void testCommit() throws Exception { GHCommit commit = gitHub.getUser("jenkinsci").getRepository("jenkins").getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7"); From 6da169cd56bf406e26beb0ed9a318d84f31f05e4 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:54:24 -0700 Subject: [PATCH 13/19] a convenience method --- .../java/org/kohsuke/github/GHOrganization.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index ff0e7f9595..0680ca39ca 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -42,10 +42,9 @@ public GHRepository createRepository(String name, String description, String hom * Teams by their names. */ public Map getTeams() throws IOException { - GHTeam[] teams = root.retrieve().to("/orgs/" + login + "/teams", GHTeam[].class); Map r = new TreeMap(); - for (GHTeam t : teams) { - r.put(t.getName(),t.wrapUp(this)); + for (GHTeam t : listTeams()) { + r.put(t.getName(),t); } return r; } @@ -67,6 +66,17 @@ protected void wrapUp(GHTeam[] page) { }; } + /** + * Finds a team that has the given name in its {@link GHTeam#getName()} + */ + public GHTeam getTeamByName(String name) throws IOException { + for (GHTeam t : listTeams()) { + if(t.getName().equals(name)) + return t; + } + return null; + } + /** * Checks if this organization has the specified user as a member. */ From 926e0ea0e5f7f1c45b0ddb6cb7c5b22e1df0d42c Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:55:53 -0700 Subject: [PATCH 14/19] added more tests. Looks like org APIs only work for owners of the org --- src/test/java/org/kohsuke/AppTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index c22558fdce..8f81d1df9d 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -261,6 +261,7 @@ public void testMemberOrgs() throws Exception { @Test public void testOrgTeams() throws Exception { + kohsuke(); int sz=0; for (GHTeam t : gitHub.getOrganization("jenkinsci").listTeams()) { assertNotNull(t.getName()); @@ -269,6 +270,12 @@ public void testOrgTeams() throws Exception { assertTrue(sz>1000); } + public void testOrgTeamByName() throws Exception { + kohsuke(); + GHTeam e = gitHub.getOrganization("jenkinsci").getTeamByName("Everyone"); + assertNotNull(e); + } + @Test public void testCommit() throws Exception { GHCommit commit = gitHub.getUser("jenkinsci").getRepository("jenkins").getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7"); From 80672c43c06a30f0d23c1c94879d0b7948b22e65 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 17:59:22 -0700 Subject: [PATCH 15/19] Restored backward compatibility --- src/main/java/org/kohsuke/github/GHMyself.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java index 1f20686c21..85c75c0971 100644 --- a/src/main/java/org/kohsuke/github/GHMyself.java +++ b/src/main/java/org/kohsuke/github/GHMyself.java @@ -1,6 +1,7 @@ package org.kohsuke.github; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -16,17 +17,30 @@ * @author Kohsuke Kawaguchi */ public class GHMyself extends GHUser { + /** + * @deprecated + * Use {@link #getEmails2()} + */ + public List getEmails() throws IOException { + List src = getEmails2(); + List r = new ArrayList(src.size()); + for (GHEmail e : src) { + r.add(e.getEmail()); + } + return r; + } + /** * Returns the read-only list of e-mail addresses configured for you. * * This corresponds to the stuff you configure in https://github.com/settings/emails, * and not to be confused with {@link #getEmail()} that shows your public e-mail address * set in https://github.com/settings/profile - * + * * @return * Always non-null. */ - public List getEmails() throws IOException { + public List getEmails2() throws IOException { GHEmail[] addresses = root.retrieve().to("/user/emails", GHEmail[].class); return Collections.unmodifiableList(Arrays.asList(addresses)); } From 926776204b9dc18eedac34a749932c4b8f0510a9 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 18:28:34 -0700 Subject: [PATCH 16/19] Implemented the builder pattern to my liking --- .../kohsuke/github/GHCommitQueryBuilder.java | 105 ++++++++++++++++++ .../java/org/kohsuke/github/GHRepository.java | 70 +----------- src/main/java/org/kohsuke/github/GitHub.java | 4 + .../java/org/kohsuke/github/Requester.java | 20 +++- src/test/java/org/kohsuke/AppTest.java | 20 +++- 5 files changed, 148 insertions(+), 71 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java diff --git a/src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java b/src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java new file mode 100644 index 0000000000..6d0a7ae995 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java @@ -0,0 +1,105 @@ +package org.kohsuke.github; + +import java.util.Date; + +/** + * Builds up query for listing commits. + * + *

+ * Call various methods that set the filter criteria, then {@link #list()} method to actually list up the commit. + * + *

+ * GHRepository r = ...;
+ * for (GHCommit c : r.queryCommits().since(x).until(y).author("kohsuke")) {
+ *     ...
+ * }
+ * 
+ * + * @author Kohsuke Kawaguchi + * @see GHRepository#queryCommits() +*/ +public class GHCommitQueryBuilder { + private final Requester req; + private final GHRepository repo; + + /*package*/ GHCommitQueryBuilder(GHRepository repo) { + this.repo = repo; + this.req = repo.root.retrieve(); // requester to build up + } + + /** + * GItHub login or email address by which to filter by commit author. + */ + public GHCommitQueryBuilder author(String author) { + req.with("author",author); + return this; + } + + /** + * Only commits containing this file path will be returned. + */ + public GHCommitQueryBuilder path(String path) { + req.with("path",path); + return this; + } + + /** + * Specifies the SHA1 commit / tag / branch / etc to start listing commits from. + * + */ + public GHCommitQueryBuilder from(String ref) { + req.with("sha",ref); + return this; + } + + public GHCommitQueryBuilder pageSize(int pageSize) { + req.with("per_page",pageSize); + return this; + } + + /** + * Only commits after this date will be returned + */ + public GHCommitQueryBuilder since(Date dt) { + req.with("since",GitHub.printDate(dt)); + return this; + } + + /** + * Only commits after this date will be returned + */ + public GHCommitQueryBuilder since(long timestamp) { + return since(new Date(timestamp)); + } + + /** + * Only commits before this date will be returned + */ + public GHCommitQueryBuilder until(Date dt) { + req.with("until",GitHub.printDate(dt)); + return this; + } + + /** + * Only commits before this date will be returned + */ + public GHCommitQueryBuilder until(long timestamp) { + return until(new Date(timestamp)); + } + + /** + * Lists up the commits with the criteria built so far. + */ + public PagedIterable list() { + return new PagedIterable() { + public PagedIterator iterator() { + return new PagedIterator(req.asIterator(repo.getApiTailUrl("commits"), GHCommit[].class)) { + protected void wrapUp(GHCommit[] page) { + for (GHCommit c : page) + c.wrapUp(repo); + } + }; + } + }; + } +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 495bafc4af..fd50c63f7b 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -435,7 +435,7 @@ public GHCompare getCompare(String id1, String id2) throws IOException { } public GHCompare getCompare(GHCommit id1, GHCommit id2) throws IOException { - return getCompare(id1.getSHA1(),id2.getSHA1()); + return getCompare(id1.getSHA1(), id2.getSHA1()); } public GHCompare getCompare(GHBranch id1, GHBranch id2) throws IOException { @@ -488,72 +488,12 @@ protected void wrapUp(GHCommit[] page) { } }; } - - public static class GHCommitBuilder { - String author; - String branch; - String startCommitSha; - Integer pageSize; - - public void setAuthor(String author) { - this.author = author; - } - - public void setBranch(String branch) { - this.branch = branch; - } - - public void setStartCommitSha(String startCommitSha) { - this.startCommitSha = startCommitSha; - } - - public void setPageSize(int pageSize) { - this.pageSize = pageSize; - } - } - + /** - * Lists all the commit by different builder options + * Search commits by specifying filters through a builder pattern. */ - public PagedIterable listCommits(GHCommitBuilder builder) { - String url = String.format("/repos/%s/%s/commits", owner.login, name); - - List params = new LinkedList(); - if (builder.author != null) { - params.add(String.format("author=%s", builder.author)); - } - if (builder.branch != null) { - params.add(String.format("sha=%s", builder.branch)); - } - if (builder.startCommitSha != null) { - params.add(String.format("sha=%s", builder.startCommitSha)); - } - if (builder.pageSize != null && builder.pageSize > 0) { - params.add(String.format("per_page=%d",builder.pageSize)); - } - - if (params.size() > 0) { - url = url + "?"; - } - for(String p: params) { - url = url + p + "&"; - } - if (params.size() > 0) { - // trimming off the last extra ampersand - url = url.substring(0, url.length() - 1); - } - - final String finalUrl = url; - return new PagedIterable() { - public PagedIterator iterator() { - return new PagedIterator(root.retrieve().asIterator(finalUrl, GHCommit[].class)) { - protected void wrapUp(GHCommit[] page) { - for (GHCommit c : page) - c.wrapUp(GHRepository.this); - } - }; - } - }; + public GHCommitQueryBuilder queryCommits() { + return new GHCommitQueryBuilder(this); } /** diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index c96c5de43d..2048f64ce9 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -392,6 +392,10 @@ public boolean isCredentialValid() throws IOException { throw new IllegalStateException("Unable to parse the timestamp: "+timestamp); } + /*package*/ static String printDate(Date dt) { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(dt); + } + /*package*/ static final ObjectMapper MAPPER = new ObjectMapper(); private static final String[] TIME_FORMATS = {"yyyy/MM/dd HH:mm:ss ZZZZ","yyyy-MM-dd'T'HH:mm:ss'Z'"}; diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index dd825e0b12..37370630ca 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -31,11 +31,13 @@ import java.io.InputStreamReader; import java.io.InterruptedIOException; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -208,9 +210,23 @@ private T _to(String tailApiUrl, Class type, T instance) throws IOExcepti * * Every iterator call reports a new batch. */ - /*package*/ Iterator asIterator(final String tailApiUrl, final Class type) { + /*package*/ Iterator asIterator(String _tailApiUrl, final Class type) { method("GET"); - if (!args.isEmpty()) throw new IllegalStateException(); + + if (!args.isEmpty()) { + boolean first=true; + try { + for (Entry a : args) { + _tailApiUrl += first ? '?' : '&'; + first = false; + _tailApiUrl += URLEncoder.encode(a.key,"UTF-8")+'='+URLEncoder.encode(a.value.toString(),"UTF-8"); + } + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); // UTF-8 is mandatory + } + } + + final String tailApiUrl = _tailApiUrl; return new Iterator() { /** diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index 0b8177657c..b8bee72d76 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Date; import java.util.Map; import java.util.Set; import java.util.List; @@ -152,7 +153,7 @@ public void testMembership() throws Exception { Set members = gitHub.getOrganization("jenkinsci").getRepository("violations-plugin").getCollaboratorNames(); System.out.println(members.contains("kohsuke")); } - + public void testMemberOrgs() throws Exception { Set o = gitHub.getUser("kohsuke").getOrganizations(); System.out.println(o); @@ -176,8 +177,19 @@ public void testListCommits() throws Exception { System.out.println(c.getSHA1()); sha1.add(c.getSHA1()); } - assertEquals("fdfad6be4db6f96faea1f153fb447b479a7a9cb7",sha1.get(0)); - assertEquals(1,sha1.size()); + assertEquals("fdfad6be4db6f96faea1f153fb447b479a7a9cb7", sha1.get(0)); + assertEquals(1, sha1.size()); + } + + public void testQueryCommits() throws Exception { + List sha1 = new ArrayList(); + for (GHCommit c : gitHub.getUser("jenkinsci").getRepository("jenkins").queryCommits() + .since(new Date(1199174400000L)).until(1201852800000L).path("pom.xml").list()) { + System.out.println(c.getSHA1()); + sha1.add(c.getSHA1()); + } + assertEquals("1cccddb22e305397151b2b7b87b4b47d74ca337b",sha1.get(0)); + assertEquals(29,sha1.size()); } public void testBranches() throws Exception { @@ -339,7 +351,7 @@ public void testCommitStatus() throws Exception { state = lst.get(0); System.out.println(state); assertEquals("oops!",state.getDescription()); - assertEquals("http://jenkins-ci.org/",state.getTargetUrl()); + assertEquals("http://jenkins-ci.org/", state.getTargetUrl()); } public void testCommitShortInfo() throws Exception { From 2e1d4381b09e3f63ba582119444a24f9ee3609a5 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 18:34:51 -0700 Subject: [PATCH 17/19] looks like this property was renamed --- src/main/java/org/kohsuke/github/GHRepository.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 7fd44e9917..bbae316583 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -39,7 +39,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -68,7 +67,7 @@ public class GHRepository { private String created_at, pushed_at; private Map milestones = new HashMap(); - private String master_branch,language; + private String default_branch,language; private Map commits = new HashMap(); private GHRepoPermission permissions; @@ -154,8 +153,9 @@ public List getIssues(GHIssueState state) throws IOException { public List getIssues(GHIssueState state, GHMilestone milestone) throws IOException { return Arrays.asList(GHIssue.wrap(root.retrieve() .to(String.format("/repos/%s/%s/issues?state=%s&milestone=%s", owner.login, name, - state.toString().toLowerCase(), milestone == null ? "none" : "" + milestone.getNumber()), - GHIssue[].class), this)); + state.toString().toLowerCase(), milestone == null ? "none" : "" + milestone.getNumber()), + GHIssue[].class + ), this)); } /** @@ -240,7 +240,7 @@ public Date getCreatedAt() { * This field is null until the user explicitly configures the master branch. */ public String getMasterBranch() { - return master_branch; + return default_branch; } public int getSize() { From 1e0129f2d8302552f6c18e7a90554e270709b671 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 18:36:46 -0700 Subject: [PATCH 18/19] A few more properties while we are at it --- src/main/java/org/kohsuke/github/GHRepository.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index bbae316583..7b12f08959 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -63,7 +63,7 @@ public class GHRepository { private boolean has_issues, has_wiki, fork, has_downloads; @JsonProperty("private") private boolean _private; - private int watchers,forks,open_issues,size; + private int watchers,forks,open_issues,size,network_count,subscribers_count; private String created_at, pushed_at; private Map milestones = new HashMap(); @@ -220,6 +220,14 @@ public int getOpenIssueCount() { return open_issues; } + public int getNetworkCount() { + return network_count; + } + + public int getSubscribersCount() { + return subscribers_count; + } + /** * * @return From a37ade13cdbf1db2de14a53ca8733d8dc85314b3 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 9 May 2014 18:39:29 -0700 Subject: [PATCH 19/19] [maven-release-plugin] prepare release github-api-1.52 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e1a496880f..a3b27867e0 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.52-SNAPSHOT + 1.52 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java