Merge branch 'master' into bridge-method-annotation

This commit is contained in:
Kohsuke Kawaguchi
2018-01-12 21:13:49 -08:00
committed by GitHub
16 changed files with 238 additions and 57 deletions

20
pom.xml
View File

@@ -7,7 +7,7 @@
</parent>
<artifactId>github-api</artifactId>
<version>1.90-SNAPSHOT</version>
<version>1.91-SNAPSHOT</version>
<name>GitHub API for Java</name>
<url>http://github-api.kohsuke.org/</url>
<description>GitHub API for Java</description>
@@ -64,7 +64,7 @@
<plugin>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-injector</artifactId>
<version>1.14</version>
<version>1.18</version>
<executions>
<execution>
<goals>
@@ -108,7 +108,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -120,7 +120,7 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
@@ -130,7 +130,7 @@
<dependency>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
<version>1.14</version>
<version>1.17</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -142,7 +142,7 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>3.1.0.201310021548-r</version>
<version>4.9.0.201710071750-r</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -154,25 +154,25 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-urlconnection</artifactId>
<version>3.4.0</version>
<version>3.9.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>wordnet-random-name</artifactId>
<version>1.2</version>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.0</version>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@@ -21,8 +21,8 @@ public class GHCreateRepositoryBuilder {
}
public GHCreateRepositoryBuilder description(String description) {
this.builder.with("description",description);
return this;
this.builder.with("description",description);
return this;
}
public GHCreateRepositoryBuilder homepage(URL homepage) {
@@ -74,6 +74,30 @@ public class GHCreateRepositoryBuilder {
return this;
}
/**
* Allow or disallow squash-merging pull requests.
*/
public GHCreateRepositoryBuilder allowSquashMerge(boolean b) {
this.builder.with("allow_squash_merge",b);
return this;
}
/**
* Allow or disallow merging pull requests with a merge commit.
*/
public GHCreateRepositoryBuilder allowMergeCommit(boolean b) {
this.builder.with("allow_merge_commit",b);
return this;
}
/**
* Allow or disallow rebase-merging pull requests.
*/
public GHCreateRepositoryBuilder allowRebaseMerge(boolean b) {
this.builder.with("allow_rebase_merge",b);
return this;
}
/**
* Creates a default .gitignore
*

View File

@@ -3,6 +3,13 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
/**
* Represents a deployment
*
* @see <a href="https://developer.github.com/v3/repos/deployments/">documentation</a>
* @see GHRepository#listDeployments(String, String, String, String)
* @see GHRepository#getDeployment(long)
*/
public class GHDeployment extends GHObject {
private GHRepository owner;
private GitHub root;
@@ -58,4 +65,23 @@ public class GHDeployment extends GHObject {
public URL getHtmlUrl() {
return null;
}
public GHDeploymentStatusBuilder createStatus(GHDeploymentState state) {
return new GHDeploymentStatusBuilder(owner,id,state);
}
public PagedIterable<GHDeploymentStatus> listStatuses() {
return new PagedIterable<GHDeploymentStatus>() {
public PagedIterator<GHDeploymentStatus> _iterator(int pageSize) {
return new PagedIterator<GHDeploymentStatus>(root.retrieve().asIterator(statuses_url, GHDeploymentStatus[].class, pageSize)) {
@Override
protected void wrapUp(GHDeploymentStatus[] page) {
for (GHDeploymentStatus c : page)
c.wrap(owner);
}
};
}
};
}
}

View File

@@ -2,12 +2,26 @@ package org.kohsuke.github;
import java.io.IOException;
/**
* Creates a new deployment status.
*
* @see
* GHDeployment#createStatus(GHDeploymentState)
*/
public class GHDeploymentStatusBuilder {
private final Requester builder;
private GHRepository repo;
private int deploymentId;
private long deploymentId;
/**
* @deprecated
* Use {@link GHDeployment#createStatus(GHDeploymentState)}
*/
public GHDeploymentStatusBuilder(GHRepository repo, int deploymentId, GHDeploymentState state) {
this(repo,(long)deploymentId,state);
}
/*package*/ GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
this.repo = repo;
this.deploymentId = deploymentId;
this.builder = new Requester(repo.root);
@@ -25,6 +39,6 @@ public class GHDeploymentStatusBuilder {
}
public GHDeploymentStatus create() throws IOException {
return builder.to(repo.getApiTailUrl("deployments")+"/"+deploymentId+"/statuses",GHDeploymentStatus.class).wrap(repo);
return builder.to(repo.getApiTailUrl("deployments/"+deploymentId+"/statuses"),GHDeploymentStatus.class).wrap(repo);
}
}

View File

@@ -103,7 +103,7 @@ public class GHGist extends GHObject {
* Used when caller obtains {@link GHGist} without knowing its owner.
* A partially constructed owner object is interned.
*/
/*package*/ GHGist wrapUp(GitHub root) throws IOException {
/*package*/ GHGist wrapUp(GitHub root) {
this.owner = root.getUser(owner);
this.root = root;
wrapUp();
@@ -144,12 +144,8 @@ public class GHGist extends GHObject {
return new PagedIterator<GHGist>(root.retrieve().asIterator(getApiTailUrl("forks"), GHGist[].class, pageSize)) {
@Override
protected void wrapUp(GHGist[] page) {
try {
for (GHGist c : page)
c.wrapUp(root);
} catch (IOException e) {
throw new Error(e);
}
for (GHGist c : page)
c.wrapUp(root);
}
};
}

View File

@@ -203,6 +203,10 @@ public class GHIssue extends GHObject implements Reactable{
edit("body",body);
}
public void setMilestone(GHMilestone milestone) throws IOException {
edit("milestone",milestone.getNumber());
}
public void assignTo(GHUser user) throws IOException {
setAssignees(user);
}

View File

@@ -34,4 +34,12 @@ public class GHLabel {
public void delete() throws IOException {
repo.root.retrieve().method("DELETE").to(url);
}
/**
* @param newColor
* 6-letter hex color code, like "f29513"
*/
public void setColor(String newColor) throws IOException {
repo.root.retrieve().method("PATCH").with("name", name).with("color", newColor).to(url);
}
}

View File

@@ -25,7 +25,7 @@ public abstract class GHObject {
protected Map<String, List<String>> responseHeaderFields;
protected String url;
protected int id;
protected long id;
protected String created_at;
protected String updated_at;
@@ -84,14 +84,18 @@ public abstract class GHObject {
/**
* Unique ID number of this resource.
*/
@WithBridgeMethods(value=String.class, adapterMethod="intToString")
public int getId() {
@WithBridgeMethods(value={String.class,int.class}, adapterMethod="longToStringOrInt")
public long getId() {
return id;
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getId")
private Object intToString(int id, Class type) {
return String.valueOf(id);
private Object longToStringOrInt(long id, Class type) {
if (type==String.class)
return String.valueOf(id);
if (type==int.class)
return (int)id;
throw new AssertionError("Unexpected type: "+type);
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getHtmlUrl")

View File

@@ -41,7 +41,7 @@ public abstract class GHPerson extends GHObject {
if (created_at!=null) {
return; // already populated
}
if (root.isOffline()) {
if (root == null || root.isOffline()) {
return; // cannot populate, will have to live with what we have
}
root.retrieve().to(url, this);

View File

@@ -95,18 +95,12 @@ public class GHRepository extends GHObject {
return new GHDeploymentBuilder(this,ref);
}
public PagedIterable<GHDeploymentStatus> getDeploymentStatuses(final int id) {
return new PagedIterable<GHDeploymentStatus>() {
public PagedIterator<GHDeploymentStatus> _iterator(int pageSize) {
return new PagedIterator<GHDeploymentStatus>(root.retrieve().asIterator(getApiTailUrl("deployments")+"/"+id+"/statuses", GHDeploymentStatus[].class, pageSize)) {
@Override
protected void wrapUp(GHDeploymentStatus[] page) {
for (GHDeploymentStatus c : page)
c.wrap(GHRepository.this);
}
};
}
};
/**
* @deprecated
* Use {@code getDeployment(id).listStatuses()}
*/
public PagedIterable<GHDeploymentStatus> getDeploymentStatuses(final int id) throws IOException {
return getDeployment(id).listStatuses();
}
public PagedIterable<GHDeployment> listDeployments(String sha,String ref,String task,String environment){
@@ -123,7 +117,13 @@ public class GHRepository extends GHObject {
};
}
};
}
/**
* Obtains a single {@link GHDeployment} by its ID.
*/
public GHDeployment getDeployment(long id) throws IOException {
return root.retrieve().to("deployments/" + id, GHDeployment.class).wrap(this);
}
private String join(List<String> params, String joinStr) {
@@ -140,8 +140,12 @@ public class GHRepository extends GHObject {
return StringUtils.trimToNull(value)== null? null: name+"="+value;
}
public GHDeploymentStatusBuilder createDeployStatus(int deploymentId, GHDeploymentState ghDeploymentState) {
return new GHDeploymentStatusBuilder(this,deploymentId,ghDeploymentState);
/**
* @deprecated
* Use {@code getDeployment(deploymentId).createStatus(ghDeploymentState)}
*/
public GHDeploymentStatusBuilder createDeployStatus(int deploymentId, GHDeploymentState ghDeploymentState) throws IOException {
return getDeployment(deploymentId).createStatus(ghDeploymentState);
}
private static class GHRepoPermission {

View File

@@ -18,6 +18,18 @@ public class GHTeam {
protected /*final*/ GHOrganization org;
/** Member's role in a team */
public enum Role {
/**
* A normal member of the team
*/
MEMBER,
/**
* Able to add/remove other team members, promote other team members to team maintainer, and edit the team's name and description.
*/
MAINTAINER
}
/*package*/ GHTeam wrapUp(GHOrganization owner) {
this.org = owner;
return this;
@@ -116,6 +128,22 @@ public class GHTeam {
org.root.retrieve().method("PUT").to(api("/memberships/" + u.getLogin()), null);
}
/**
* Adds a member to the team
*
* The user will be invited to the organization if required.
*
* @param user github user
* @param role role for the new member
*
* @throws IOException
*/
public void add(GHUser user, Role role) throws IOException {
org.root.retrieve().method("PUT")
.with("role", role.name())
.to(api("/memberships/" + user.getLogin()), null);
}
/**
* Removes a member to the team.
*/
@@ -129,7 +157,7 @@ public class GHTeam {
public void add(GHRepository r, GHOrganization.Permission permission) throws IOException {
org.root.retrieve().method("PUT")
.with("permission",permission)
.with("permission", permission)
.to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
}
@@ -145,7 +173,7 @@ public class GHTeam {
}
private String api(String tail) {
return "/teams/"+id+tail;
return "/teams/" + id + tail;
}
public GHOrganization getOrganization() {

View File

@@ -48,7 +48,6 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -166,6 +165,16 @@ public class GitHub {
return GitHubBuilder.fromCredentials().build();
}
/**
* Version that connects to GitHub Enterprise.
*
* @deprecated
* Use {@link #connectToEnterpriseWithOAuth(String, String, String)}
*/
public static GitHub connectToEnterprise(String apiUrl, String oauthAccessToken) throws IOException {
return connectToEnterpriseWithOAuth(apiUrl,null,oauthAccessToken);
}
/**
* Version that connects to GitHub Enterprise.
*
@@ -174,10 +183,16 @@ public class GitHub {
* "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has <tt>/api/v3</tt> in the URL.
* For historical reasons, this parameter still accepts the bare domain name, but that's considered deprecated.
*/
public static GitHub connectToEnterprise(String apiUrl, String oauthAccessToken) throws IOException {
return new GitHubBuilder().withEndpoint(apiUrl).withOAuthToken(oauthAccessToken).build();
public static GitHub connectToEnterpriseWithOAuth(String apiUrl, String login, String oauthAccessToken) throws IOException {
return new GitHubBuilder().withEndpoint(apiUrl).withOAuthToken(oauthAccessToken, login).build();
}
/**
* Version that connects to GitHub Enterprise.
*
* @deprecated
* Use with caution. Login with password is not a preferred method.
*/
public static GitHub connectToEnterprise(String apiUrl, String login, String password) throws IOException {
return new GitHubBuilder().withEndpoint(apiUrl).withPassword(login, password).build();
}
@@ -408,6 +423,9 @@ public class GitHub {
return u;
}
/**
* Gets {@link GHOrganization} specified by name.
*/
public GHOrganization getOrganization(String name) throws IOException {
GHOrganization o = orgs.get(name);
if (o==null) {
@@ -417,6 +435,35 @@ public class GitHub {
return o;
}
/**
* Gets a list of all organizations.
*/
public PagedIterable<GHOrganization> listOrganizations() {
return listOrganizations(null);
}
/**
* Gets a list of all organizations starting after the organization identifier specified by 'since'.
*
* @see <a href="https://developer.github.com/v3/orgs/#parameters">List All Orgs - Parameters</a>
*/
public PagedIterable<GHOrganization> listOrganizations(final String since) {
return new PagedIterable<GHOrganization>() {
@Override
public PagedIterator<GHOrganization> _iterator(int pageSize) {
System.out.println("page size: " + pageSize);
return new PagedIterator<GHOrganization>(retrieve().with("since",since)
.asIterator("/organizations", GHOrganization[].class, pageSize)) {
@Override
protected void wrapUp(GHOrganization[] page) {
for (GHOrganization c : page)
c.wrapUp(GitHub.this);
}
};
}
};
}
/**
* Gets the repository object from 'user/reponame' string that GitHub calls as "repository name"
*
@@ -793,7 +840,7 @@ public class GitHub {
* This provides a dump of every public repository, in the order that they were created.
*
* @param since
* The integer ID of the last Repository that youve seen. See {@link GHRepository#getId()}
* The numeric ID of the last Repository that youve seen. See {@link GHRepository#getId()}
* @see <a href="https://developer.github.com/v3/repos/#list-all-public-repositories">documentation</a>
*/
public PagedIterable<GHRepository> listAllPublicRepositories(final String since) {

View File

@@ -154,6 +154,12 @@ public class GitHubBuilder {
return self;
}
/**
* @param endpoint
* The URL of GitHub (or GitHub enterprise) API endpoint, such as "https://api.github.com" or
* "http://ghe.acme.com/api/v3". Note that GitHub Enterprise has <tt>/api/v3</tt> in the URL.
* For historical reasons, this parameter still accepts the bare domain name, but that's considered deprecated.
*/
public GitHubBuilder withEndpoint(String endpoint) {
this.endpoint = endpoint;
return this;

View File

@@ -54,16 +54,17 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import static java.util.Arrays.*;
import static java.util.logging.Level.*;
import static org.apache.commons.lang.StringUtils.*;
import static org.kohsuke.github.GitHub.*;
import static java.util.Arrays.asList;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.INFO;
import static org.apache.commons.lang.StringUtils.defaultString;
import static org.kohsuke.github.GitHub.MAPPER;
/**
* A builder pattern for making HTTP call and parsing its output.
@@ -452,7 +453,7 @@ class Requester {
try {
return new PagingIterator<T>(type, tailApiUrl, root.getApiURL(s.toString()));
} catch (IOException e) {
throw new Error(e);
throw new GHException("Unable to build github Api URL",e);
}
}
@@ -513,7 +514,7 @@ class Requester {
}
}
} catch (IOException e) {
throw new Error(e);
throw new GHException("Failed to retrieve "+url);
}
}

View File

@@ -134,10 +134,10 @@ public class AppTest extends AbstractGitHubApiTestBase {
.description("question")
.payload("{\"user\":\"atmos\",\"room_id\":123456}")
.create();
GHDeploymentStatus ghDeploymentStatus = repository.createDeployStatus(deployment.getId(), GHDeploymentState.SUCCESS)
GHDeploymentStatus ghDeploymentStatus = deployment.createStatus(GHDeploymentState.SUCCESS)
.description("success")
.targetUrl("http://www.github.com").create();
Iterable<GHDeploymentStatus> deploymentStatuses = repository.getDeploymentStatuses(deployment.getId());
Iterable<GHDeploymentStatus> deploymentStatuses = deployment.listStatuses();
assertNotNull(deploymentStatuses);
assertEquals(1,Iterables.size(deploymentStatuses));
assertEquals(ghDeploymentStatus.getId(), Iterables.get(deploymentStatuses, 0).getId());
@@ -753,6 +753,10 @@ public class AppTest extends AbstractGitHubApiTestBase {
assertEquals(t.getColor(), "123456");
assertEquals(t.getColor(), t2.getColor());
assertEquals(t.getUrl(), t2.getUrl());
t.setColor("000000");
GHLabel t3 = r.getLabel("test");
assertEquals(t3.getColor(), "000000");
t.delete();
}
}
@@ -784,7 +788,7 @@ public class AppTest extends AbstractGitHubApiTestBase {
GHRepository r = itr.next();
System.out.println(r.getFullName());
assertNotNull(r.getUrl());
assertNotEquals(0,r.getId());
assertNotEquals(0L,r.getId());
}
}

View File

@@ -5,11 +5,14 @@ import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Iterables;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -155,4 +158,16 @@ public class GitHubTest {
System.out.println(u.getName());
}
}
@Test
public void getOrgs() throws IOException {
GitHub hub = GitHub.connect();
int iterations = 10;
Set<Long> orgIds = new HashSet<Long>();
for (GHOrganization org : Iterables.limit(hub.listOrganizations().withPageSize(2), iterations)) {
orgIds.add(org.getId());
System.out.println(org.getName());
}
assertThat(orgIds.size(), equalTo(iterations));
}
}