mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-11 08:21:23 +00:00
Compare commits
206 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d1ef296b3 | ||
|
|
16dbcde90b | ||
|
|
50cbf25c72 | ||
|
|
7b87de2b4c | ||
|
|
1ce54a7925 | ||
|
|
1bfe7dd99b | ||
|
|
27e855ddbd | ||
|
|
3d1bed0f8f | ||
|
|
5c9ea9b63a | ||
|
|
7c034f5670 | ||
|
|
3b9f5a417a | ||
|
|
cde501af8d | ||
|
|
3c5592c1c8 | ||
|
|
2508e022bb | ||
|
|
01fcbc24e8 | ||
|
|
204e639679 | ||
|
|
3d301ec730 | ||
|
|
9ab6d57019 | ||
|
|
37c473130f | ||
|
|
5f95987a48 | ||
|
|
d530b34073 | ||
|
|
35dec7a5ec | ||
|
|
baedad8124 | ||
|
|
007378c3a6 | ||
|
|
beae9fd6ec | ||
|
|
b7507076c6 | ||
|
|
6b5ade3ca0 | ||
|
|
715192d26c | ||
|
|
ce140460af | ||
|
|
d30b0403ce | ||
|
|
255c993548 | ||
|
|
557ae4165c | ||
|
|
a31395ed80 | ||
|
|
397886d289 | ||
|
|
7307bec2ae | ||
|
|
0cd5147e1a | ||
|
|
36d5b092d7 | ||
|
|
f9014dbab3 | ||
|
|
755d5f77ea | ||
|
|
906d9af7b7 | ||
|
|
14dcb37ee1 | ||
|
|
c1c2a27358 | ||
|
|
5ab9657f9c | ||
|
|
7a78f9f5aa | ||
|
|
ac8c65f062 | ||
|
|
1954a9f3f8 | ||
|
|
3b764f9c90 | ||
|
|
10f55cc549 | ||
|
|
cd8d955646 | ||
|
|
bba07c9080 | ||
|
|
dba84a33b9 | ||
|
|
ae49166aa2 | ||
|
|
e09185fd0e | ||
|
|
56379bb3b9 | ||
|
|
027e4b4f25 | ||
|
|
ba951cb6e3 | ||
|
|
ae85cf4b6c | ||
|
|
dbc79f8c42 | ||
|
|
54c3070607 | ||
|
|
013eaa30b6 | ||
|
|
751043bf81 | ||
|
|
14f7198a07 | ||
|
|
94af819ae5 | ||
|
|
dbcc9afbc7 | ||
|
|
8556033ae6 | ||
|
|
650493f863 | ||
|
|
d80ad77871 | ||
|
|
f4b129b9f1 | ||
|
|
c0a05e0650 | ||
|
|
33d95d3e3a | ||
|
|
f573f83fb9 | ||
|
|
e94c36b7e6 | ||
|
|
c879e9e34d | ||
|
|
ac39b564a8 | ||
|
|
d91388aba4 | ||
|
|
733d78abdd | ||
|
|
d5809e375c | ||
|
|
2440a676bd | ||
|
|
03ac6c72e7 | ||
|
|
1bbbcabae0 | ||
|
|
9149b6b998 | ||
|
|
2603b5a402 | ||
|
|
dbddf5b9eb | ||
|
|
841f77bac2 | ||
|
|
83ffe75baa | ||
|
|
8cb7094803 | ||
|
|
ed8cd0ad19 | ||
|
|
90d8e65a3b | ||
|
|
b24fcb18af | ||
|
|
c2f2d0f8af | ||
|
|
e33bdd7e62 | ||
|
|
402adc3559 | ||
|
|
0f45d03c51 | ||
|
|
0397d7ab53 | ||
|
|
79f86b82e4 | ||
|
|
261a7a34e3 | ||
|
|
723bb89e10 | ||
|
|
832e4f3c37 | ||
|
|
75a4081549 | ||
|
|
f9291f9fd1 | ||
|
|
c3b4ee9321 | ||
|
|
f86896943d | ||
|
|
c33f05e8ca | ||
|
|
52727ded03 | ||
|
|
f7d132758e | ||
|
|
bb17ca9a53 | ||
|
|
aab21c5b17 | ||
|
|
acbafee02a | ||
|
|
c6d2b1a222 | ||
|
|
b037f75fb0 | ||
|
|
a1e79d3050 | ||
|
|
354969d5fa | ||
|
|
a371892409 | ||
|
|
b0789a7ce7 | ||
|
|
08be8eb4f8 | ||
|
|
bafddf4baf | ||
|
|
75b9184a00 | ||
|
|
5dc83cf2bf | ||
|
|
092e9062c8 | ||
|
|
512c921a81 | ||
|
|
defcd6fe26 | ||
|
|
025b6cbfb7 | ||
|
|
b0687dbeb5 | ||
|
|
e0b109cba6 | ||
|
|
adaa8ece89 | ||
|
|
6516b20e16 | ||
|
|
839cb03690 | ||
|
|
2bcd99b14f | ||
|
|
e3ebf6e8a1 | ||
|
|
76d28314b0 | ||
|
|
ec450b8fd8 | ||
|
|
79c5b2edd5 | ||
|
|
2d45ac51ef | ||
|
|
505bb8f06d | ||
|
|
f8408bd29f | ||
|
|
5f2c84a913 | ||
|
|
3011c99e3f | ||
|
|
ebc97f42ad | ||
|
|
4660c6d363 | ||
|
|
e239ef50ba | ||
|
|
8b4312a880 | ||
|
|
90daf8087e | ||
|
|
dd21bcb34c | ||
|
|
c4113f1ac7 | ||
|
|
efa48acd1d | ||
|
|
15e4d07a6d | ||
|
|
cb2248809c | ||
|
|
eb9551d81b | ||
|
|
87d1256a1b | ||
|
|
dd6179cf25 | ||
|
|
23c56ff887 | ||
|
|
c4eefa6917 | ||
|
|
202cff58f2 | ||
|
|
025806f0fd | ||
|
|
b0c54ef0f1 | ||
|
|
4d7681b1a4 | ||
|
|
340fb3f624 | ||
|
|
a83aad22ca | ||
|
|
5a418dcce6 | ||
|
|
ec5392708f | ||
|
|
901db92b11 | ||
|
|
01b8b10344 | ||
|
|
698d642ec8 | ||
|
|
90d1047fb2 | ||
|
|
b0d1eac477 | ||
|
|
cce02aec3d | ||
|
|
492ff58aa8 | ||
|
|
dd3e73996b | ||
|
|
931ed7adac | ||
|
|
861fd55d06 | ||
|
|
9a4eee4e7d | ||
|
|
ed76cdbddf | ||
|
|
9d91549803 | ||
|
|
a5425a3c71 | ||
|
|
f4b105b10f | ||
|
|
e4de09c55b | ||
|
|
d77be9d382 | ||
|
|
626909addb | ||
|
|
9b750bedef | ||
|
|
b976e0ef4e | ||
|
|
fd434292ad | ||
|
|
7b4d3a869b | ||
|
|
eeebb1b59f | ||
|
|
63136f64b7 | ||
|
|
1d2fbf2d92 | ||
|
|
1e52dded14 | ||
|
|
cfc7005275 | ||
|
|
f23afcd5aa | ||
|
|
4e88a0c91b | ||
|
|
d070f9deb0 | ||
|
|
b736e20a74 | ||
|
|
aad20d0a03 | ||
|
|
7ff97348d9 | ||
|
|
68dda3a46d | ||
|
|
2cd44f8c33 | ||
|
|
9775954aff | ||
|
|
1a071b0b54 | ||
|
|
8dcea59c74 | ||
|
|
f482f77871 | ||
|
|
b058c39ee1 | ||
|
|
b926b6c67f | ||
|
|
3fb8e5f799 | ||
|
|
9ebc9c0867 | ||
|
|
f1f96713a4 | ||
|
|
fc3b6d2c2e | ||
|
|
d0d0716b3b |
51
pom.xml
51
pom.xml
@@ -7,7 +7,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>github-api</artifactId>
|
<artifactId>github-api</artifactId>
|
||||||
<version>1.66</version>
|
<version>1.76</version>
|
||||||
<name>GitHub API for Java</name>
|
<name>GitHub API for Java</name>
|
||||||
<url>http://github-api.kohsuke.org/</url>
|
<url>http://github-api.kohsuke.org/</url>
|
||||||
<description>GitHub API for Java</description>
|
<description>GitHub API for Java</description>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
|
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
|
||||||
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
|
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
|
||||||
<url>http://${project.artifactId}.kohsuke.org/</url>
|
<url>http://${project.artifactId}.kohsuke.org/</url>
|
||||||
<tag>github-api-1.66</tag>
|
<tag>github-api-1.76</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -28,10 +28,33 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<findbugs-maven-plugin.version>3.0.2</findbugs-maven-plugin.version>
|
||||||
|
<findbugs-maven-plugin.failOnError>true</findbugs-maven-plugin.failOnError>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||||
|
<version>1.15</version>
|
||||||
|
<configuration>
|
||||||
|
<signature>
|
||||||
|
<groupId>org.codehaus.mojo.signature</groupId>
|
||||||
|
<artifactId>java15</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</signature>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>ensure-java-1.5-class-library</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.infradna.tool</groupId>
|
<groupId>com.infradna.tool</groupId>
|
||||||
<artifactId>bridge-method-injector</artifactId>
|
<artifactId>bridge-method-injector</artifactId>
|
||||||
@@ -44,6 +67,24 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>findbugs-maven-plugin</artifactId>
|
||||||
|
<version>${findbugs-maven-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<xmlOutput>true</xmlOutput>
|
||||||
|
<failOnError>${findbugs-maven-plugin.failOnError}</failOnError>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>run-findbugs</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@@ -109,6 +150,12 @@
|
|||||||
<version>1.9.5</version>
|
<version>1.9.5</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
|
<artifactId>annotations</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
|||||||
21
src/main/java/org/kohsuke/github/BranchProtection.java
Normal file
21
src/main/java/org/kohsuke/github/BranchProtection.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
* @see GHBranch#disableProtection()
|
||||||
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
|
||||||
|
class BranchProtection {
|
||||||
|
boolean enabled;
|
||||||
|
RequiredStatusChecks requiredStatusChecks;
|
||||||
|
|
||||||
|
static class RequiredStatusChecks {
|
||||||
|
EnforcementLevel enforcement_level;
|
||||||
|
List<String> contexts = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,9 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD",
|
||||||
|
justification = "Being constructed by JSON deserialization")
|
||||||
class DeleteToken {
|
class DeleteToken {
|
||||||
public String delete_token;
|
public String delete_token;
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/main/java/org/kohsuke/github/EnforcementLevel.java
Normal file
14
src/main/java/org/kohsuke/github/EnforcementLevel.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public enum EnforcementLevel {
|
||||||
|
OFF, NON_ADMINS, EVERYONE;
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return name().toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asset in a release.
|
* Asset in a release.
|
||||||
@@ -60,6 +61,14 @@ public class GHAsset extends GHObject {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getBrowserDownloadUrl() {
|
public String getBrowserDownloadUrl() {
|
||||||
return browser_download_url;
|
return browser_download_url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -10,78 +11,86 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author janinko
|
* @author janinko
|
||||||
* @see GitHub#createToken(Collection, String, String)
|
* @see GitHub#createToken(Collection, String, String)
|
||||||
* @see http://developer.github.com/v3/oauth/#create-a-new-authorization
|
* @see <a href="http://developer.github.com/v3/oauth/#create-a-new-authorization">API documentation</a>
|
||||||
*/
|
*/
|
||||||
public class GHAuthorization extends GHObject {
|
public class GHAuthorization extends GHObject {
|
||||||
public static final String USER = "user";
|
public static final String USER = "user";
|
||||||
public static final String USER_EMAIL = "user:email";
|
public static final String USER_EMAIL = "user:email";
|
||||||
public static final String USER_FOLLOW = "user:follow";
|
public static final String USER_FOLLOW = "user:follow";
|
||||||
public static final String PUBLIC_REPO = "public_repo";
|
public static final String PUBLIC_REPO = "public_repo";
|
||||||
public static final String REPO = "repo";
|
public static final String REPO = "repo";
|
||||||
public static final String REPO_STATUS = "repo:status";
|
public static final String REPO_STATUS = "repo:status";
|
||||||
public static final String DELETE_REPO = "delete_repo";
|
public static final String DELETE_REPO = "delete_repo";
|
||||||
public static final String NOTIFICATIONS = "notifications";
|
public static final String NOTIFICATIONS = "notifications";
|
||||||
public static final String GIST = "gist";
|
public static final String GIST = "gist";
|
||||||
public static final String READ_HOOK = "read:repo_hook";
|
public static final String READ_HOOK = "read:repo_hook";
|
||||||
public static final String WRITE_HOOK = "write:repo_hook";
|
public static final String WRITE_HOOK = "write:repo_hook";
|
||||||
public static final String AMIN_HOOK = "admin:repo_hook";
|
public static final String AMIN_HOOK = "admin:repo_hook";
|
||||||
public static final String READ_ORG = "read:org";
|
public static final String READ_ORG = "read:org";
|
||||||
public static final String WRITE_ORG = "write:org";
|
public static final String WRITE_ORG = "write:org";
|
||||||
public static final String ADMIN_ORG = "admin:org";
|
public static final String ADMIN_ORG = "admin:org";
|
||||||
public static final String READ_KEY = "read:public_key";
|
public static final String READ_KEY = "read:public_key";
|
||||||
public static final String WRITE_KEY = "write:public_key";
|
public static final String WRITE_KEY = "write:public_key";
|
||||||
public static final String ADMIN_KEY = "admin:public_key";
|
public static final String ADMIN_KEY = "admin:public_key";
|
||||||
|
|
||||||
private GitHub root;
|
private GitHub root;
|
||||||
private List<String> scopes;
|
private List<String> scopes;
|
||||||
private String token;
|
private String token;
|
||||||
private App app;
|
private App app;
|
||||||
private String note;
|
private String note;
|
||||||
private String note_url;
|
private String note_url;
|
||||||
|
|
||||||
public GitHub getRoot() {
|
public GitHub getRoot() {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getScopes() {
|
public List<String> getScopes() {
|
||||||
return scopes;
|
return scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken(){
|
public String getToken() {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getAppUrl(){
|
public URL getAppUrl() {
|
||||||
return GitHub.parseURL(app.url);
|
return GitHub.parseURL(app.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName() {
|
||||||
return app.name;
|
return app.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getApiURL(){
|
@SuppressFBWarnings(value = "NM_CONFUSING",
|
||||||
|
justification = "It's a part of the library API, cannot be changed")
|
||||||
|
public URL getApiURL() {
|
||||||
return GitHub.parseURL(url);
|
return GitHub.parseURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNote() {
|
/**
|
||||||
return note;
|
* @deprecated This object has no HTML URL.
|
||||||
}
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public URL getNoteUrl(){
|
public String getNote() {
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getNoteUrl() {
|
||||||
return GitHub.parseURL(note_url);
|
return GitHub.parseURL(note_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ GHAuthorization wrap(GitHub root) {
|
/*package*/ GHAuthorization wrap(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
|
||||||
|
justification = "JSON API")
|
||||||
|
private static class App {
|
||||||
|
private String url;
|
||||||
private static class App{
|
private String name;
|
||||||
private String url;
|
}
|
||||||
private String name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.kohsuke.github.BranchProtection.RequiredStatusChecks;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A branch in a repository.
|
* A branch in a repository.
|
||||||
*
|
*
|
||||||
* @author Yusuke Kokubo
|
* @author Yusuke Kokubo
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
|
||||||
public class GHBranch {
|
public class GHBranch {
|
||||||
private GitHub root;
|
private GitHub root;
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
@@ -13,7 +22,10 @@ public class GHBranch {
|
|||||||
private Commit commit;
|
private Commit commit;
|
||||||
|
|
||||||
public static class Commit {
|
public static class Commit {
|
||||||
String sha,url;
|
String sha;
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
|
String url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitHub getRoot() {
|
public GitHub getRoot() {
|
||||||
@@ -38,9 +50,47 @@ public class GHBranch {
|
|||||||
return commit.sha;
|
return commit.sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables branch protection and allows anyone with push access to push changes.
|
||||||
|
*/
|
||||||
|
public void disableProtection() throws IOException {
|
||||||
|
BranchProtection bp = new BranchProtection();
|
||||||
|
bp.enabled = false;
|
||||||
|
setProtection(bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables branch protection to control what commit statuses are required to push.
|
||||||
|
*
|
||||||
|
* @see GHCommitStatus#getContext()
|
||||||
|
*/
|
||||||
|
public void enableProtection(EnforcementLevel level, Collection<String> contexts) throws IOException {
|
||||||
|
BranchProtection bp = new BranchProtection();
|
||||||
|
bp.enabled = true;
|
||||||
|
bp.requiredStatusChecks = new RequiredStatusChecks();
|
||||||
|
bp.requiredStatusChecks.enforcement_level = level;
|
||||||
|
bp.requiredStatusChecks.contexts.addAll(contexts);
|
||||||
|
setProtection(bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableProtection(EnforcementLevel level, String... contexts) throws IOException {
|
||||||
|
enableProtection(level, Arrays.asList(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setProtection(BranchProtection bp) throws IOException {
|
||||||
|
new Requester(root).method("PATCH")
|
||||||
|
.withHeader("Accept","application/vnd.github.loki-preview+json")
|
||||||
|
._with("protection",bp).to(getApiRoute());
|
||||||
|
}
|
||||||
|
|
||||||
|
String getApiRoute() {
|
||||||
|
return owner.getApiTailUrl("/branches/"+name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Branch:" + name + " in " + owner.getUrl();
|
final String url = owner != null ? owner.getUrl().toString() : "unknown";
|
||||||
|
return "Branch:" + name + " in " + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ GHBranch wrap(GHRepository repo) {
|
/*package*/ GHBranch wrap(GHRepository repo) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -16,6 +17,8 @@ import java.util.List;
|
|||||||
* @see GHRepository#getCommit(String)
|
* @see GHRepository#getCommit(String)
|
||||||
* @see GHCommitComment#getCommit()
|
* @see GHCommitComment#getCommit()
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD"},
|
||||||
|
justification = "JSON API")
|
||||||
public class GHCommit {
|
public class GHCommit {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
|
|
||||||
@@ -24,6 +27,8 @@ public class GHCommit {
|
|||||||
/**
|
/**
|
||||||
* Short summary of this commit.
|
* Short summary of this commit.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public static class ShortInfo {
|
public static class ShortInfo {
|
||||||
private GHAuthor author;
|
private GHAuthor author;
|
||||||
private GHAuthor committer;
|
private GHAuthor committer;
|
||||||
@@ -32,26 +37,26 @@ public class GHCommit {
|
|||||||
|
|
||||||
private int comment_count;
|
private int comment_count;
|
||||||
|
|
||||||
@WithBridgeMethods(value=GHAuthor.class,castRequired=true)
|
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
|
||||||
public GitUser getAuthor() {
|
public GitUser getAuthor() {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithBridgeMethods(value=GHAuthor.class,castRequired=true)
|
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
|
||||||
public GitUser getCommitter() {
|
public GitUser getCommitter() {
|
||||||
return committer;
|
return committer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commit message.
|
* Commit message.
|
||||||
*/
|
*/
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCommentCount() {
|
public int getCommentCount() {
|
||||||
return comment_count;
|
return comment_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,10 +72,13 @@ public class GHCommit {
|
|||||||
/**
|
/**
|
||||||
* A file that was modified.
|
* A file that was modified.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD",
|
||||||
|
justification = "It's being initilized by JSON deserialization")
|
||||||
public static class File {
|
public static class File {
|
||||||
String status;
|
String status;
|
||||||
int changes,additions,deletions;
|
int changes,additions,deletions;
|
||||||
String raw_url, blob_url, filename, sha, patch;
|
String raw_url, blob_url, sha, patch;
|
||||||
|
String filename, previous_filename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of lines added + removed.
|
* Number of lines added + removed.
|
||||||
@@ -94,19 +102,28 @@ public class GHCommit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "modified", "added", or "deleted"
|
* "modified", "added", or "removed"
|
||||||
*/
|
*/
|
||||||
public String getStatus() {
|
public String getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just the base name and the extension without any directory name.
|
* Full path in the repository.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "NM_CONFUSING",
|
||||||
|
justification = "It's a part of the library's API and cannot be renamed")
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Previous path, in case file has moved.
|
||||||
|
*/
|
||||||
|
public String getPreviousFilename() {
|
||||||
|
return previous_filename;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual change.
|
* The actual change.
|
||||||
*/
|
*/
|
||||||
@@ -139,28 +156,34 @@ public class GHCommit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Parent {
|
public static class Parent {
|
||||||
String url,sha;
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
|
String url;
|
||||||
|
String sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class User {
|
static class User {
|
||||||
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
||||||
String url,avatar_url,login,gravatar_id;
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
|
String url,avatar_url,gravatar_id;
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
String login;
|
||||||
}
|
}
|
||||||
|
|
||||||
String url,sha;
|
String url,html_url,sha;
|
||||||
List<File> files;
|
List<File> files;
|
||||||
Stats stats;
|
Stats stats;
|
||||||
List<Parent> parents;
|
List<Parent> parents;
|
||||||
User author,committer;
|
User author,committer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ShortInfo getCommitShortInfo() {
|
|
||||||
return commit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public ShortInfo getCommitShortInfo() throws IOException {
|
||||||
|
populate();
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* The repository that contains the commit.
|
* The repository that contains the commit.
|
||||||
*/
|
*/
|
||||||
public GHRepository getOwner() {
|
public GHRepository getOwner() {
|
||||||
@@ -170,24 +193,34 @@ public class GHCommit {
|
|||||||
/**
|
/**
|
||||||
* Number of lines added + removed.
|
* Number of lines added + removed.
|
||||||
*/
|
*/
|
||||||
public int getLinesChanged() {
|
public int getLinesChanged() throws IOException {
|
||||||
|
populate();
|
||||||
return stats.total;
|
return stats.total;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of lines added.
|
* Number of lines added.
|
||||||
*/
|
*/
|
||||||
public int getLinesAdded() {
|
public int getLinesAdded() throws IOException {
|
||||||
|
populate();
|
||||||
return stats.additions;
|
return stats.additions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of lines removed.
|
* Number of lines removed.
|
||||||
*/
|
*/
|
||||||
public int getLinesDeleted() {
|
public int getLinesDeleted() throws IOException {
|
||||||
|
populate();
|
||||||
return stats.deletions;
|
return stats.deletions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL of this commit like "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000"
|
||||||
|
*/
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [0-9a-f]{40} SHA1 checksum.
|
* [0-9a-f]{40} SHA1 checksum.
|
||||||
*/
|
*/
|
||||||
@@ -201,7 +234,8 @@ public class GHCommit {
|
|||||||
* @return
|
* @return
|
||||||
* Can be empty but never null.
|
* Can be empty but never null.
|
||||||
*/
|
*/
|
||||||
public List<File> getFiles() {
|
public List<File> getFiles() throws IOException {
|
||||||
|
populate();
|
||||||
return files!=null ? Collections.unmodifiableList(files) : Collections.<File>emptyList();
|
return files!=null ? Collections.unmodifiableList(files) : Collections.<File>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +285,8 @@ public class GHCommit {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHCommitComment> listComments() {
|
public PagedIterable<GHCommitComment> listComments() {
|
||||||
return new PagedIterable<GHCommitComment>() {
|
return new PagedIterable<GHCommitComment>() {
|
||||||
public PagedIterator<GHCommitComment> iterator() {
|
public PagedIterator<GHCommitComment> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHCommitComment>(owner.root.retrieve().asIterator(String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha), GHCommitComment[].class)) {
|
return new PagedIterator<GHCommitComment>(owner.root.retrieve().asIterator(String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha), GHCommitComment[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHCommitComment[] page) {
|
protected void wrapUp(GHCommitComment[] page) {
|
||||||
for (GHCommitComment c : page)
|
for (GHCommitComment c : page)
|
||||||
@@ -279,7 +313,7 @@ public class GHCommit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHCommitComment createComment(String body) throws IOException {
|
public GHCommitComment createComment(String body) throws IOException {
|
||||||
return createComment(body,null,null,null);
|
return createComment(body, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,6 +330,14 @@ public class GHCommit {
|
|||||||
return owner.getLastCommitStatus(sha);
|
return owner.getLastCommitStatus(sha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some of the fields are not always filled in when this object is retrieved as a part of another API call.
|
||||||
|
*/
|
||||||
|
void populate() throws IOException {
|
||||||
|
if (files==null && stats==null)
|
||||||
|
owner.root.retrieve().to(owner.getApiTailUrl("commits/" + sha), this);
|
||||||
|
}
|
||||||
|
|
||||||
GHCommit wrapUp(GHRepository owner) {
|
GHCommit wrapUp(GHRepository owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -12,6 +13,8 @@ import java.util.Date;
|
|||||||
* @see GHCommit#listComments()
|
* @see GHCommit#listComments()
|
||||||
* @see GHCommit#createComment(String, String, Integer, Integer)
|
* @see GHCommit#createComment(String, String, Integer, Integer)
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public class GHCommitComment extends GHObject {
|
public class GHCommitComment extends GHObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
|
|
||||||
@@ -22,8 +25,12 @@ public class GHCommitComment extends GHObject {
|
|||||||
|
|
||||||
static class User {
|
static class User {
|
||||||
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
||||||
String url,avatar_url,login,gravatar_id;
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
|
String url,avatar_url,gravatar_id;
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
|
String login;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHRepository getOwner() {
|
public GHRepository getOwner() {
|
||||||
@@ -83,7 +90,7 @@ public class GHCommitComment extends GHObject {
|
|||||||
* Updates the body of the commit message.
|
* Updates the body of the commit message.
|
||||||
*/
|
*/
|
||||||
public void update(String body) throws IOException {
|
public void update(String body) throws IOException {
|
||||||
GHCommitComment r = new Requester(owner.root)
|
new Requester(owner.root)
|
||||||
.with("body", body)
|
.with("body", body)
|
||||||
.method("PATCH").to(getApiTail(), GHCommitComment.class);
|
.method("PATCH").to(getApiTail(), GHCommitComment.class);
|
||||||
this.body = body;
|
this.body = body;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies a commit in {@link GHPullRequest}.
|
* Identifies a commit in {@link GHPullRequest}.
|
||||||
*
|
*
|
||||||
@@ -69,6 +71,13 @@ public class GHCommitPointer {
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the commit that this pointer is referring to.
|
||||||
|
*/
|
||||||
|
public GHCommit getCommit() throws IOException {
|
||||||
|
return getRepository().getCommit(getSha());
|
||||||
|
}
|
||||||
|
|
||||||
void wrapUp(GitHub root) {
|
void wrapUp(GitHub root) {
|
||||||
if (user!=null) user.root = root;
|
if (user!=null) user.root = root;
|
||||||
if (repo!=null) repo.wrap(root);
|
if (repo!=null) repo.wrap(root);
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ public class GHCommitQueryBuilder {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHCommit> list() {
|
public PagedIterable<GHCommit> list() {
|
||||||
return new PagedIterable<GHCommit>() {
|
return new PagedIterable<GHCommit>() {
|
||||||
public PagedIterator<GHCommit> iterator() {
|
public PagedIterator<GHCommit> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHCommit>(req.asIterator(repo.getApiTailUrl("commits"), GHCommit[].class)) {
|
return new PagedIterator<GHCommit>(req.asIterator(repo.getApiTailUrl("commits"), GHCommit[].class, pageSize)) {
|
||||||
protected void wrapUp(GHCommit[] page) {
|
protected void wrapUp(GHCommit[] page) {
|
||||||
for (GHCommit c : page)
|
for (GHCommit c : page)
|
||||||
c.wrapUp(repo);
|
c.wrapUp(repo);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a status of a commit.
|
* Represents a status of a commit.
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
* @see GHRepository#getCommitStatus(String)
|
* @see GHRepository#getLastCommitStatus(String)
|
||||||
* @see GHCommit#getStatus()
|
* @see GHCommit#getLastStatus()
|
||||||
|
* @see GHRepository#createCommitStatus(String, GHCommitState, String, String)
|
||||||
*/
|
*/
|
||||||
public class GHCommitStatus extends GHObject {
|
public class GHCommitStatus extends GHObject {
|
||||||
String state;
|
String state;
|
||||||
@@ -49,7 +49,15 @@ public class GHCommitStatus extends GHObject {
|
|||||||
return creator;
|
return creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContext() {
|
public String getContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The model user for comparing 2 commits in the GitHub API.
|
* The model user for comparing 2 commits in the GitHub API.
|
||||||
@@ -65,15 +65,27 @@ public class GHCompare {
|
|||||||
return merge_base_commit;
|
return merge_base_commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of commits.
|
||||||
|
* @return A copy of the array being stored in the class.
|
||||||
|
*/
|
||||||
public Commit[] getCommits() {
|
public Commit[] getCommits() {
|
||||||
return commits;
|
Commit[] newValue = new Commit[commits.length];
|
||||||
|
System.arraycopy(commits, 0, newValue, 0, commits.length);
|
||||||
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of commits.
|
||||||
|
* @return A copy of the array being stored in the class.
|
||||||
|
*/
|
||||||
public GHCommit.File[] getFiles() {
|
public GHCommit.File[] getFiles() {
|
||||||
return files;
|
GHCommit.File[] newValue = new GHCommit.File[files.length];
|
||||||
}
|
System.arraycopy(files, 0, newValue, 0, files.length);
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
public GHCompare wrap(GHRepository owner) {
|
public GHCompare wrap(GHRepository owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
for (Commit commit : commits) {
|
for (Commit commit : commits) {
|
||||||
commit.wrapUp(owner);
|
commit.wrapUp(owner);
|
||||||
@@ -87,6 +99,8 @@ public class GHCompare {
|
|||||||
* Compare commits had a child commit element with additional details we want to capture.
|
* Compare commits had a child commit element with additional details we want to capture.
|
||||||
* This extenstion of GHCommit provides that.
|
* This extenstion of GHCommit provides that.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
|
||||||
|
justification = "JSON API")
|
||||||
public static class Commit extends GHCommit {
|
public static class Commit extends GHCommit {
|
||||||
|
|
||||||
private InnerCommit commit;
|
private InnerCommit commit;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
@@ -75,8 +76,9 @@ public class GHContent {
|
|||||||
* @deprecated
|
* @deprecated
|
||||||
* Use {@link #read()}
|
* Use {@link #read()}
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
|
||||||
public String getContent() throws IOException {
|
public String getContent() throws IOException {
|
||||||
return new String(DatatypeConverter.parseBase64Binary(getEncodedContent()));
|
return new String(Base64.decodeBase64(getEncodedContent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,7 +115,8 @@ public class GHContent {
|
|||||||
* Retrieves the actual content stored here.
|
* Retrieves the actual content stored here.
|
||||||
*/
|
*/
|
||||||
public InputStream read() throws IOException {
|
public InputStream read() throws IOException {
|
||||||
return new Requester(root).asStream(getDownloadUrl());
|
// if the download link is encoded with a token on the query string, the default behavior of POST will fail
|
||||||
|
return new Requester(root).method("GET").asStream(getDownloadUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,8 +153,8 @@ public class GHContent {
|
|||||||
throw new IllegalStateException(path+" is not a directory");
|
throw new IllegalStateException(path+" is not a directory");
|
||||||
|
|
||||||
return new PagedIterable<GHContent>() {
|
return new PagedIterable<GHContent>() {
|
||||||
public PagedIterator<GHContent> iterator() {
|
public PagedIterator<GHContent> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHContent>(root.retrieve().asIterator(url, GHContent[].class)) {
|
return new PagedIterator<GHContent>(root.retrieve().asIterator(url, GHContent[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHContent[] page) {
|
protected void wrapUp(GHContent[] page) {
|
||||||
GHContent.wrap(page, repository);
|
GHContent.wrap(page, repository);
|
||||||
@@ -161,10 +164,12 @@ public class GHContent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
|
||||||
public GHContentUpdateResponse update(String newContent, String commitMessage) throws IOException {
|
public GHContentUpdateResponse update(String newContent, String commitMessage) throws IOException {
|
||||||
return update(newContent.getBytes(), commitMessage, null);
|
return update(newContent.getBytes(), commitMessage, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
|
||||||
public GHContentUpdateResponse update(String newContent, String commitMessage, String branch) throws IOException {
|
public GHContentUpdateResponse update(String newContent, String commitMessage, String branch) throws IOException {
|
||||||
return update(newContent.getBytes(), commitMessage, branch);
|
return update(newContent.getBytes(), commitMessage, branch);
|
||||||
}
|
}
|
||||||
@@ -174,7 +179,7 @@ public class GHContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage, String branch) throws IOException {
|
public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage, String branch) throws IOException {
|
||||||
String encodedContent = DatatypeConverter.printBase64Binary(newContentBytes);
|
String encodedContent = Base64.encodeBase64String(newContentBytes);
|
||||||
|
|
||||||
Requester requester = new Requester(root)
|
Requester requester = new Requester(root)
|
||||||
.with("path", path)
|
.with("path", path)
|
||||||
|
|||||||
114
src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
Normal file
114
src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a repository
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public class GHCreateRepositoryBuilder {
|
||||||
|
private final GitHub root;
|
||||||
|
protected final Requester builder;
|
||||||
|
private final String apiUrlTail;
|
||||||
|
|
||||||
|
/*package*/ GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) {
|
||||||
|
this.root = root;
|
||||||
|
this.apiUrlTail = apiUrlTail;
|
||||||
|
this.builder = new Requester(root);
|
||||||
|
this.builder.with("name",name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHCreateRepositoryBuilder description(String description) {
|
||||||
|
this.builder.with("description",description);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHCreateRepositoryBuilder homepage(URL homepage) {
|
||||||
|
return homepage(homepage.toExternalForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHCreateRepositoryBuilder homepage(String homepage) {
|
||||||
|
this.builder.with("homepage",homepage);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a private repository
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder private_(boolean b) {
|
||||||
|
this.builder.with("private",b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables issue tracker
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder issues(boolean b) {
|
||||||
|
this.builder.with("has_issues",b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables wiki
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder wiki(boolean b) {
|
||||||
|
this.builder.with("has_wiki",b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables downloads
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder downloads(boolean b) {
|
||||||
|
this.builder.with("has_downloads",b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, create an initial commit with empty README.
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder autoInit(boolean b) {
|
||||||
|
this.builder.with("auto_init",b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default .gitignore
|
||||||
|
*
|
||||||
|
* See https://developer.github.com/v3/repos/#create
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder gitignoreTemplate(String language) {
|
||||||
|
this.builder.with("gitignore_template",language);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Desired license template to apply
|
||||||
|
*
|
||||||
|
* See https://developer.github.com/v3/repos/#create
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder licenseTemplate(String license) {
|
||||||
|
this.builder.with("license_template",license);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The team that gets granted access to this repository. Only valid for creating a repository in
|
||||||
|
* an organization.
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder team(GHTeam team) {
|
||||||
|
if (team!=null)
|
||||||
|
this.builder.with("team_id",team.getId());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a repository with all the parameters.
|
||||||
|
*/
|
||||||
|
public GHRepository create() throws IOException {
|
||||||
|
return builder.method("POST").to(apiUrlTail, GHRepository.class).wrap(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ public class GHDeployKey {
|
|||||||
protected String url, key, title;
|
protected String url, key, title;
|
||||||
protected boolean verified;
|
protected boolean verified;
|
||||||
protected int id;
|
protected int id;
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
@@ -31,10 +31,10 @@ public class GHDeployKey {
|
|||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHDeployKey wrap(GHRepository repo) {
|
public GHDeployKey wrap(GHRepository repo) {
|
||||||
this.owner = repo;
|
this.owner = repo;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this).append("title",title).append("id",id).append("key",key).toString();
|
return new ToStringBuilder(this).append("title",title).append("id",id).append("key",key).toString();
|
||||||
|
|||||||
@@ -50,4 +50,12 @@ public class GHDeployment extends GHObject {
|
|||||||
public String getSha(){
|
public String getSha(){
|
||||||
return sha;
|
return sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class GHDeploymentStatus extends GHObject {
|
public class GHDeploymentStatus extends GHObject {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
@@ -28,9 +29,16 @@ public class GHDeploymentStatus extends GHObject {
|
|||||||
public URL getRepositoryUrl() {
|
public URL getRepositoryUrl() {
|
||||||
return GitHub.parseURL(repository_url);
|
return GitHub.parseURL(repository_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHDeploymentState getState() {
|
public GHDeploymentState getState() {
|
||||||
return GHDeploymentState.valueOf(state.toUpperCase());
|
return GHDeploymentState.valueOf(state.toUpperCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class GHDeploymentStatusBuilder {
|
public class GHDeploymentStatusBuilder {
|
||||||
private final Requester builder;
|
private final Requester builder;
|
||||||
@@ -11,7 +12,7 @@ public class GHDeploymentStatusBuilder {
|
|||||||
this.repo = repo;
|
this.repo = repo;
|
||||||
this.deploymentId = deploymentId;
|
this.deploymentId = deploymentId;
|
||||||
this.builder = new Requester(repo.root);
|
this.builder = new Requester(repo.root);
|
||||||
this.builder.with("state",state.toString().toLowerCase());
|
this.builder.with("state",state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHDeploymentStatusBuilder description(String description) {
|
public GHDeploymentStatusBuilder description(String description) {
|
||||||
|
|||||||
10
src/main/java/org/kohsuke/github/GHDirection.java
Normal file
10
src/main/java/org/kohsuke/github/GHDirection.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort direction
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public enum GHDirection {
|
||||||
|
ASC, DESC
|
||||||
|
}
|
||||||
@@ -23,12 +23,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an email of GitHub.
|
* Represents an email of GitHub.
|
||||||
*
|
*
|
||||||
* @author Kelly Campbell
|
* @author Kelly Campbell
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD", "NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD"}, justification = "JSON API")
|
||||||
public class GHEmail {
|
public class GHEmail {
|
||||||
|
|
||||||
protected String email;
|
protected String email;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook event type.
|
* Hook event type.
|
||||||
*
|
*
|
||||||
* See http://developer.github.com/v3/events/types/
|
|
||||||
*
|
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
* @see GHEventInfo
|
* @see GHEventInfo
|
||||||
|
* @see <a href="https://developer.github.com/v3/activity/events/types/">Event type reference</a>
|
||||||
*/
|
*/
|
||||||
public enum GHEvent {
|
public enum GHEvent {
|
||||||
COMMIT_COMMENT,
|
COMMIT_COMMENT,
|
||||||
@@ -23,12 +24,28 @@ public enum GHEvent {
|
|||||||
ISSUE_COMMENT,
|
ISSUE_COMMENT,
|
||||||
ISSUES,
|
ISSUES,
|
||||||
MEMBER,
|
MEMBER,
|
||||||
|
PAGE_BUILD,
|
||||||
PUBLIC,
|
PUBLIC,
|
||||||
PULL_REQUEST,
|
PULL_REQUEST,
|
||||||
PULL_REQUEST_REVIEW_COMMENT,
|
PULL_REQUEST_REVIEW_COMMENT,
|
||||||
PUSH,
|
PUSH,
|
||||||
RELEASE,
|
RELEASE,
|
||||||
|
REPOSITORY, // only valid for org hooks
|
||||||
STATUS,
|
STATUS,
|
||||||
TEAM_ADD,
|
TEAM_ADD,
|
||||||
WATCH
|
WATCH,
|
||||||
|
PING,
|
||||||
|
/**
|
||||||
|
* Special event type that means "every possible event"
|
||||||
|
*/
|
||||||
|
ALL;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns GitHub's internal representation of this event.
|
||||||
|
*/
|
||||||
|
String symbol() {
|
||||||
|
if (this==ALL) return "*";
|
||||||
|
return name().toLowerCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,21 @@ import java.io.IOException;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an event.
|
* Represents an event.
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||||
public class GHEventInfo {
|
public class GHEventInfo {
|
||||||
private GitHub root;
|
private GitHub root;
|
||||||
|
|
||||||
// we don't want to expose Jackson dependency to the user. This needs databinding
|
// we don't want to expose Jackson dependency to the user. This needs databinding
|
||||||
private ObjectNode payload;
|
private ObjectNode payload;
|
||||||
|
|
||||||
|
private long id;
|
||||||
private String created_at;
|
private String created_at;
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
@@ -27,8 +30,12 @@ public class GHEventInfo {
|
|||||||
/**
|
/**
|
||||||
* Inside the event JSON model, GitHub uses a slightly different format.
|
* Inside the event JSON model, GitHub uses a slightly different format.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" }, justification = "JSON API")
|
||||||
public static class GHEventRepository {
|
public static class GHEventRepository {
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
private int id;
|
private int id;
|
||||||
|
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||||
private String url; // repository API URL
|
private String url; // repository API URL
|
||||||
private String name; // owner/repo
|
private String name; // owner/repo
|
||||||
}
|
}
|
||||||
@@ -48,6 +55,10 @@ public class GHEventInfo {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public Date getCreatedAt() {
|
public Date getCreatedAt() {
|
||||||
return GitHub.parseDate(created_at);
|
return GitHub.parseDate(created_at);
|
||||||
}
|
}
|
||||||
@@ -55,10 +66,14 @@ public class GHEventInfo {
|
|||||||
/**
|
/**
|
||||||
* Repository where the change was made.
|
* Repository where the change was made.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
|
||||||
|
justification = "The field comes from JSON deserialization")
|
||||||
public GHRepository getRepository() throws IOException {
|
public GHRepository getRepository() throws IOException {
|
||||||
return root.getRepository(repo.name);
|
return root.getRepository(repo.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
|
||||||
|
justification = "The field comes from JSON deserialization")
|
||||||
public GHUser getActor() throws IOException {
|
public GHUser getActor() throws IOException {
|
||||||
return root.getUser(actor.getLogin());
|
return root.getUser(actor.getLogin());
|
||||||
}
|
}
|
||||||
@@ -70,6 +85,8 @@ public class GHEventInfo {
|
|||||||
return actor.getLogin();
|
return actor.getLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
|
||||||
|
justification = "The field comes from JSON deserialization")
|
||||||
public GHOrganization getOrganization() throws IOException {
|
public GHOrganization getOrganization() throws IOException {
|
||||||
return (org==null || org.getLogin()==null) ? null : root.getOrganization(org.getLogin());
|
return (org==null || org.getLogin()==null) ? null : root.getOrganization(org.getLogin());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ public abstract class GHEventPayload {
|
|||||||
*
|
*
|
||||||
* @see <a href="http://developer.github.com/v3/activity/events/types/#pullrequestevent">authoritative source</a>
|
* @see <a href="http://developer.github.com/v3/activity/events/types/#pullrequestevent">authoritative source</a>
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public static class PullRequest extends GHEventPayload {
|
public static class PullRequest extends GHEventPayload {
|
||||||
private String action;
|
private String action;
|
||||||
private int number;
|
private int number;
|
||||||
@@ -67,12 +70,15 @@ public abstract class GHEventPayload {
|
|||||||
*
|
*
|
||||||
* @see <a href="http://developer.github.com/v3/activity/events/types/#issuecommentevent">authoritative source</a>
|
* @see <a href="http://developer.github.com/v3/activity/events/types/#issuecommentevent">authoritative source</a>
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" },
|
||||||
|
justification = "Constructed by JSON deserialization")
|
||||||
public static class IssueComment extends GHEventPayload {
|
public static class IssueComment extends GHEventPayload {
|
||||||
private String action;
|
private String action;
|
||||||
private GHIssueComment comment;
|
private GHIssueComment comment;
|
||||||
private GHIssue issue;
|
private GHIssue issue;
|
||||||
private GHRepository repository;
|
private GHRepository repository;
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization")
|
||||||
public String getAction() {
|
public String getAction() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
@@ -104,8 +110,12 @@ public abstract class GHEventPayload {
|
|||||||
@Override
|
@Override
|
||||||
void wrapUp(GitHub root) {
|
void wrapUp(GitHub root) {
|
||||||
super.wrapUp(root);
|
super.wrapUp(root);
|
||||||
repository.wrap(root);
|
if (repository != null) {
|
||||||
issue.wrap(repository);
|
repository.wrap(root);
|
||||||
|
issue.wrap(repository);
|
||||||
|
} else {
|
||||||
|
issue.wrap(root);
|
||||||
|
}
|
||||||
comment.wrapUp(issue);
|
comment.wrapUp(issue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,6 +175,7 @@ public abstract class GHEventPayload {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void wrapUp(GitHub root) {
|
void wrapUp(GitHub root) {
|
||||||
|
super.wrapUp(root);
|
||||||
if (repository!=null)
|
if (repository!=null)
|
||||||
repository.wrap(root);
|
repository.wrap(root);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.kohsuke.github;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -60,8 +61,8 @@ public class GHGist extends GHObject {
|
|||||||
return git_push_url;
|
return git_push_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHtmlUrl() {
|
public URL getHtmlUrl() {
|
||||||
return html_url;
|
return GitHub.parseURL(html_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPublic() {
|
public boolean isPublic() {
|
||||||
@@ -139,8 +140,8 @@ public class GHGist extends GHObject {
|
|||||||
|
|
||||||
public PagedIterable<GHGist> listForks() {
|
public PagedIterable<GHGist> listForks() {
|
||||||
return new PagedIterable<GHGist>() {
|
return new PagedIterable<GHGist>() {
|
||||||
public PagedIterator<GHGist> iterator() {
|
public PagedIterator<GHGist> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHGist>(root.retrieve().asIterator(getApiTailUrl("forks"), GHGist[].class)) {
|
return new PagedIterator<GHGist>(root.retrieve().asIterator(getApiTailUrl("forks"), GHGist[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHGist[] page) {
|
protected void wrapUp(GHGist[] page) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -10,30 +12,24 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public class GHHook extends GHObject {
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
/**
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
* Repository that the hook belongs to.
|
public abstract class GHHook extends GHObject {
|
||||||
*/
|
|
||||||
/*package*/ transient GHRepository repository;
|
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
List<String> events;
|
List<String> events;
|
||||||
boolean active;
|
boolean active;
|
||||||
Map<String,String> config;
|
Map<String,String> config;
|
||||||
|
|
||||||
/*package*/ GHHook wrap(GHRepository owner) {
|
|
||||||
this.repository = owner;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumSet<GHEvent> getEvents() {
|
public EnumSet<GHEvent> getEvents() {
|
||||||
EnumSet<GHEvent> s = EnumSet.noneOf(GHEvent.class);
|
EnumSet<GHEvent> s = EnumSet.noneOf(GHEvent.class);
|
||||||
for (String e : events)
|
for (String e : events) {
|
||||||
s.add(Enum.valueOf(GHEvent.class,e.toUpperCase(Locale.ENGLISH)));
|
if (e.equals("*")) s.add(GHEvent.ALL);
|
||||||
|
else s.add(Enum.valueOf(GHEvent.class, e.toUpperCase(Locale.ENGLISH)));
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +45,18 @@ public class GHHook extends GHObject {
|
|||||||
* Deletes this hook.
|
* Deletes this hook.
|
||||||
*/
|
*/
|
||||||
public void delete() throws IOException {
|
public void delete() throws IOException {
|
||||||
new Requester(repository.root).method("DELETE").to(String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id));
|
new Requester(getRoot()).method("DELETE").to(getApiRoute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract GitHub getRoot();
|
||||||
|
|
||||||
|
abstract String getApiRoute();
|
||||||
}
|
}
|
||||||
|
|||||||
131
src/main/java/org/kohsuke/github/GHHooks.java
Normal file
131
src/main/java/org/kohsuke/github/GHHooks.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for creating and retrieving webhooks; removes duplication between GHOrganization and GHRepository
|
||||||
|
* functionality
|
||||||
|
*/
|
||||||
|
class GHHooks {
|
||||||
|
static abstract class Context {
|
||||||
|
private final GitHub root;
|
||||||
|
|
||||||
|
private Context(GitHub root) {
|
||||||
|
this.root = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GHHook> getHooks() throws IOException {
|
||||||
|
|
||||||
|
GHHook [] hookArray = root.retrieve().to(collection(),collectionClass()); // jdk/eclipse bug requires this to be on separate line
|
||||||
|
List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(hookArray));
|
||||||
|
for (GHHook h : list)
|
||||||
|
wrap(h);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHHook getHook(int id) throws IOException {
|
||||||
|
GHHook hook = root.retrieve().to(collection() + "/" + id, clazz());
|
||||||
|
return wrap(hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active) throws IOException {
|
||||||
|
List<String> ea = null;
|
||||||
|
if (events!=null) {
|
||||||
|
ea = new ArrayList<String>();
|
||||||
|
for (GHEvent e : events)
|
||||||
|
ea.add(e.symbol());
|
||||||
|
}
|
||||||
|
|
||||||
|
GHHook hook = new Requester(root)
|
||||||
|
.with("name", name)
|
||||||
|
.with("active", active)
|
||||||
|
._with("config", config)
|
||||||
|
._with("events", ea)
|
||||||
|
.to(collection(), clazz());
|
||||||
|
|
||||||
|
return wrap(hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract String collection();
|
||||||
|
|
||||||
|
abstract Class<? extends GHHook[]> collectionClass();
|
||||||
|
|
||||||
|
abstract Class<? extends GHHook> clazz();
|
||||||
|
|
||||||
|
abstract GHHook wrap(GHHook hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RepoContext extends Context {
|
||||||
|
private final GHRepository repository;
|
||||||
|
private final GHUser owner;
|
||||||
|
|
||||||
|
private RepoContext(GHRepository repository, GHUser owner) {
|
||||||
|
super(repository.root);
|
||||||
|
this.repository = repository;
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String collection() {
|
||||||
|
return String.format("/repos/%s/%s/hooks", owner.getLogin(), repository.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Class<? extends GHHook[]> collectionClass() {
|
||||||
|
return GHRepoHook[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Class<? extends GHHook> clazz() {
|
||||||
|
return GHRepoHook.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GHHook wrap(GHHook hook) {
|
||||||
|
return ((GHRepoHook)hook).wrap(repository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class OrgContext extends Context {
|
||||||
|
private final GHOrganization organization;
|
||||||
|
|
||||||
|
private OrgContext(GHOrganization organization) {
|
||||||
|
super(organization.root);
|
||||||
|
this.organization = organization;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String collection() {
|
||||||
|
return String.format("/orgs/%s/hooks", organization.getLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Class<? extends GHHook[]> collectionClass() {
|
||||||
|
return GHOrgHook[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Class<? extends GHHook> clazz() {
|
||||||
|
return GHOrgHook.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GHHook wrap(GHHook hook) {
|
||||||
|
return ((GHOrgHook)hook).wrap(organization);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Context repoContext(GHRepository repository, GHUser owner) {
|
||||||
|
return new RepoContext(repository, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Context orgContext(GHOrganization organization) {
|
||||||
|
return new OrgContext(organization);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
|
|
||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -44,13 +47,14 @@ import java.util.Locale;
|
|||||||
public class GHIssue extends GHObject {
|
public class GHIssue extends GHObject {
|
||||||
GitHub root;
|
GitHub root;
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
|
|
||||||
// API v3
|
// API v3
|
||||||
protected GHUser assignee;
|
protected GHUser assignee;
|
||||||
protected String state;
|
protected String state;
|
||||||
protected int number;
|
protected int number;
|
||||||
protected String closed_at;
|
protected String closed_at;
|
||||||
protected int comments;
|
protected int comments;
|
||||||
|
@SkipFromToString
|
||||||
protected String body;
|
protected String body;
|
||||||
// for backward compatibility with < 1.63, this collection needs to hold instances of Label, not GHLabel
|
// for backward compatibility with < 1.63, this collection needs to hold instances of Label, not GHLabel
|
||||||
protected List<Label> labels;
|
protected List<Label> labels;
|
||||||
@@ -74,9 +78,9 @@ public class GHIssue extends GHObject {
|
|||||||
|
|
||||||
/*package*/ GHIssue wrap(GitHub root) {
|
/*package*/ GHIssue wrap(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
if(assignee != null) assignee.wrapUp(root);
|
if(assignee != null) assignee.wrapUp(root);
|
||||||
if(user != null) user.wrapUp(root);
|
if(user != null) user.wrapUp(root);
|
||||||
if(closed_by != null) closed_by.wrapUp(root);
|
if(closed_by != null) closed_by.wrapUp(root);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,15 +138,20 @@ public class GHIssue extends GHObject {
|
|||||||
return GitHub.parseDate(closed_at);
|
return GitHub.parseDate(closed_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getApiURL(){
|
public URL getApiURL(){
|
||||||
return GitHub.parseURL(url);
|
return GitHub.parseURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the issue by adding a comment.
|
* Updates the issue by adding a comment.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Newly posted comment.
|
||||||
*/
|
*/
|
||||||
public void comment(String message) throws IOException {
|
@WithBridgeMethods(void.class)
|
||||||
new Requester(root).with("body",message).to(getIssuesApiRoute() + "/comments");
|
public GHIssueComment comment(String message) throws IOException {
|
||||||
|
GHIssueComment r = new Requester(root).with("body",message).to(getIssuesApiRoute() + "/comments", GHIssueComment.class);
|
||||||
|
return r.wrapUp(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void edit(String key, Object value) throws IOException {
|
private void edit(String key, Object value) throws IOException {
|
||||||
@@ -176,7 +185,7 @@ public class GHIssue extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void assignTo(GHUser user) throws IOException {
|
public void assignTo(GHUser user) throws IOException {
|
||||||
editIssue("assignee",user.getLogin());
|
editIssue("assignee", user.getLogin());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLabels(String... labels) throws IOException {
|
public void setLabels(String... labels) throws IOException {
|
||||||
@@ -185,20 +194,20 @@ public class GHIssue extends GHObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains all the comments associated with this issue.
|
* Obtains all the comments associated with this issue.
|
||||||
*
|
*
|
||||||
* @see #listComments()
|
* @see #listComments()
|
||||||
|
*/
|
||||||
|
public List<GHIssueComment> getComments() throws IOException {
|
||||||
|
return listComments().asList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains all the comments associated with this issue.
|
||||||
*/
|
*/
|
||||||
public List<GHIssueComment> getComments() throws IOException {
|
|
||||||
return listComments().asList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains all the comments associated with this issue.
|
|
||||||
*/
|
|
||||||
public PagedIterable<GHIssueComment> listComments() throws IOException {
|
public PagedIterable<GHIssueComment> listComments() throws IOException {
|
||||||
return new PagedIterable<GHIssueComment>() {
|
return new PagedIterable<GHIssueComment>() {
|
||||||
public PagedIterator<GHIssueComment> iterator() {
|
public PagedIterator<GHIssueComment> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHIssueComment>(root.retrieve().asIterator(getIssuesApiRoute() + "/comments", GHIssueComment[].class)) {
|
return new PagedIterator<GHIssueComment>(root.retrieve().asIterator(getIssuesApiRoute() + "/comments", GHIssueComment[].class, pageSize)) {
|
||||||
protected void wrapUp(GHIssueComment[] page) {
|
protected void wrapUp(GHIssueComment[] page) {
|
||||||
for (GHIssueComment c : page)
|
for (GHIssueComment c : page)
|
||||||
c.wrapUp(GHIssue.this);
|
c.wrapUp(GHIssue.this);
|
||||||
@@ -216,16 +225,16 @@ public class GHIssue extends GHObject {
|
|||||||
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/issues/"+number;
|
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/issues/"+number;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHUser getAssignee() {
|
public GHUser getAssignee() {
|
||||||
return assignee;
|
return assignee;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User who submitted the issue.
|
* User who submitted the issue.
|
||||||
*/
|
*/
|
||||||
public GHUser getUser() {
|
public GHUser getUser() {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports who has closed the issue.
|
* Reports who has closed the issue.
|
||||||
@@ -235,46 +244,48 @@ public class GHIssue extends GHObject {
|
|||||||
* even for an issue that's already closed. See
|
* even for an issue that's already closed. See
|
||||||
* https://github.com/kohsuke/github-api/issues/60.
|
* https://github.com/kohsuke/github-api/issues/60.
|
||||||
*/
|
*/
|
||||||
public GHUser getClosedBy() {
|
public GHUser getClosedBy() {
|
||||||
if(!"closed".equals(state)) return null;
|
if(!"closed".equals(state)) return null;
|
||||||
if(closed_by != null) return closed_by;
|
if(closed_by != null) return closed_by;
|
||||||
|
|
||||||
//TODO closed_by = owner.getIssue(number).getClosed_by();
|
//TODO closed_by = owner.getIssue(number).getClosed_by();
|
||||||
return closed_by;
|
return closed_by;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCommentsCount(){
|
public int getCommentsCount(){
|
||||||
return comments;
|
return comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns non-null if this issue is a shadow of a pull request.
|
* Returns non-null if this issue is a shadow of a pull request.
|
||||||
*/
|
*/
|
||||||
public PullRequest getPullRequest() {
|
public PullRequest getPullRequest() {
|
||||||
return pull_request;
|
return pull_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPullRequest() {
|
public boolean isPullRequest() {
|
||||||
return pull_request!=null;
|
return pull_request!=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHMilestone getMilestone() {
|
public GHMilestone getMilestone() {
|
||||||
return milestone;
|
return milestone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PullRequest{
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
|
||||||
private String diff_url, patch_url, html_url;
|
justification = "JSON API")
|
||||||
|
public static class PullRequest{
|
||||||
public URL getDiffUrl() {
|
private String diff_url, patch_url, html_url;
|
||||||
return GitHub.parseURL(diff_url);
|
|
||||||
}
|
public URL getDiffUrl() {
|
||||||
|
return GitHub.parseURL(diff_url);
|
||||||
public URL getPatchUrl() {
|
}
|
||||||
return GitHub.parseURL(patch_url);
|
|
||||||
}
|
public URL getPatchUrl() {
|
||||||
|
return GitHub.parseURL(patch_url);
|
||||||
public URL getUrl() {
|
}
|
||||||
return GitHub.parseURL(html_url);
|
|
||||||
}
|
public URL getUrl() {
|
||||||
}
|
return GitHub.parseURL(html_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comment to the issue
|
* Comment to the issue
|
||||||
@@ -71,4 +70,31 @@ public class GHIssueComment extends GHObject {
|
|||||||
public GHUser getUser() throws IOException {
|
public GHUser getUser() throws IOException {
|
||||||
return owner.root.getUser(user.getLogin());
|
return owner.root.getUser(user.getLogin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the body of the issue comment.
|
||||||
|
*/
|
||||||
|
public void update(String body) throws IOException {
|
||||||
|
new Requester(owner.root).with("body", body).method("PATCH").to(getApiRoute(), GHIssueComment.class);
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes this issue comment.
|
||||||
|
*/
|
||||||
|
public void delete() throws IOException {
|
||||||
|
new Requester(owner.root).method("DELETE").to(getApiRoute());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getApiRoute() {
|
||||||
|
return "/repos/"+owner.getRepository().getOwnerName()+"/"+owner.getRepository().getName()+"/issues/comments/" + id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class GHIssueSearchBuilder extends GHSearchBuilder<GHIssue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHIssueSearchBuilder sort(Sort sort) {
|
public GHIssueSearchBuilder sort(Sort sort) {
|
||||||
req.with("sort",sort.toString().toLowerCase(Locale.ENGLISH));
|
req.with("sort",sort);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,11 @@
|
|||||||
|
|
||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see GHPullRequestQueryBuilder#state(GHIssueState)
|
||||||
|
*/
|
||||||
public enum GHIssueState {
|
public enum GHIssueState {
|
||||||
OPEN,
|
OPEN,
|
||||||
CLOSED
|
CLOSED,
|
||||||
|
ALL
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,6 +8,7 @@ import org.apache.commons.lang.builder.ToStringBuilder;
|
|||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||||
public class GHKey {
|
public class GHKey {
|
||||||
/*package almost final*/ GitHub root;
|
/*package almost final*/ GitHub root;
|
||||||
|
|
||||||
@@ -33,6 +35,10 @@ public class GHKey {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GitHub getRoot() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isVerified() {
|
public boolean isVerified() {
|
||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -11,60 +12,79 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public class GHMilestone extends GHObject {
|
public class GHMilestone extends GHObject {
|
||||||
GitHub root;
|
GitHub root;
|
||||||
GHRepository owner;
|
GHRepository owner;
|
||||||
|
|
||||||
GHUser creator;
|
GHUser creator;
|
||||||
private String state, due_on, title, description;
|
private String state, due_on, title, description, html_url;
|
||||||
private int closed_issues, open_issues, number;
|
private int closed_issues, open_issues, number;
|
||||||
|
protected String closed_at;
|
||||||
|
|
||||||
public GitHub getRoot() {
|
public GitHub getRoot() {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHRepository getOwner() {
|
public GHRepository getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHUser getCreator() {
|
public GHUser getCreator() {
|
||||||
return creator;
|
return creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getDueOn() {
|
public Date getDueOn() {
|
||||||
if (due_on == null) return null;
|
if (due_on == null) return null;
|
||||||
return GitHub.parseDate(due_on);
|
return GitHub.parseDate(due_on);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getClosedIssues() {
|
|
||||||
return closed_issues;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOpenIssues() {
|
|
||||||
return open_issues;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNumber() {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GHMilestoneState getState() {
|
|
||||||
return Enum.valueOf(GHMilestoneState.class, state.toUpperCase(Locale.ENGLISH));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes this issue.
|
* When was this milestone closed?
|
||||||
|
*/
|
||||||
|
public Date getClosedAt() throws IOException {
|
||||||
|
return GitHub.parseDate(closed_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClosedIssues() {
|
||||||
|
return closed_issues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOpenIssues() {
|
||||||
|
return open_issues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHMilestoneState getState() {
|
||||||
|
return Enum.valueOf(GHMilestoneState.class, state.toUpperCase(Locale.ENGLISH));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes this milestone.
|
||||||
*/
|
*/
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
edit("state", "closed");
|
edit("state", "closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reopens this milestone.
|
||||||
|
*/
|
||||||
|
public void reopen() throws IOException {
|
||||||
|
edit("state", "open");
|
||||||
|
}
|
||||||
|
|
||||||
private void edit(String key, Object value) throws IOException {
|
private void edit(String key, Object value) throws IOException {
|
||||||
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
|
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
|
||||||
}
|
}
|
||||||
@@ -73,9 +93,9 @@ public class GHMilestone extends GHObject {
|
|||||||
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/milestones/"+number;
|
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/milestones/"+number;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHMilestone wrap(GHRepository repo) {
|
public GHMilestone wrap(GHRepository repo) {
|
||||||
this.owner = repo;
|
this.owner = repo;
|
||||||
this.root = repo.root;
|
this.root = repo.root;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@@ -17,6 +17,33 @@ import java.util.TreeMap;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public class GHMyself extends GHUser {
|
public class GHMyself extends GHUser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of repositories returned during listing.
|
||||||
|
*/
|
||||||
|
public enum RepositoryListFilter {
|
||||||
|
/**
|
||||||
|
* All public and private repositories that current user has access or collaborates to
|
||||||
|
*/
|
||||||
|
ALL,
|
||||||
|
/**
|
||||||
|
* Public and private repositories owned by current user
|
||||||
|
*/
|
||||||
|
OWNER,
|
||||||
|
/**
|
||||||
|
* Public repositories that current user has access or collaborates to
|
||||||
|
*/
|
||||||
|
PUBLIC,
|
||||||
|
/**
|
||||||
|
* Private repositories that current user has access or collaborates to
|
||||||
|
*/
|
||||||
|
PRIVATE,
|
||||||
|
/**
|
||||||
|
* Public and private repositories that current user is a member
|
||||||
|
*/
|
||||||
|
MEMBER;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
* Use {@link #getEmails2()}
|
* Use {@link #getEmails2()}
|
||||||
@@ -109,16 +136,30 @@ public class GHMyself extends GHUser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists up all the repositories this user owns (public and private) using the specified page size.
|
* List repositories that are accessible to the authenticated user (public and private) using the specified page size.
|
||||||
|
*
|
||||||
|
* This includes repositories owned by the authenticated user, repositories that belong to other users
|
||||||
|
* where the authenticated user is a collaborator, and other organizations' repositories that the authenticated
|
||||||
|
* user has access to through an organization membership.
|
||||||
*
|
*
|
||||||
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
|
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
|
||||||
*
|
*
|
||||||
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
|
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
||||||
|
return listRepositories(pageSize, RepositoryListFilter.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List repositories of a certain type that are accessible by current authenticated user using the specified page size.
|
||||||
|
*
|
||||||
|
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
|
||||||
|
* @param repoType type of repository returned in the listing
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHRepository> listRepositories(final int pageSize, final RepositoryListFilter repoType) {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/user/repos?per_page=" + pageSize, GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(root.retrieve().with("type",repoType).asIterator("/user/repos", GHRepository[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository c : page)
|
for (GHRepository c : page)
|
||||||
@@ -126,7 +167,7 @@ public class GHMyself extends GHUser {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
}.withPageSize(pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class GHNotificationStream implements Iterable<GHThread> {
|
|||||||
while (true) {
|
while (true) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (nextCheckTime < now) break;
|
if (nextCheckTime < now) break;
|
||||||
long waitTime = Math.max(Math.min(nextCheckTime - now, 1000), 60 * 1000);
|
long waitTime = Math.min(Math.max(nextCheckTime - now, 1000), 60 * 1000);
|
||||||
Thread.sleep(waitTime);
|
Thread.sleep(waitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +180,8 @@ public class GHNotificationStream implements Iterable<GHThread> {
|
|||||||
private long calcNextCheckTime() {
|
private long calcNextCheckTime() {
|
||||||
String v = req.getResponseHeader("X-Poll-Interval");
|
String v = req.getResponseHeader("X-Poll-Interval");
|
||||||
if (v==null) v="60";
|
if (v==null) v="60";
|
||||||
return System.currentTimeMillis()+Integer.parseInt(v)*1000;
|
long seconds = Integer.parseInt(v);
|
||||||
|
return System.currentTimeMillis() + seconds*1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
|
||||||
|
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||||
|
import org.apache.commons.lang.builder.ToStringStyle;
|
||||||
|
import org.apache.commons.lang.reflect.FieldUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Most (all?) domain objects in GitHub seems to have these 4 properties.
|
* Most (all?) domain objects in GitHub seems to have these 4 properties.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public abstract class GHObject {
|
public abstract class GHObject {
|
||||||
protected String url;
|
protected String url;
|
||||||
protected int id;
|
protected int id;
|
||||||
@@ -26,6 +34,7 @@ public abstract class GHObject {
|
|||||||
return GitHub.parseDate(created_at);
|
return GitHub.parseDate(created_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getCreatedAt")
|
||||||
private Object createdAtStr(Date id, Class type) {
|
private Object createdAtStr(Date id, Class type) {
|
||||||
return created_at;
|
return created_at;
|
||||||
}
|
}
|
||||||
@@ -38,6 +47,12 @@ public abstract class GHObject {
|
|||||||
return GitHub.parseURL(url);
|
return GitHub.parseURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL of this object for humans, which renders some HTML.
|
||||||
|
*/
|
||||||
|
@WithBridgeMethods(value=String.class, adapterMethod="urlToString")
|
||||||
|
public abstract URL getHtmlUrl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When was this resource last updated?
|
* When was this resource last updated?
|
||||||
*/
|
*/
|
||||||
@@ -53,11 +68,48 @@ public abstract class GHObject {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getId")
|
||||||
private Object intToString(int id, Class type) {
|
private Object intToString(int id, Class type) {
|
||||||
return String.valueOf(id);
|
return String.valueOf(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getHtmlUrl")
|
||||||
private Object urlToString(URL url, Class type) {
|
private Object urlToString(URL url, Class type) {
|
||||||
return url==null ? null : url.toString();
|
return url==null ? null : url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String representation to assist debugging and inspection. The output format of this string
|
||||||
|
* is not a committed part of the API and is subject to change.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ReflectionToStringBuilder(this, TOSTRING_STYLE, null, null, false, false) {
|
||||||
|
@Override
|
||||||
|
protected boolean accept(Field field) {
|
||||||
|
return super.accept(field) && !field.isAnnotationPresent(SkipFromToString.class);
|
||||||
|
}
|
||||||
|
}.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ToStringStyle TOSTRING_STYLE = new ToStringStyle() {
|
||||||
|
{
|
||||||
|
this.setUseShortClassName(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
|
||||||
|
// skip unimportant properties. '_' is a heuristics as important properties tend to have short names
|
||||||
|
if (fieldName.contains("_"))
|
||||||
|
return;
|
||||||
|
// avoid recursing other GHObject
|
||||||
|
if (value instanceof GHObject)
|
||||||
|
return;
|
||||||
|
// likewise no point in showing root
|
||||||
|
if (value instanceof GitHub)
|
||||||
|
return;
|
||||||
|
|
||||||
|
super.append(buffer,fieldName,value,fullDetail);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/main/java/org/kohsuke/github/GHOrgHook.java
Normal file
27
src/main/java/org/kohsuke/github/GHOrgHook.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* © Copyright 2015 - SourceClear Inc
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
class GHOrgHook extends GHHook {
|
||||||
|
/**
|
||||||
|
* Organization that the hook belongs to.
|
||||||
|
*/
|
||||||
|
/*package*/ transient GHOrganization organization;
|
||||||
|
|
||||||
|
/*package*/ GHOrgHook wrap(GHOrganization owner) {
|
||||||
|
this.organization = owner;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GitHub getRoot() {
|
||||||
|
return organization.root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getApiRoute() {
|
||||||
|
return String.format("/orgs/%s/hooks/%d", organization.getLogin(), id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@@ -21,21 +23,35 @@ public class GHOrganization extends GHPerson {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* Newly created repository.
|
* Newly created repository.
|
||||||
|
* @deprecated
|
||||||
|
* Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
|
||||||
*/
|
*/
|
||||||
public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException {
|
public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException {
|
||||||
GHTeam t = getTeams().get(team);
|
GHTeam t = getTeams().get(team);
|
||||||
if (t==null)
|
if (t==null)
|
||||||
throw new IllegalArgumentException("No such team: "+team);
|
throw new IllegalArgumentException("No such team: "+team);
|
||||||
return createRepository(name,description,homepage,t,isPublic);
|
return createRepository(name, description, homepage, t, isPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
|
||||||
|
*/
|
||||||
public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
|
public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
|
||||||
if (team==null)
|
if (team==null)
|
||||||
throw new IllegalArgumentException("Invalid team");
|
throw new IllegalArgumentException("Invalid team");
|
||||||
// such API doesn't exist, so fall back to HTML scraping
|
return createRepository(name).description(description).homepage(homepage).private_(!isPublic).team(team).create();
|
||||||
return new Requester(root)
|
}
|
||||||
.with("name", name).with("description", description).with("homepage", homepage)
|
|
||||||
.with("public", isPublic).with("team_id",team.getId()).to("/orgs/"+login+"/repos", GHRepository.class).wrap(root);
|
/**
|
||||||
|
* Starts a builder that creates a new repository.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()}
|
||||||
|
* to finally createa repository.
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder createRepository(String name) throws IOException {
|
||||||
|
return new GHCreateRepositoryBuilder(root,"/orgs/"+login+"/repos",name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,8 +70,8 @@ public class GHOrganization extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHTeam> listTeams() throws IOException {
|
public PagedIterable<GHTeam> listTeams() throws IOException {
|
||||||
return new PagedIterable<GHTeam>() {
|
return new PagedIterable<GHTeam>() {
|
||||||
public PagedIterator<GHTeam> iterator() {
|
public PagedIterator<GHTeam> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHTeam>(root.retrieve().asIterator(String.format("/orgs/%s/teams", login), GHTeam[].class)) {
|
return new PagedIterator<GHTeam>(root.retrieve().asIterator(String.format("/orgs/%s/teams", login), GHTeam[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHTeam[] page) {
|
protected void wrapUp(GHTeam[] page) {
|
||||||
for (GHTeam c : page)
|
for (GHTeam c : page)
|
||||||
@@ -77,6 +93,17 @@ public class GHOrganization extends GHPerson {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a team that has the given slug in its {@link GHTeam#getSlug()}
|
||||||
|
*/
|
||||||
|
public GHTeam getTeamBySlug(String slug) throws IOException {
|
||||||
|
for (GHTeam t : listTeams()) {
|
||||||
|
if(t.getSlug().equals(slug))
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this organization has the specified user as a member.
|
* Checks if this organization has the specified user as a member.
|
||||||
*/
|
*/
|
||||||
@@ -147,9 +174,9 @@ public class GHOrganization extends GHPerson {
|
|||||||
|
|
||||||
private PagedIterable<GHUser> listMembers(final String suffix, final String filter) throws IOException {
|
private PagedIterable<GHUser> listMembers(final String suffix, final String filter) throws IOException {
|
||||||
return new PagedIterable<GHUser>() {
|
return new PagedIterable<GHUser>() {
|
||||||
public PagedIterator<GHUser> iterator() {
|
public PagedIterator<GHUser> _iterator(int pageSize) {
|
||||||
String filterParams = (filter == null) ? "" : ("?filter=" + filter);
|
String filterParams = (filter == null) ? "" : ("?filter=" + filter);
|
||||||
return new PagedIterator<GHUser>(root.retrieve().asIterator(String.format("/orgs/%s/%s%s", login, suffix, filterParams), GHUser[].class)) {
|
return new PagedIterator<GHUser>(root.retrieve().asIterator(String.format("/orgs/%s/%s%s", login, suffix, filterParams), GHUser[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHUser[] users) {
|
protected void wrapUp(GHUser[] users) {
|
||||||
GHUser.wrap(users, root);
|
GHUser.wrap(users, root);
|
||||||
@@ -172,7 +199,7 @@ public class GHOrganization extends GHPerson {
|
|||||||
* Creates a new team and assigns the repositories.
|
* Creates a new team and assigns the repositories.
|
||||||
*/
|
*/
|
||||||
public GHTeam createTeam(String name, Permission p, Collection<GHRepository> repositories) throws IOException {
|
public GHTeam createTeam(String name, Permission p, Collection<GHRepository> repositories) throws IOException {
|
||||||
Requester post = new Requester(root).with("name", name).with("permission", p.name().toLowerCase());
|
Requester post = new Requester(root).with("name", name).with("permission", p);
|
||||||
List<String> repo_names = new ArrayList<String>();
|
List<String> repo_names = new ArrayList<String>();
|
||||||
for (GHRepository r : repositories) {
|
for (GHRepository r : repositories) {
|
||||||
repo_names.add(r.getName());
|
repo_names.add(r.getName());
|
||||||
@@ -182,7 +209,7 @@ public class GHOrganization extends GHPerson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException {
|
public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException {
|
||||||
return createTeam(name,p, Arrays.asList(repositories));
|
return createTeam(name, p, Arrays.asList(repositories));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,8 +246,8 @@ public class GHOrganization extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
||||||
return new PagedIterable<GHEventInfo>() {
|
return new PagedIterable<GHEventInfo>() {
|
||||||
public PagedIterator<GHEventInfo> iterator() {
|
public PagedIterator<GHEventInfo> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/orgs/%s/events", login), GHEventInfo[].class)) {
|
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/orgs/%s/events", login), GHEventInfo[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHEventInfo[] page) {
|
protected void wrapUp(GHEventInfo[] page) {
|
||||||
for (GHEventInfo c : page)
|
for (GHEventInfo c : page)
|
||||||
@@ -241,8 +268,8 @@ public class GHOrganization extends GHPerson {
|
|||||||
@Override
|
@Override
|
||||||
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/orgs/" + login + "/repos?per_page=" + pageSize, GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/orgs/" + login + "/repos?per_page=" + pageSize, GHRepository[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository c : page)
|
for (GHRepository c : page)
|
||||||
@@ -252,4 +279,39 @@ public class GHOrganization extends GHPerson {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the currently configured hooks.
|
||||||
|
*/
|
||||||
|
public List<GHHook> getHooks() throws IOException {
|
||||||
|
return GHHooks.orgContext(this).getHooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHHook getHook(int id) throws IOException {
|
||||||
|
return GHHooks.orgContext(this).getHook(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* See https://api.github.com/hooks for possible names and their configuration scheme.
|
||||||
|
* TODO: produce type-safe binding
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
|
||||||
|
* @param config
|
||||||
|
* The configuration hash.
|
||||||
|
* @param events
|
||||||
|
* Can be null. Types of events to hook into.
|
||||||
|
*/
|
||||||
|
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
|
||||||
|
return GHHooks.orgContext(this).createHook(name, config, events, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
|
||||||
|
return createHook("web", Collections.singletonMap("url", url.toExternalForm()),events,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHHook createWebHook(URL url) throws IOException {
|
||||||
|
return createWebHook(url, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -75,8 +76,8 @@ public abstract class GHPerson extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize, GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize, GHRepository[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository c : page)
|
for (GHRepository c : page)
|
||||||
@@ -103,7 +104,7 @@ public abstract class GHPerson extends GHObject {
|
|||||||
public synchronized Iterable<List<GHRepository>> iterateRepositories(final int pageSize) {
|
public synchronized Iterable<List<GHRepository>> iterateRepositories(final int pageSize) {
|
||||||
return new Iterable<List<GHRepository>>() {
|
return new Iterable<List<GHRepository>>() {
|
||||||
public Iterator<List<GHRepository>> iterator() {
|
public Iterator<List<GHRepository>> iterator() {
|
||||||
final Iterator<GHRepository[]> pager = root.retrieve().asIterator("/users/" + login + "/repos?per_page="+pageSize,GHRepository[].class);
|
final Iterator<GHRepository[]> pager = root.retrieve().asIterator("/users/" + login + "/repos?per_page="+pageSize,GHRepository[].class, pageSize);
|
||||||
|
|
||||||
return new Iterator<List<GHRepository>>() {
|
return new Iterator<List<GHRepository>>() {
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
@@ -203,7 +204,7 @@ public abstract class GHPerson extends GHObject {
|
|||||||
|
|
||||||
public Date getUpdatedAt() throws IOException {
|
public Date getUpdatedAt() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return super.getCreatedAt();
|
return super.getUpdatedAt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,8 +215,9 @@ public abstract class GHPerson extends GHObject {
|
|||||||
return blog;
|
return blog;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHtmlUrl() {
|
@Override
|
||||||
return html_url;
|
public URL getHtmlUrl() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import java.util.HashSet;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public class GHPersonSet<T extends GHPerson> extends HashSet<T> {
|
public class GHPersonSet<T extends GHPerson> extends HashSet<T> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public GHPersonSet() {
|
public GHPersonSet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.io.IOException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pull request.
|
* A pull request.
|
||||||
@@ -37,20 +36,21 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings({"UnusedDeclaration"})
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
public class GHPullRequest extends GHIssue {
|
public class GHPullRequest extends GHIssue {
|
||||||
|
|
||||||
private String patch_url, diff_url, issue_url;
|
private String patch_url, diff_url, issue_url;
|
||||||
private GHCommitPointer base;
|
private GHCommitPointer base;
|
||||||
private String merged_at;
|
private String merged_at;
|
||||||
private GHCommitPointer head;
|
private GHCommitPointer head;
|
||||||
|
|
||||||
// details that are only available when obtained from ID
|
// details that are only available when obtained from ID
|
||||||
private GHUser merged_by;
|
private GHUser merged_by;
|
||||||
private int review_comments, additions;
|
private int review_comments, additions;
|
||||||
private boolean merged;
|
private boolean merged;
|
||||||
private Boolean mergeable;
|
private Boolean mergeable;
|
||||||
private int deletions;
|
private int deletions;
|
||||||
private String mergeable_state;
|
private String mergeable_state;
|
||||||
private int changed_files;
|
private int changed_files;
|
||||||
|
private String merge_commit_sha;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GitHub doesn't return some properties of {@link GHIssue} when requesting the GET on the 'pulls' API
|
* GitHub doesn't return some properties of {@link GHIssue} when requesting the GET on the 'pulls' API
|
||||||
@@ -60,15 +60,15 @@ public class GHPullRequest extends GHIssue {
|
|||||||
private transient boolean fetchedIssueDetails;
|
private transient boolean fetchedIssueDetails;
|
||||||
|
|
||||||
|
|
||||||
GHPullRequest wrapUp(GHRepository owner) {
|
GHPullRequest wrapUp(GHRepository owner) {
|
||||||
this.wrap(owner);
|
this.wrap(owner);
|
||||||
return wrapUp(owner.root);
|
return wrapUp(owner.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
GHPullRequest wrapUp(GitHub root) {
|
GHPullRequest wrapUp(GitHub root) {
|
||||||
if (owner!=null) owner.wrap(root);
|
if (owner != null) owner.wrap(root);
|
||||||
if (base!=null) base.wrapUp(root);
|
if (base != null) base.wrapUp(root);
|
||||||
if (head!=null) head.wrapUp(root);
|
if (head != null) head.wrapUp(root);
|
||||||
if (merged_by != null) merged_by.wrapUp(root);
|
if (merged_by != null) merged_by.wrapUp(root);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -85,8 +85,8 @@ public class GHPullRequest extends GHIssue {
|
|||||||
public URL getPatchUrl() {
|
public URL getPatchUrl() {
|
||||||
return GitHub.parseURL(patch_url);
|
return GitHub.parseURL(patch_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL of the patch file.
|
* The URL of the patch file.
|
||||||
* like https://github.com/jenkinsci/jenkins/pull/100.patch
|
* like https://github.com/jenkinsci/jenkins/pull/100.patch
|
||||||
*/
|
*/
|
||||||
@@ -108,8 +108,8 @@ public class GHPullRequest extends GHIssue {
|
|||||||
public GHCommitPointer getHead() {
|
public GHCommitPointer getHead() {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Date getIssueUpdatedAt() throws IOException {
|
public Date getIssueUpdatedAt() throws IOException {
|
||||||
return super.getUpdatedAt();
|
return super.getUpdatedAt();
|
||||||
}
|
}
|
||||||
@@ -126,65 +126,73 @@ public class GHPullRequest extends GHIssue {
|
|||||||
return GitHub.parseDate(merged_at);
|
return GitHub.parseDate(merged_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<GHLabel> getLabels() throws IOException {
|
public Collection<GHLabel> getLabels() throws IOException {
|
||||||
fetchIssue();
|
fetchIssue();
|
||||||
return super.getLabels();
|
return super.getLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GHUser getClosedBy() {
|
public GHUser getClosedBy() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PullRequest getPullRequest() {
|
public PullRequest getPullRequest() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// details that are only available via get with ID
|
||||||
|
//
|
||||||
|
|
||||||
//
|
|
||||||
// details that are only available via get with ID
|
|
||||||
//
|
|
||||||
//
|
|
||||||
public GHUser getMergedBy() throws IOException {
|
public GHUser getMergedBy() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return merged_by;
|
return merged_by;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getReviewComments() throws IOException {
|
public int getReviewComments() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return review_comments;
|
return review_comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAdditions() throws IOException {
|
public int getAdditions() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return additions;
|
return additions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMerged() throws IOException {
|
public boolean isMerged() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getMergeable() throws IOException {
|
public Boolean getMergeable() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return mergeable;
|
return mergeable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDeletions() throws IOException {
|
public int getDeletions() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return deletions;
|
return deletions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMergeableState() throws IOException {
|
public String getMergeableState() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return mergeable_state;
|
return mergeable_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChangedFiles() throws IOException {
|
public int getChangedFiles() throws IOException {
|
||||||
populate();
|
populate();
|
||||||
return changed_files;
|
return changed_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See <a href="https://developer.github.com/changes/2013-04-25-deprecating-merge-commit-sha">GitHub blog post</a>
|
||||||
|
*/
|
||||||
|
public String getMergeCommitSha() throws IOException {
|
||||||
|
populate();
|
||||||
|
return merge_commit_sha;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fully populate the data by retrieving missing data.
|
* Fully populate the data by retrieving missing data.
|
||||||
@@ -200,20 +208,64 @@ public class GHPullRequest extends GHIssue {
|
|||||||
/**
|
/**
|
||||||
* Retrieves all the commits associated to this pull request.
|
* Retrieves all the commits associated to this pull request.
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHPullRequestCommitDetail> listCommits() {
|
public PagedIterable<GHPullRequestFileDetail> listFiles() {
|
||||||
return new PagedIterable<GHPullRequestCommitDetail>() {
|
return new PagedIterable<GHPullRequestFileDetail>() {
|
||||||
public PagedIterator<GHPullRequestCommitDetail> iterator() {
|
public PagedIterator<GHPullRequestFileDetail> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHPullRequestCommitDetail>(root.retrieve().asIterator(
|
return new PagedIterator<GHPullRequestFileDetail>(root.retrieve().asIterator(String.format("%s/files", getApiURL()),
|
||||||
String.format("%s/commits", getApiURL()),
|
GHPullRequestFileDetail[].class, pageSize)) {
|
||||||
GHPullRequestCommitDetail[].class)) {
|
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHPullRequestCommitDetail[] page) {
|
protected void wrapUp(GHPullRequestFileDetail[] page) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains all the review comments associated with this pull request.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
|
||||||
|
return new PagedIterable<GHPullRequestReviewComment>() {
|
||||||
|
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
|
||||||
|
return new PagedIterator<GHPullRequestReviewComment>(root.retrieve().asIterator(getApiRoute() + "/comments",
|
||||||
|
GHPullRequestReviewComment[].class, pageSize)) {
|
||||||
|
protected void wrapUp(GHPullRequestReviewComment[] page) {
|
||||||
|
for (GHPullRequestReviewComment c : page)
|
||||||
|
c.wrapUp(GHPullRequest.this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all the commits associated to this pull request.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHPullRequestCommitDetail> listCommits() {
|
||||||
|
return new PagedIterable<GHPullRequestCommitDetail>() {
|
||||||
|
public PagedIterator<GHPullRequestCommitDetail> _iterator(int pageSize) {
|
||||||
|
return new PagedIterator<GHPullRequestCommitDetail>(root.retrieve().asIterator(
|
||||||
|
String.format("%s/commits", getApiURL()),
|
||||||
|
GHPullRequestCommitDetail[].class, pageSize)) {
|
||||||
|
@Override
|
||||||
|
protected void wrapUp(GHPullRequestCommitDetail[] page) {
|
||||||
|
for (GHPullRequestCommitDetail c : page)
|
||||||
|
c.wrapUp(GHPullRequest.this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position) throws IOException {
|
||||||
|
return new Requester(root).method("POST")
|
||||||
|
.with("body", body)
|
||||||
|
.with("commit_id", sha)
|
||||||
|
.with("path", path)
|
||||||
|
.with("position", position)
|
||||||
|
.to(getApiRoute() + "/comments", GHPullRequestReviewComment.class).wrapUp(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge this pull request.
|
* Merge this pull request.
|
||||||
*
|
*
|
||||||
@@ -223,7 +275,21 @@ public class GHPullRequest extends GHIssue {
|
|||||||
* Commit message. If null, the default one will be used.
|
* Commit message. If null, the default one will be used.
|
||||||
*/
|
*/
|
||||||
public void merge(String msg) throws IOException {
|
public void merge(String msg) throws IOException {
|
||||||
new Requester(root).method("PUT").with("commit_message",msg).to(getApiRoute()+"/merge");
|
merge(msg,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge this pull request.
|
||||||
|
*
|
||||||
|
* The equivalent of the big green "Merge pull request" button.
|
||||||
|
*
|
||||||
|
* @param msg
|
||||||
|
* Commit message. If null, the default one will be used.
|
||||||
|
* @param sha
|
||||||
|
* SHA that pull request head must match to allow merge.
|
||||||
|
*/
|
||||||
|
public void merge(String msg, String sha) throws IOException {
|
||||||
|
new Requester(root).method("PUT").with("commit_message",msg).with("sha",sha).to(getApiRoute()+"/merge");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchIssue() throws IOException {
|
private void fetchIssue() throws IOException {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
@@ -31,99 +32,119 @@ import java.net.URL;
|
|||||||
* Commit detail inside a {@link GHPullRequest}.
|
* Commit detail inside a {@link GHPullRequest}.
|
||||||
*
|
*
|
||||||
* @author Luca Milanesio
|
* @author Luca Milanesio
|
||||||
|
* @see GHPullRequest#listCommits()
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
|
||||||
public class GHPullRequestCommitDetail {
|
public class GHPullRequestCommitDetail {
|
||||||
|
private GHPullRequest owner;
|
||||||
|
|
||||||
|
/*package*/ void wrapUp(GHPullRequest owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link GitUser}
|
* @deprecated Use {@link GitUser}
|
||||||
*/
|
*/
|
||||||
public static class Authorship extends GitUser {}
|
public static class Authorship extends GitUser {
|
||||||
|
}
|
||||||
|
|
||||||
public static class Tree {
|
public static class Tree {
|
||||||
|
String sha;
|
||||||
|
String url;
|
||||||
|
|
||||||
|
public String getSha() {
|
||||||
|
return sha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
return GitHub.parseURL(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Commit {
|
||||||
|
Authorship author;
|
||||||
|
Authorship committer;
|
||||||
|
String message;
|
||||||
|
Tree tree;
|
||||||
|
String url;
|
||||||
|
int comment_count;
|
||||||
|
|
||||||
|
@WithBridgeMethods(value = Authorship.class, castRequired = true)
|
||||||
|
public GitUser getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithBridgeMethods(value = Authorship.class, castRequired = true)
|
||||||
|
public GitUser getCommitter() {
|
||||||
|
return committer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
return GitHub.parseURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getComment_count() {
|
||||||
|
return comment_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tree getTree() {
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CommitPointer {
|
||||||
|
String sha;
|
||||||
|
String url;
|
||||||
|
String html_url;
|
||||||
|
|
||||||
|
public URL getUrl() {
|
||||||
|
return GitHub.parseURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getHtml_url() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSha() {
|
||||||
|
return sha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String sha;
|
String sha;
|
||||||
String url;
|
Commit commit;
|
||||||
|
|
||||||
public String getSha() {
|
|
||||||
return sha;
|
|
||||||
}
|
|
||||||
|
|
||||||
public URL getUrl() {
|
|
||||||
return GitHub.parseURL(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Commit {
|
|
||||||
Authorship author;
|
|
||||||
Authorship committer;
|
|
||||||
String message;
|
|
||||||
Tree tree;
|
|
||||||
String url;
|
|
||||||
int comment_count;
|
|
||||||
|
|
||||||
@WithBridgeMethods(value=Authorship.class,castRequired=true)
|
|
||||||
public GitUser getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
@WithBridgeMethods(value=Authorship.class,castRequired=true)
|
|
||||||
public GitUser getCommitter() {
|
|
||||||
return committer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public URL getUrl() {
|
|
||||||
return GitHub.parseURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getComment_count() {
|
|
||||||
return comment_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CommitPointer {
|
|
||||||
String sha;
|
|
||||||
String url;
|
String url;
|
||||||
String html_url;
|
String html_url;
|
||||||
|
String comments_url;
|
||||||
public URL getUrl() {
|
CommitPointer[] parents;
|
||||||
return GitHub.parseURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public URL getHtml_url() {
|
|
||||||
return GitHub.parseURL(html_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSha() {
|
public String getSha() {
|
||||||
return sha;
|
return sha;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
String sha;
|
public Commit getCommit() {
|
||||||
Commit commit;
|
return commit;
|
||||||
String url;
|
}
|
||||||
String html_url;
|
|
||||||
String comments_url;
|
public URL getApiUrl() {
|
||||||
CommitPointer[] parents;
|
return GitHub.parseURL(url);
|
||||||
|
}
|
||||||
public String getSha() {
|
|
||||||
return sha;
|
public URL getUrl() {
|
||||||
}
|
return GitHub.parseURL(html_url);
|
||||||
public Commit getCommit() {
|
}
|
||||||
return commit;
|
|
||||||
}
|
public URL getCommentsUrl() {
|
||||||
public URL getApiUrl() {
|
return GitHub.parseURL(comments_url);
|
||||||
return GitHub.parseURL(url);
|
}
|
||||||
}
|
|
||||||
public URL getUrl() {
|
public CommitPointer[] getParents() {
|
||||||
return GitHub.parseURL(html_url);
|
CommitPointer[] newValue = new CommitPointer[parents.length];
|
||||||
}
|
System.arraycopy(parents, 0, newValue, 0, parents.length);
|
||||||
public URL getCommentsUrl() {
|
return newValue;
|
||||||
return GitHub.parseURL(comments_url);
|
}
|
||||||
}
|
|
||||||
public CommitPointer[] getParents() {
|
|
||||||
return parents;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015, Julien Henry
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File detail inside a {@link GHPullRequest}.
|
||||||
|
*
|
||||||
|
* @author Julien Henry
|
||||||
|
* @see GHPullRequest#listFiles()
|
||||||
|
*/
|
||||||
|
public class GHPullRequestFileDetail {
|
||||||
|
|
||||||
|
String sha;
|
||||||
|
String filename;
|
||||||
|
String status;
|
||||||
|
int additions;
|
||||||
|
int deletions;
|
||||||
|
int changes;
|
||||||
|
String blob_url;
|
||||||
|
String raw_url;
|
||||||
|
String contents_url;
|
||||||
|
String patch;
|
||||||
|
|
||||||
|
public String getSha() {
|
||||||
|
return sha;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAdditions() {
|
||||||
|
return additions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDeletions() {
|
||||||
|
return deletions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChanges() {
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getBlobUrl() {
|
||||||
|
return GitHub.parseURL(blob_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getRawUrl() {
|
||||||
|
return GitHub.parseURL(raw_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getContentsUrl() {
|
||||||
|
return GitHub.parseURL(contents_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPatch() {
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists up pull requests with some filtering and sorting.
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
* @see GHRepository#queryPullRequests()
|
||||||
|
*/
|
||||||
|
public class GHPullRequestQueryBuilder extends GHQueryBuilder<GHPullRequest> {
|
||||||
|
private final GHRepository repo;
|
||||||
|
|
||||||
|
/*package*/ GHPullRequestQueryBuilder(GHRepository repo) {
|
||||||
|
super(repo.root);
|
||||||
|
this.repo = repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHPullRequestQueryBuilder state(GHIssueState state) {
|
||||||
|
req.with("state",state);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHPullRequestQueryBuilder head(String head) {
|
||||||
|
req.with("head",head);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHPullRequestQueryBuilder base(String base) {
|
||||||
|
req.with("base",base);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GHPullRequestQueryBuilder sort(Sort sort) {
|
||||||
|
req.with("sort",sort);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Sort { CREATED, UPDATED, POPULARITY, LONG_RUNNING }
|
||||||
|
|
||||||
|
public GHPullRequestQueryBuilder direction(GHDirection d) {
|
||||||
|
req.with("direction",d);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PagedIterable<GHPullRequest> list() {
|
||||||
|
return new PagedIterable<GHPullRequest>() {
|
||||||
|
public PagedIterator<GHPullRequest> _iterator(int pageSize) {
|
||||||
|
return new PagedIterator<GHPullRequest>(req.asIterator(repo.getApiTailUrl("pulls"), GHPullRequest[].class, pageSize)) {
|
||||||
|
@Override
|
||||||
|
protected void wrapUp(GHPullRequest[] page) {
|
||||||
|
for (GHPullRequest pr : page)
|
||||||
|
pr.wrapUp(repo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
106
src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java
Normal file
106
src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Review comment to the pull request
|
||||||
|
*
|
||||||
|
* @author Julien Henry
|
||||||
|
* @see GHPullRequest#listReviewComments()
|
||||||
|
* @see GHPullRequest#createReviewComment(String, String, String, int)
|
||||||
|
*/
|
||||||
|
public class GHPullRequestReviewComment extends GHObject {
|
||||||
|
GHPullRequest owner;
|
||||||
|
|
||||||
|
private String body;
|
||||||
|
private GHUser user;
|
||||||
|
private String path;
|
||||||
|
private int position;
|
||||||
|
private int originalPosition;
|
||||||
|
|
||||||
|
/*package*/ GHPullRequestReviewComment wrapUp(GHPullRequest owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the pull request to which this review comment is associated.
|
||||||
|
*/
|
||||||
|
public GHPullRequest getParent() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The comment itself.
|
||||||
|
*/
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user who posted this comment.
|
||||||
|
*/
|
||||||
|
public GHUser getUser() throws IOException {
|
||||||
|
return owner.root.getUser(user.getLogin());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOriginalPosition() {
|
||||||
|
return originalPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getApiRoute() {
|
||||||
|
return "/repos/"+owner.getRepository().getFullName()+"/pulls/comments/"+id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the comment.
|
||||||
|
*/
|
||||||
|
public void update(String body) throws IOException {
|
||||||
|
new Requester(owner.root).method("PATCH").with("body", body).to(getApiRoute(),this);
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes this review comment.
|
||||||
|
*/
|
||||||
|
public void delete() throws IOException {
|
||||||
|
new Requester(owner.root).method("DELETE").to(getApiRoute());
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main/java/org/kohsuke/github/GHQueryBuilder.java
Normal file
21
src/main/java/org/kohsuke/github/GHQueryBuilder.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to specify filters, sort order, etc for listing items in a collection.
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public abstract class GHQueryBuilder<T> {
|
||||||
|
protected final GitHub root;
|
||||||
|
protected final Requester req;
|
||||||
|
|
||||||
|
/*package*/ GHQueryBuilder(GitHub root) {
|
||||||
|
this.root = root;
|
||||||
|
this.req = root.retrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start listing items by using the settings built up on this object.
|
||||||
|
*/
|
||||||
|
public abstract PagedIterable<T> list();
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,6 +25,8 @@ public class GHRateLimit {
|
|||||||
/**
|
/**
|
||||||
* Non-epoch date
|
* Non-epoch date
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR",
|
||||||
|
justification = "The value comes from JSON deserialization")
|
||||||
public Date getResetDate() {
|
public Date getResetDate() {
|
||||||
return new Date(reset.getTime() * 1000);
|
return new Date(reset.getTime() * 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
@@ -77,7 +78,8 @@ public class GHRef {
|
|||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public static class GHObject {
|
public static class GHObject {
|
||||||
private String type, sha, url;
|
private String type, sha, url;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.kohsuke.github;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,8 +45,14 @@ public class GHRelease extends GHObject {
|
|||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHtmlUrl() {
|
public GHRelease setDraft(boolean draft) throws IOException {
|
||||||
return html_url;
|
edit("draft", draft);
|
||||||
|
this.draft = draft;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -69,7 +76,7 @@ public class GHRelease extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Date getPublished_at() {
|
public Date getPublished_at() {
|
||||||
return published_at;
|
return new Date(published_at.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitHub getRoot() {
|
public GitHub getRoot() {
|
||||||
@@ -143,6 +150,13 @@ public class GHRelease extends GHObject {
|
|||||||
new Requester(root).method("DELETE").to(owner.getApiTailUrl("releases/"+id));
|
new Requester(root).method("DELETE").to(owner.getApiTailUrl("releases/"+id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit this release.
|
||||||
|
*/
|
||||||
|
private void edit(String key, Object value) throws IOException {
|
||||||
|
new Requester(root)._with(key, value).method("PATCH").to(owner.getApiTailUrl("releases/"+id));
|
||||||
|
}
|
||||||
|
|
||||||
private String getApiTailUrl(String end) {
|
private String getApiTailUrl(String end) {
|
||||||
return owner.getApiTailUrl(format("releases/%s/%s",id,end));
|
return owner.getApiTailUrl(format("releases/%s/%s",id,end));
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/main/java/org/kohsuke/github/GHRepoHook.java
Normal file
23
src/main/java/org/kohsuke/github/GHRepoHook.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
class GHRepoHook extends GHHook {
|
||||||
|
/**
|
||||||
|
* Repository that the hook belongs to.
|
||||||
|
*/
|
||||||
|
/*package*/ transient GHRepository repository;
|
||||||
|
|
||||||
|
/*package*/ GHRepoHook wrap(GHRepository owner) {
|
||||||
|
this.repository = owner;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GitHub getRoot() {
|
||||||
|
return repository.root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getApiRoute() {
|
||||||
|
return String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,31 +25,47 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
import javax.xml.bind.DatatypeConverter;
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.AbstractSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A repository on GitHub.
|
* A repository on GitHub.
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"UnusedDeclaration"})
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public class GHRepository extends GHObject {
|
public class GHRepository extends GHObject {
|
||||||
/*package almost final*/ GitHub root;
|
/*package almost final*/ GitHub root;
|
||||||
|
|
||||||
private String description, homepage, name, full_name;
|
private String description, homepage, name, full_name;
|
||||||
private String html_url; // this is the UI
|
private String html_url; // this is the UI
|
||||||
private String git_url, ssh_url, clone_url, svn_url;
|
private String git_url, ssh_url, clone_url, svn_url, mirror_url;
|
||||||
private GHUser owner; // not fully populated. beware.
|
private GHUser owner; // not fully populated. beware.
|
||||||
private boolean has_issues, has_wiki, fork, has_downloads;
|
private boolean has_issues, has_wiki, fork, has_downloads;
|
||||||
@JsonProperty("private")
|
@JsonProperty("private")
|
||||||
@@ -57,20 +73,23 @@ public class GHRepository extends GHObject {
|
|||||||
private int watchers,forks,open_issues,size,network_count,subscribers_count;
|
private int watchers,forks,open_issues,size,network_count,subscribers_count;
|
||||||
private String pushed_at;
|
private String pushed_at;
|
||||||
private Map<Integer,GHMilestone> milestones = new HashMap<Integer, GHMilestone>();
|
private Map<Integer,GHMilestone> milestones = new HashMap<Integer, GHMilestone>();
|
||||||
|
|
||||||
private String default_branch,language;
|
private String default_branch,language;
|
||||||
private Map<String,GHCommit> commits = new HashMap<String, GHCommit>();
|
private Map<String,GHCommit> commits = new HashMap<String, GHCommit>();
|
||||||
|
|
||||||
|
@SkipFromToString
|
||||||
private GHRepoPermission permissions;
|
private GHRepoPermission permissions;
|
||||||
|
|
||||||
|
private GHRepository source, parent;
|
||||||
|
|
||||||
public GHDeploymentBuilder createDeployment(String ref) {
|
public GHDeploymentBuilder createDeployment(String ref) {
|
||||||
return new GHDeploymentBuilder(this,ref);
|
return new GHDeploymentBuilder(this,ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PagedIterable<GHDeploymentStatus> getDeploymentStatuses(final int id) {
|
public PagedIterable<GHDeploymentStatus> getDeploymentStatuses(final int id) {
|
||||||
return new PagedIterable<GHDeploymentStatus>() {
|
return new PagedIterable<GHDeploymentStatus>() {
|
||||||
public PagedIterator<GHDeploymentStatus> iterator() {
|
public PagedIterator<GHDeploymentStatus> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHDeploymentStatus>(root.retrieve().asIterator(getApiTailUrl("deployments")+"/"+id+"/statuses", GHDeploymentStatus[].class)) {
|
return new PagedIterator<GHDeploymentStatus>(root.retrieve().asIterator(getApiTailUrl("deployments")+"/"+id+"/statuses", GHDeploymentStatus[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHDeploymentStatus[] page) {
|
protected void wrapUp(GHDeploymentStatus[] page) {
|
||||||
for (GHDeploymentStatus c : page)
|
for (GHDeploymentStatus c : page)
|
||||||
@@ -85,8 +104,8 @@ public class GHRepository extends GHObject {
|
|||||||
List<String> params = Arrays.asList(getParam("sha", sha), getParam("ref", ref), getParam("task", task), getParam("environment", environment));
|
List<String> params = Arrays.asList(getParam("sha", sha), getParam("ref", ref), getParam("task", task), getParam("environment", environment));
|
||||||
final String deploymentsUrl = getApiTailUrl("deployments") + "?"+ join(params,"&");
|
final String deploymentsUrl = getApiTailUrl("deployments") + "?"+ join(params,"&");
|
||||||
return new PagedIterable<GHDeployment>() {
|
return new PagedIterable<GHDeployment>() {
|
||||||
public PagedIterator<GHDeployment> iterator() {
|
public PagedIterator<GHDeployment> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHDeployment>(root.retrieve().asIterator(deploymentsUrl, GHDeployment[].class)) {
|
return new PagedIterator<GHDeployment>(root.retrieve().asIterator(deploymentsUrl, GHDeployment[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHDeployment[] page) {
|
protected void wrapUp(GHDeployment[] page) {
|
||||||
for (GHDeployment c : page)
|
for (GHDeployment c : page)
|
||||||
@@ -152,6 +171,14 @@ public class GHRepository extends GHObject {
|
|||||||
return svn_url;
|
return svn_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Mirror URL to access this repository: https://github.com/apache/tomee
|
||||||
|
* mirrored from git://git.apache.org/tomee.git
|
||||||
|
*/
|
||||||
|
public String getMirrorUrl() {
|
||||||
|
return mirror_url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the SSH URL to access this repository, such as git@github.com:rails/rails.git
|
* Gets the SSH URL to access this repository, such as git@github.com:rails/rails.git
|
||||||
*/
|
*/
|
||||||
@@ -159,6 +186,10 @@ public class GHRepository extends GHObject {
|
|||||||
return ssh_url;
|
return ssh_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return GitHub.parseURL(html_url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Short repository name without the owner. For example 'jenkins' in case of http://github.com/jenkinsci/jenkins
|
* Short repository name without the owner. For example 'jenkins' in case of http://github.com/jenkinsci/jenkins
|
||||||
*/
|
*/
|
||||||
@@ -210,10 +241,10 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
public List<GHIssue> getIssues(GHIssueState state, GHMilestone milestone) throws IOException {
|
public List<GHIssue> getIssues(GHIssueState state, GHMilestone milestone) throws IOException {
|
||||||
return Arrays.asList(GHIssue.wrap(root.retrieve()
|
return Arrays.asList(GHIssue.wrap(root.retrieve()
|
||||||
.to(getApiTailUrl(String.format("issues?state=%s&milestone=%s",
|
.with("state", state)
|
||||||
state.toString().toLowerCase(), milestone == null ? "none" : "" + milestone.getNumber())),
|
.with("milestone", milestone == null ? "none" : "" + milestone.getNumber())
|
||||||
GHIssue[].class
|
.to(getApiTailUrl("issues"),
|
||||||
), this));
|
GHIssue[].class), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,8 +252,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHIssue> listIssues(final GHIssueState state) {
|
public PagedIterable<GHIssue> listIssues(final GHIssueState state) {
|
||||||
return new PagedIterable<GHIssue>() {
|
return new PagedIterable<GHIssue>() {
|
||||||
public PagedIterator<GHIssue> iterator() {
|
public PagedIterator<GHIssue> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHIssue>(root.retrieve().asIterator(getApiTailUrl("issues?state="+state.toString().toLowerCase(Locale.ENGLISH)), GHIssue[].class)) {
|
return new PagedIterator<GHIssue>(root.retrieve().with("state",state).asIterator(getApiTailUrl("issues"), GHIssue[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHIssue[] page) {
|
protected void wrapUp(GHIssue[] page) {
|
||||||
for (GHIssue c : page)
|
for (GHIssue c : page)
|
||||||
@@ -261,8 +292,8 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
public PagedIterable<GHRelease> listReleases() throws IOException {
|
public PagedIterable<GHRelease> listReleases() throws IOException {
|
||||||
return new PagedIterable<GHRelease>() {
|
return new PagedIterable<GHRelease>() {
|
||||||
public PagedIterator<GHRelease> iterator() {
|
public PagedIterator<GHRelease> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRelease>(root.retrieve().asIterator(getApiTailUrl("releases"), GHRelease[].class)) {
|
return new PagedIterator<GHRelease>(root.retrieve().asIterator(getApiTailUrl("releases"), GHRelease[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRelease[] page) {
|
protected void wrapUp(GHRelease[] page) {
|
||||||
for (GHRelease c : page)
|
for (GHRelease c : page)
|
||||||
@@ -275,8 +306,8 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
public PagedIterable<GHTag> listTags() throws IOException {
|
public PagedIterable<GHTag> listTags() throws IOException {
|
||||||
return new PagedIterable<GHTag>() {
|
return new PagedIterable<GHTag>() {
|
||||||
public PagedIterator<GHTag> iterator() {
|
public PagedIterator<GHTag> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHTag>(root.retrieve().asIterator(getApiTailUrl("tags"), GHTag[].class)) {
|
return new PagedIterator<GHTag>(root.retrieve().asIterator(getApiTailUrl("tags"), GHTag[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHTag[] page) {
|
protected void wrapUp(GHTag[] page) {
|
||||||
for (GHTag c : page)
|
for (GHTag c : page)
|
||||||
@@ -315,6 +346,10 @@ public class GHRepository extends GHObject {
|
|||||||
return fork;
|
return fork;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of all forks of this repository.
|
||||||
|
* This not only counts direct forks, but also forks of forks, and so on.
|
||||||
|
*/
|
||||||
public int getForks() {
|
public int getForks() {
|
||||||
return forks;
|
return forks;
|
||||||
}
|
}
|
||||||
@@ -353,11 +388,19 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the primary branch you'll configure in the "Admin > Options" config page.
|
* Returns the primary branch you'll configure in the "Admin > Options" config page.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* This field is null until the user explicitly configures the master branch.
|
* This field is null until the user explicitly configures the master branch.
|
||||||
*/
|
*/
|
||||||
|
public String getDefaultBranch() {
|
||||||
|
return default_branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* Renamed to {@link #getDefaultBranch()}
|
||||||
|
*/
|
||||||
public String getMasterBranch() {
|
public String getMasterBranch() {
|
||||||
return default_branch;
|
return default_branch;
|
||||||
}
|
}
|
||||||
@@ -365,7 +408,8 @@ public class GHRepository extends GHObject {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the collaborators on this repository.
|
* Gets the collaborators on this repository.
|
||||||
* This set always appear to include the owner.
|
* This set always appear to include the owner.
|
||||||
@@ -383,9 +427,9 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHUser> listCollaborators() throws IOException {
|
public PagedIterable<GHUser> listCollaborators() throws IOException {
|
||||||
return new PagedIterable<GHUser>() {
|
return new PagedIterable<GHUser>() {
|
||||||
public PagedIterator<GHUser> iterator() {
|
public PagedIterator<GHUser> _iterator(int pageSize) {
|
||||||
|
|
||||||
return new PagedIterator<GHUser>(root.retrieve().asIterator(getApiTailUrl("collaborators"), GHUser[].class)) {
|
return new PagedIterator<GHUser>(root.retrieve().asIterator(getApiTailUrl("collaborators"), GHUser[].class, pageSize)) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHUser[] users) {
|
protected void wrapUp(GHUser[] users) {
|
||||||
@@ -444,7 +488,7 @@ public class GHRepository extends GHObject {
|
|||||||
public void setEmailServiceHook(String address) throws IOException {
|
public void setEmailServiceHook(String address) throws IOException {
|
||||||
Map<String, String> config = new HashMap<String, String>();
|
Map<String, String> config = new HashMap<String, String>();
|
||||||
config.put("address", address);
|
config.put("address", address);
|
||||||
new Requester(root).method("POST").with("name", "email").with("config", config).with("active", "true")
|
new Requester(root).method("POST").with("name", "email").with("config", config).with("active", true)
|
||||||
.to(getApiTailUrl("hooks"));
|
.to(getApiTailUrl("hooks"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,6 +532,10 @@ public class GHRepository extends GHObject {
|
|||||||
edit("homepage",value);
|
edit("homepage",value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDefaultBranch(String value) throws IOException {
|
||||||
|
edit("default_branch", value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes this repository.
|
* Deletes this repository.
|
||||||
*/
|
*/
|
||||||
@@ -499,6 +547,39 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort orders for listing forks
|
||||||
|
*/
|
||||||
|
public enum ForkSort { NEWEST, OLDEST, STARGAZERS }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all the direct forks of this repository, sorted by
|
||||||
|
* github api default, currently {@link ForkSort#NEWEST ForkSort.NEWEST}.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHRepository> listForks() {
|
||||||
|
return listForks(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all the direct forks of this repository, sorted by the given sort order.
|
||||||
|
* @param sort the sort order. If null, defaults to github api default,
|
||||||
|
* currently {@link ForkSort#NEWEST ForkSort.NEWEST}.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHRepository> listForks(final ForkSort sort) {
|
||||||
|
return new PagedIterable<GHRepository>() {
|
||||||
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
|
return new PagedIterator<GHRepository>(root.retrieve().with("sort",sort).asIterator(getApiTailUrl("forks"), GHRepository[].class, pageSize)) {
|
||||||
|
@Override
|
||||||
|
protected void wrapUp(GHRepository[] page) {
|
||||||
|
for (GHRepository c : page) {
|
||||||
|
c.wrap(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forks this repository as your repository.
|
* Forks this repository as your repository.
|
||||||
*
|
*
|
||||||
@@ -506,7 +587,19 @@ public class GHRepository extends GHObject {
|
|||||||
* Newly forked repository that belong to you.
|
* Newly forked repository that belong to you.
|
||||||
*/
|
*/
|
||||||
public GHRepository fork() throws IOException {
|
public GHRepository fork() throws IOException {
|
||||||
return new Requester(root).method("POST").to(getApiTailUrl("forks"), GHRepository.class).wrap(root);
|
new Requester(root).method("POST").to(getApiTailUrl("forks"), null);
|
||||||
|
|
||||||
|
// 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) return r;
|
||||||
|
try {
|
||||||
|
Thread.sleep(3000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw (IOException)new InterruptedIOException().initCause(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IOException(this+" was forked but can't find the new repository");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,24 +637,24 @@ public class GHRepository extends GHObject {
|
|||||||
* @see #listPullRequests(GHIssueState)
|
* @see #listPullRequests(GHIssueState)
|
||||||
*/
|
*/
|
||||||
public List<GHPullRequest> getPullRequests(GHIssueState state) throws IOException {
|
public List<GHPullRequest> getPullRequests(GHIssueState state) throws IOException {
|
||||||
return listPullRequests(state).asList();
|
return queryPullRequests().state(state).list().asList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all the pull requests of a particular state.
|
* Retrieves all the pull requests of a particular state.
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
* Use {@link #queryPullRequests()}
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHPullRequest> listPullRequests(final GHIssueState state) {
|
public PagedIterable<GHPullRequest> listPullRequests(GHIssueState state) {
|
||||||
return new PagedIterable<GHPullRequest>() {
|
return queryPullRequests().state(state).list();
|
||||||
public PagedIterator<GHPullRequest> iterator() {
|
}
|
||||||
return new PagedIterator<GHPullRequest>(root.retrieve().asIterator(getApiTailUrl("pulls?state="+state.name().toLowerCase(Locale.ENGLISH)), GHPullRequest[].class)) {
|
|
||||||
@Override
|
/**
|
||||||
protected void wrapUp(GHPullRequest[] page) {
|
* Retrieves pull requests.
|
||||||
for (GHPullRequest pr : page)
|
*/
|
||||||
pr.wrapUp(GHRepository.this);
|
public GHPullRequestQueryBuilder queryPullRequests() {
|
||||||
}
|
return new GHPullRequestQueryBuilder(this);
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -591,15 +684,11 @@ public class GHRepository extends GHObject {
|
|||||||
* Retrieves the currently configured hooks.
|
* Retrieves the currently configured hooks.
|
||||||
*/
|
*/
|
||||||
public List<GHHook> getHooks() throws IOException {
|
public List<GHHook> getHooks() throws IOException {
|
||||||
List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(
|
return GHHooks.repoContext(this, owner).getHooks();
|
||||||
root.retrieve().to(getApiTailUrl("hooks"), GHHook[].class)));
|
|
||||||
for (GHHook h : list)
|
|
||||||
h.wrap(this);
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHHook getHook(int id) throws IOException {
|
public GHHook getHook(int id) throws IOException {
|
||||||
return root.retrieve().to(getApiTailUrl("hooks/" + id), GHHook.class).wrap(this);
|
return GHHooks.repoContext(this, owner).getHook(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -620,7 +709,23 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHCompare getCompare(GHBranch id1, GHBranch id2) throws IOException {
|
public GHCompare getCompare(GHBranch id1, GHBranch id2) throws IOException {
|
||||||
return getCompare(id1.getName(),id2.getName());
|
|
||||||
|
GHRepository owner1 = id1.getOwner();
|
||||||
|
GHRepository owner2 = id2.getOwner();
|
||||||
|
|
||||||
|
// If the owner of the branches is different, we have a cross-fork compare.
|
||||||
|
if (owner1!=null && owner2!=null) {
|
||||||
|
String ownerName1 = owner1.getOwnerName();
|
||||||
|
String ownerName2 = owner2.getOwnerName();
|
||||||
|
if (!StringUtils.equals(ownerName1, ownerName2)) {
|
||||||
|
String qualifiedName1 = String.format("%s:%s", ownerName1, id1.getName());
|
||||||
|
String qualifiedName2 = String.format("%s:%s", ownerName2, id2.getName());
|
||||||
|
return getCompare(qualifiedName1, qualifiedName2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCompare(id1.getName(), id2.getName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -629,7 +734,7 @@ public class GHRepository extends GHObject {
|
|||||||
* @throws IOException on failure communicating with GitHub
|
* @throws IOException on failure communicating with GitHub
|
||||||
*/
|
*/
|
||||||
public GHRef[] getRefs() throws IOException {
|
public GHRef[] getRefs() throws IOException {
|
||||||
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs", owner.login, name), GHRef[].class),root);
|
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs", owner.login, name), GHRef[].class), root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -642,48 +747,48 @@ public class GHRepository extends GHObject {
|
|||||||
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refType), GHRef[].class),root);
|
return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refType), GHRef[].class),root);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrive a ref of the given type for the current GitHub repository.
|
* Retrive a ref of the given type for the current GitHub repository.
|
||||||
*
|
*
|
||||||
* @param refName
|
* @param refName
|
||||||
* eg: heads/branch
|
* eg: heads/branch
|
||||||
* @return refs matching the request type
|
* @return refs matching the request type
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* on failure communicating with GitHub, potentially due to an
|
* on failure communicating with GitHub, potentially due to an
|
||||||
* invalid ref type being requested
|
* invalid ref type being requested
|
||||||
*/
|
*/
|
||||||
public GHRef getRef(String refName) throws IOException {
|
public GHRef getRef(String refName) throws IOException {
|
||||||
return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root);
|
return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrive a tree of the given type for the current GitHub repository.
|
* Retrive a tree of the given type for the current GitHub repository.
|
||||||
*
|
*
|
||||||
* @param sha - sha number or branch name ex: "master"
|
* @param sha - sha number or branch name ex: "master"
|
||||||
* @return refs matching the request type
|
* @return refs matching the request type
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* on failure communicating with GitHub, potentially due to an
|
* on failure communicating with GitHub, potentially due to an
|
||||||
* invalid tree type being requested
|
* invalid tree type being requested
|
||||||
*/
|
*/
|
||||||
public GHTree getTree(String sha) throws IOException {
|
public GHTree getTree(String sha) throws IOException {
|
||||||
String url = String.format("/repos/%s/%s/git/trees/%s", owner.login, name, sha);
|
String url = String.format("/repos/%s/%s/git/trees/%s", owner.login, name, sha);
|
||||||
return root.retrieve().to(url, GHTree.class).wrap(root);
|
return root.retrieve().to(url, GHTree.class).wrap(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the tree for the current GitHub repository, recursively as described in here:
|
|
||||||
* https://developer.github.com/v3/git/trees/#get-a-tree-recursively
|
|
||||||
*
|
|
||||||
* @param sha - sha number or branch name ex: "master"
|
|
||||||
* @param recursive use 1
|
|
||||||
* @throws IOException
|
|
||||||
* on failure communicating with GitHub, potentially due to an
|
|
||||||
* invalid tree type being requested
|
|
||||||
*/
|
|
||||||
public GHTree getTreeRecursive(String sha, int recursive) throws IOException {
|
|
||||||
String url = String.format("/repos/%s/%s/git/trees/%s?recursive=%d", owner.login, name, sha, recursive);
|
|
||||||
return root.retrieve().to(url, GHTree.class).wrap(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Retrieves the tree for the current GitHub repository, recursively as described in here:
|
||||||
|
* https://developer.github.com/v3/git/trees/#get-a-tree-recursively
|
||||||
|
*
|
||||||
|
* @param sha - sha number or branch name ex: "master"
|
||||||
|
* @param recursive use 1
|
||||||
|
* @throws IOException
|
||||||
|
* on failure communicating with GitHub, potentially due to an
|
||||||
|
* invalid tree type being requested
|
||||||
|
*/
|
||||||
|
public GHTree getTreeRecursive(String sha, int recursive) throws IOException {
|
||||||
|
String url = String.format("/repos/%s/%s/git/trees/%s?recursive=%d", owner.login, name, sha, recursive);
|
||||||
|
return root.retrieve().to(url, GHTree.class).wrap(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Gets a commit object in this repository.
|
* Gets a commit object in this repository.
|
||||||
*/
|
*/
|
||||||
public GHCommit getCommit(String sha1) throws IOException {
|
public GHCommit getCommit(String sha1) throws IOException {
|
||||||
@@ -700,8 +805,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHCommit> listCommits() {
|
public PagedIterable<GHCommit> listCommits() {
|
||||||
return new PagedIterable<GHCommit>() {
|
return new PagedIterable<GHCommit>() {
|
||||||
public PagedIterator<GHCommit> iterator() {
|
public PagedIterator<GHCommit> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHCommit>(root.retrieve().asIterator(String.format("/repos/%s/%s/commits", owner.login, name), GHCommit[].class)) {
|
return new PagedIterator<GHCommit>(root.retrieve().asIterator(String.format("/repos/%s/%s/commits", owner.login, name), GHCommit[].class, pageSize)) {
|
||||||
protected void wrapUp(GHCommit[] page) {
|
protected void wrapUp(GHCommit[] page) {
|
||||||
for (GHCommit c : page)
|
for (GHCommit c : page)
|
||||||
c.wrapUp(GHRepository.this);
|
c.wrapUp(GHRepository.this);
|
||||||
@@ -723,8 +828,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHCommitComment> listCommitComments() {
|
public PagedIterable<GHCommitComment> listCommitComments() {
|
||||||
return new PagedIterable<GHCommitComment>() {
|
return new PagedIterable<GHCommitComment>() {
|
||||||
public PagedIterator<GHCommitComment> iterator() {
|
public PagedIterator<GHCommitComment> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHCommitComment>(root.retrieve().asIterator(String.format("/repos/%s/%s/comments", owner.login, name), GHCommitComment[].class)) {
|
return new PagedIterator<GHCommitComment>(root.retrieve().asIterator(String.format("/repos/%s/%s/comments", owner.login, name), GHCommitComment[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHCommitComment[] page) {
|
protected void wrapUp(GHCommitComment[] page) {
|
||||||
for (GHCommitComment c : page)
|
for (GHCommitComment c : page)
|
||||||
@@ -740,8 +845,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHCommitStatus> listCommitStatuses(final String sha1) throws IOException {
|
public PagedIterable<GHCommitStatus> listCommitStatuses(final String sha1) throws IOException {
|
||||||
return new PagedIterable<GHCommitStatus>() {
|
return new PagedIterable<GHCommitStatus>() {
|
||||||
public PagedIterator<GHCommitStatus> iterator() {
|
public PagedIterator<GHCommitStatus> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHCommitStatus>(root.retrieve().asIterator(String.format("/repos/%s/%s/statuses/%s", owner.login, name, sha1), GHCommitStatus[].class)) {
|
return new PagedIterator<GHCommitStatus>(root.retrieve().asIterator(String.format("/repos/%s/%s/statuses/%s", owner.login, name, sha1), GHCommitStatus[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHCommitStatus[] page) {
|
protected void wrapUp(GHCommitStatus[] page) {
|
||||||
for (GHCommitStatus c : page)
|
for (GHCommitStatus c : page)
|
||||||
@@ -768,22 +873,22 @@ public class GHRepository extends GHObject {
|
|||||||
* @param description
|
* @param description
|
||||||
* Optional short description.
|
* Optional short description.
|
||||||
* @param context
|
* @param context
|
||||||
* Optinal commit status context.
|
* Optinal commit status context.
|
||||||
*/
|
*/
|
||||||
public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, String targetUrl, String description, String context) throws IOException {
|
public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, String targetUrl, String description, String context) throws IOException {
|
||||||
return new Requester(root)
|
return new Requester(root)
|
||||||
.with("state", state.name().toLowerCase(Locale.ENGLISH))
|
.with("state", state)
|
||||||
.with("target_url", targetUrl)
|
.with("target_url", targetUrl)
|
||||||
.with("description", description)
|
.with("description", description)
|
||||||
.with("context", context)
|
.with("context", context)
|
||||||
.to(String.format("/repos/%s/%s/statuses/%s",owner.login,this.name,sha1),GHCommitStatus.class).wrapUp(root);
|
.to(String.format("/repos/%s/%s/statuses/%s",owner.login,this.name,sha1),GHCommitStatus.class).wrapUp(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see {@link #createCommitStatus(String, GHCommitState,String,String,String) createCommitStatus}
|
* @see #createCommitStatus(String, GHCommitState,String,String,String)
|
||||||
*/
|
*/
|
||||||
public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, String targetUrl, String description) throws IOException {
|
public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, String targetUrl, String description) throws IOException {
|
||||||
return createCommitStatus(sha1, state, targetUrl, description,null);
|
return createCommitStatus(sha1, state, targetUrl, description, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -791,8 +896,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
||||||
return new PagedIterable<GHEventInfo>() {
|
return new PagedIterable<GHEventInfo>() {
|
||||||
public PagedIterator<GHEventInfo> iterator() {
|
public PagedIterator<GHEventInfo> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/repos/%s/%s/events", owner.login, name), GHEventInfo[].class)) {
|
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/repos/%s/%s/events", owner.login, name), GHEventInfo[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHEventInfo[] page) {
|
protected void wrapUp(GHEventInfo[] page) {
|
||||||
for (GHEventInfo c : page)
|
for (GHEventInfo c : page)
|
||||||
@@ -810,8 +915,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHLabel> listLabels() throws IOException {
|
public PagedIterable<GHLabel> listLabels() throws IOException {
|
||||||
return new PagedIterable<GHLabel>() {
|
return new PagedIterable<GHLabel>() {
|
||||||
public PagedIterator<GHLabel> iterator() {
|
public PagedIterator<GHLabel> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHLabel>(root.retrieve().asIterator(getApiTailUrl("labels"), GHLabel[].class)) {
|
return new PagedIterator<GHLabel>(root.retrieve().asIterator(getApiTailUrl("labels"), GHLabel[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHLabel[] page) {
|
protected void wrapUp(GHLabel[] page) {
|
||||||
for (GHLabel c : page)
|
for (GHLabel c : page)
|
||||||
@@ -829,7 +934,7 @@ public class GHRepository extends GHObject {
|
|||||||
public GHLabel createLabel(String name, String color) throws IOException {
|
public GHLabel createLabel(String name, String color) throws IOException {
|
||||||
return root.retrieve().method("POST")
|
return root.retrieve().method("POST")
|
||||||
.with("name",name)
|
.with("name",name)
|
||||||
.with("color",color)
|
.with("color", color)
|
||||||
.to(getApiTailUrl("labels"), GHLabel.class).wrapUp(this);
|
.to(getApiTailUrl("labels"), GHLabel.class).wrapUp(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -839,9 +944,44 @@ public class GHRepository extends GHObject {
|
|||||||
* https://developer.github.com/v3/activity/watching/
|
* https://developer.github.com/v3/activity/watching/
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHUser> listSubscribers() {
|
public PagedIterable<GHUser> listSubscribers() {
|
||||||
|
return listUsers("subscribers");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all the users who have starred this repo based on the old version of the API. For
|
||||||
|
* additional information, like date when the repository was starred, see {@link #listStargazers2()}
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHUser> listStargazers() {
|
||||||
|
return listUsers("stargazers");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all the users who have starred this repo based on new version of the API, having extended
|
||||||
|
* information like the time when the repository was starred. For compatibility with the old API
|
||||||
|
* see {@link #listStargazers()}
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHStargazer> listStargazers2() {
|
||||||
|
return new PagedIterable<GHStargazer>() {
|
||||||
|
@Override
|
||||||
|
public PagedIterator<GHStargazer> _iterator(int pageSize) {
|
||||||
|
Requester requester = root.retrieve();
|
||||||
|
requester.setHeader("Accept", "application/vnd.github.v3.star+json");
|
||||||
|
return new PagedIterator<GHStargazer>(requester.asIterator(getApiTailUrl("stargazers"), GHStargazer[].class, pageSize)) {
|
||||||
|
@Override
|
||||||
|
protected void wrapUp(GHStargazer[] page) {
|
||||||
|
for (GHStargazer c : page) {
|
||||||
|
c.wrapUp(GHRepository.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private PagedIterable<GHUser> listUsers(final String suffix) {
|
||||||
return new PagedIterable<GHUser>() {
|
return new PagedIterable<GHUser>() {
|
||||||
public PagedIterator<GHUser> iterator() {
|
public PagedIterator<GHUser> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHUser>(root.retrieve().asIterator(getApiTailUrl("subscribers"), GHUser[].class)) {
|
return new PagedIterator<GHUser>(root.retrieve().asIterator(getApiTailUrl(suffix), GHUser[].class, pageSize)) {
|
||||||
protected void wrapUp(GHUser[] page) {
|
protected void wrapUp(GHUser[] page) {
|
||||||
for (GHUser c : page)
|
for (GHUser c : page)
|
||||||
c.wrapUp(root);
|
c.wrapUp(root);
|
||||||
@@ -852,10 +992,10 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* See https://api.github.com/hooks for possible names and their configuration scheme.
|
* See https://api.github.com/hooks for possible names and their configuration scheme.
|
||||||
* TODO: produce type-safe binding
|
* TODO: produce type-safe binding
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
|
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
|
||||||
* @param config
|
* @param config
|
||||||
@@ -864,21 +1004,9 @@ public class GHRepository extends GHObject {
|
|||||||
* Can be null. Types of events to hook into.
|
* Can be null. Types of events to hook into.
|
||||||
*/
|
*/
|
||||||
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
|
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
|
||||||
List<String> ea = null;
|
return GHHooks.repoContext(this, owner).createHook(name, config, events, active);
|
||||||
if (events!=null) {
|
|
||||||
ea = new ArrayList<String>();
|
|
||||||
for (GHEvent e : events)
|
|
||||||
ea.add(e.name().toLowerCase(Locale.ENGLISH));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Requester(root)
|
|
||||||
.with("name", name)
|
|
||||||
.with("active", active)
|
|
||||||
._with("config", config)
|
|
||||||
._with("events",ea)
|
|
||||||
.to(String.format("/repos/%s/%s/hooks",owner.login,this.name),GHHook.class).wrap(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
|
public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
|
||||||
return createHook("web",Collections.singletonMap("url",url.toExternalForm()),events,true);
|
return createHook("web",Collections.singletonMap("url",url.toExternalForm()),events,true);
|
||||||
}
|
}
|
||||||
@@ -903,10 +1031,12 @@ public class GHRepository extends GHObject {
|
|||||||
/**
|
/**
|
||||||
* Returns a set that represents the post-commit hook URLs.
|
* Returns a set that represents the post-commit hook URLs.
|
||||||
* The returned set is live, and changes made to them are reflected to GitHub.
|
* The returned set is live, and changes made to them are reflected to GitHub.
|
||||||
*
|
*
|
||||||
* @deprecated
|
* @deprecated
|
||||||
* Use {@link #getHooks()} and {@link #createHook(String, Map, Collection, boolean)}
|
* Use {@link #getHooks()} and {@link #createHook(String, Map, Collection, boolean)}
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||||
|
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||||
public Set<URL> getPostCommitHooks() {
|
public Set<URL> getPostCommitHooks() {
|
||||||
return postCommitHooks;
|
return postCommitHooks;
|
||||||
}
|
}
|
||||||
@@ -914,6 +1044,9 @@ public class GHRepository extends GHObject {
|
|||||||
/**
|
/**
|
||||||
* Live set view of the post-commit hook.
|
* Live set view of the post-commit hook.
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS",
|
||||||
|
justification = "It causes a performance degradation, but we have already exposed it to the API")
|
||||||
|
@SkipFromToString
|
||||||
private final Set<URL> postCommitHooks = new AbstractSet<URL>() {
|
private final Set<URL> postCommitHooks = new AbstractSet<URL>() {
|
||||||
private List<URL> getPostCommitHooks() {
|
private List<URL> getPostCommitHooks() {
|
||||||
try {
|
try {
|
||||||
@@ -983,16 +1116,20 @@ public class GHRepository extends GHObject {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GHBranch getBranch(String name) throws IOException {
|
||||||
|
return root.retrieve().to(getApiTailUrl("branches/"+name),GHBranch.class).wrap(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
* Use {@link #listMilestones(GHIssueState)}
|
* Use {@link #listMilestones(GHIssueState)}
|
||||||
*/
|
*/
|
||||||
public Map<Integer, GHMilestone> getMilestones() throws IOException {
|
public Map<Integer, GHMilestone> getMilestones() throws IOException {
|
||||||
Map<Integer,GHMilestone> milestones = new TreeMap<Integer, GHMilestone>();
|
Map<Integer,GHMilestone> milestones = new TreeMap<Integer, GHMilestone>();
|
||||||
for (GHMilestone m : listMilestones(GHIssueState.OPEN)) {
|
for (GHMilestone m : listMilestones(GHIssueState.OPEN)) {
|
||||||
milestones.put(m.getNumber(), m);
|
milestones.put(m.getNumber(), m);
|
||||||
}
|
}
|
||||||
return milestones;
|
return milestones;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1000,8 +1137,8 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHMilestone> listMilestones(final GHIssueState state) {
|
public PagedIterable<GHMilestone> listMilestones(final GHIssueState state) {
|
||||||
return new PagedIterable<GHMilestone>() {
|
return new PagedIterable<GHMilestone>() {
|
||||||
public PagedIterator<GHMilestone> iterator() {
|
public PagedIterator<GHMilestone> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHMilestone>(root.retrieve().asIterator(getApiTailUrl("milestones?state="+state.toString().toLowerCase(Locale.ENGLISH)), GHMilestone[].class)) {
|
return new PagedIterator<GHMilestone>(root.retrieve().with("state",state).asIterator(getApiTailUrl("milestones"), GHMilestone[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHMilestone[] page) {
|
protected void wrapUp(GHMilestone[] page) {
|
||||||
for (GHMilestone c : page)
|
for (GHMilestone c : page)
|
||||||
@@ -1012,16 +1149,16 @@ public class GHRepository extends GHObject {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHMilestone getMilestone(int number) throws IOException {
|
public GHMilestone getMilestone(int number) throws IOException {
|
||||||
GHMilestone m = milestones.get(number);
|
GHMilestone m = milestones.get(number);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
m = root.retrieve().to(getApiTailUrl("milestones/" + number), GHMilestone.class);
|
m = root.retrieve().to(getApiTailUrl("milestones/" + number), GHMilestone.class);
|
||||||
m.owner = this;
|
m.owner = this;
|
||||||
m.root = root;
|
m.root = root;
|
||||||
milestones.put(m.getNumber(), m);
|
milestones.put(m.getNumber(), m);
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHContent getFileContent(String path) throws IOException {
|
public GHContent getFileContent(String path) throws IOException {
|
||||||
return getFileContent(path, null);
|
return getFileContent(path, null);
|
||||||
@@ -1040,6 +1177,9 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
public List<GHContent> getDirectoryContent(String path, String ref) throws IOException {
|
public List<GHContent> getDirectoryContent(String path, String ref) throws IOException {
|
||||||
Requester requester = root.retrieve();
|
Requester requester = root.retrieve();
|
||||||
|
while (path.endsWith("/")) {
|
||||||
|
path = path.substring(0, path.length() - 1);
|
||||||
|
}
|
||||||
String target = getApiTailUrl("contents/" + path);
|
String target = getApiTailUrl("contents/" + path);
|
||||||
|
|
||||||
GHContent[] files = requester.with("ref",ref).to(target, GHContent[].class);
|
GHContent[] files = requester.with("ref",ref).to(target, GHContent[].class);
|
||||||
@@ -1058,11 +1198,17 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHContentUpdateResponse createContent(String content, String commitMessage, String path) throws IOException {
|
public GHContentUpdateResponse createContent(String content, String commitMessage, String path) throws IOException {
|
||||||
return createContent(content.getBytes(), commitMessage, path, null);
|
return createContent(content, commitMessage, path, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHContentUpdateResponse createContent(String content, String commitMessage, String path, String branch) throws IOException {
|
public GHContentUpdateResponse createContent(String content, String commitMessage, String path, String branch) throws IOException {
|
||||||
return createContent(content.getBytes(), commitMessage, path, branch);
|
final byte[] payload;
|
||||||
|
try {
|
||||||
|
payload = content.getBytes("UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException ex) {
|
||||||
|
throw (IOException) new IOException("UTF-8 encoding is not supported").initCause(ex);
|
||||||
|
}
|
||||||
|
return createContent(payload, commitMessage, path, branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHContentUpdateResponse createContent(byte[] contentBytes, String commitMessage, String path) throws IOException {
|
public GHContentUpdateResponse createContent(byte[] contentBytes, String commitMessage, String path) throws IOException {
|
||||||
@@ -1073,7 +1219,7 @@ public class GHRepository extends GHObject {
|
|||||||
Requester requester = new Requester(root)
|
Requester requester = new Requester(root)
|
||||||
.with("path", path)
|
.with("path", path)
|
||||||
.with("message", commitMessage)
|
.with("message", commitMessage)
|
||||||
.with("content", DatatypeConverter.printBase64Binary(contentBytes))
|
.with("content", Base64.encodeBase64String(contentBytes))
|
||||||
.method("PUT");
|
.method("PUT");
|
||||||
|
|
||||||
if (branch != null) {
|
if (branch != null) {
|
||||||
@@ -1088,24 +1234,56 @@ public class GHRepository extends GHObject {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHMilestone createMilestone(String title, String description) throws IOException {
|
public GHMilestone createMilestone(String title, String description) throws IOException {
|
||||||
return new Requester(root)
|
return new Requester(root)
|
||||||
.with("title", title).with("description", description).method("POST").to(getApiTailUrl("milestones"), GHMilestone.class).wrap(this);
|
.with("title", title).with("description", description).method("POST").to(getApiTailUrl("milestones"), GHMilestone.class).wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GHDeployKey addDeployKey(String title,String key) throws IOException {
|
public GHDeployKey addDeployKey(String title,String key) throws IOException {
|
||||||
return new Requester(root)
|
return new Requester(root)
|
||||||
.with("title", title).with("key", key).method("POST").to(getApiTailUrl("keys"), GHDeployKey.class).wrap(this);
|
.with("title", title).with("key", key).method("POST").to(getApiTailUrl("keys"), GHDeployKey.class).wrap(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GHDeployKey> getDeployKeys() throws IOException{
|
public List<GHDeployKey> getDeployKeys() throws IOException{
|
||||||
List<GHDeployKey> list = new ArrayList<GHDeployKey>(Arrays.asList(
|
List<GHDeployKey> list = new ArrayList<GHDeployKey>(Arrays.asList(
|
||||||
root.retrieve().to(getApiTailUrl("keys"), GHDeployKey[].class)));
|
root.retrieve().to(getApiTailUrl("keys"), GHDeployKey[].class)));
|
||||||
for (GHDeployKey h : list)
|
for (GHDeployKey h : list)
|
||||||
h.wrap(this);
|
h.wrap(this);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forked repositories have a 'source' attribute that specifies the ultimate source of the forking chain.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* {@link GHRepository} that points to the root repository where this repository is forked
|
||||||
|
* (indirectly or directly) from. Otherwise null.
|
||||||
|
* @see #getParent()
|
||||||
|
*/
|
||||||
|
public GHRepository getSource() throws IOException {
|
||||||
|
if (source == null) return null;
|
||||||
|
if (source.root == null)
|
||||||
|
source = root.getRepository(source.getFullName());
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forked repositories have a 'parent' attribute that specifies the repository this repository
|
||||||
|
* is directly forked from. If we keep traversing {@link #getParent()} until it returns null, that
|
||||||
|
* is {@link #getSource()}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* {@link GHRepository} that points to the repository where this repository is forked
|
||||||
|
* directly from. Otherwise null.
|
||||||
|
* @see #getSource()
|
||||||
|
*/
|
||||||
|
public GHRepository getParent() throws IOException {
|
||||||
|
if (parent == null) return null;
|
||||||
|
if (parent.root == null)
|
||||||
|
parent = root.getRepository(parent.getFullName());
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribes to this repository to get notifications.
|
* Subscribes to this repository to get notifications.
|
||||||
@@ -1124,7 +1302,7 @@ public class GHRepository extends GHObject {
|
|||||||
*/
|
*/
|
||||||
public GHSubscription getSubscription() throws IOException {
|
public GHSubscription getSubscription() throws IOException {
|
||||||
try {
|
try {
|
||||||
return new Requester(root).to(getApiTailUrl("subscription"), GHSubscription.class).wrapUp(this);
|
return root.retrieve().to(getApiTailUrl("subscription"), GHSubscription.class).wrapUp(this);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1132,8 +1310,8 @@ public class GHRepository extends GHObject {
|
|||||||
|
|
||||||
public PagedIterable<Contributor> listContributors() throws IOException {
|
public PagedIterable<Contributor> listContributors() throws IOException {
|
||||||
return new PagedIterable<Contributor>() {
|
return new PagedIterable<Contributor>() {
|
||||||
public PagedIterator<Contributor> iterator() {
|
public PagedIterator<Contributor> _iterator(int pageSize) {
|
||||||
return new PagedIterator<Contributor>(root.retrieve().asIterator(getApiTailUrl("contributors"), Contributor[].class)) {
|
return new PagedIterator<Contributor>(root.retrieve().asIterator(getApiTailUrl("contributors"), Contributor[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(Contributor[] page) {
|
protected void wrapUp(Contributor[] page) {
|
||||||
for (Contributor c : page)
|
for (Contributor c : page)
|
||||||
@@ -1150,6 +1328,18 @@ public class GHRepository extends GHObject {
|
|||||||
public int getContributions() {
|
public int getContributions() {
|
||||||
return contributions;
|
return contributions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
// We ignore contributions in the calculation
|
||||||
|
return super.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
// We ignore contributions in the calculation
|
||||||
|
return super.equals(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1178,14 +1368,9 @@ public class GHRepository extends GHObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Repository:"+owner.login+":"+name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return toString().hashCode();
|
return ("Repository:"+owner.login+":"+name).hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class GHRepositorySearchBuilder extends GHSearchBuilder<GHRepository> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHRepositorySearchBuilder sort(Sort sort) {
|
public GHRepositorySearchBuilder sort(Sort sort) {
|
||||||
req.with("sort",sort.toString().toLowerCase(Locale.ENGLISH));
|
req.with("sort",sort);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public abstract class GHSearchBuilder<T> {
|
public abstract class GHSearchBuilder<T> extends GHQueryBuilder<T> {
|
||||||
protected final GitHub root;
|
|
||||||
protected final Requester req;
|
|
||||||
protected final List<String> terms = new ArrayList<String>();
|
protected final List<String> terms = new ArrayList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,15 +19,14 @@ public abstract class GHSearchBuilder<T> {
|
|||||||
private final Class<? extends SearchResult<T>> receiverType;
|
private final Class<? extends SearchResult<T>> receiverType;
|
||||||
|
|
||||||
/*package*/ GHSearchBuilder(GitHub root, Class<? extends SearchResult<T>> receiverType) {
|
/*package*/ GHSearchBuilder(GitHub root, Class<? extends SearchResult<T>> receiverType) {
|
||||||
this.root = root;
|
super(root);
|
||||||
this.req = root.retrieve();
|
|
||||||
this.receiverType = receiverType;
|
this.receiverType = receiverType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search terms.
|
* Search terms.
|
||||||
*/
|
*/
|
||||||
public GHSearchBuilder q(String term) {
|
public GHQueryBuilder<T> q(String term) {
|
||||||
terms.add(term);
|
terms.add(term);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -37,11 +34,12 @@ public abstract class GHSearchBuilder<T> {
|
|||||||
/**
|
/**
|
||||||
* Performs the search.
|
* Performs the search.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public PagedSearchIterable<T> list() {
|
public PagedSearchIterable<T> list() {
|
||||||
return new PagedSearchIterable<T>(root) {
|
return new PagedSearchIterable<T>(root) {
|
||||||
public PagedIterator<T> iterator() {
|
public PagedIterator<T> _iterator(int pageSize) {
|
||||||
req.set("q", StringUtils.join(terms, " "));
|
req.set("q", StringUtils.join(terms, " "));
|
||||||
return new PagedIterator<T>(adapt(req.asIterator(getApiUrl(), receiverType))) {
|
return new PagedIterator<T>(adapt(req.asIterator(getApiUrl(), receiverType, pageSize))) {
|
||||||
protected void wrapUp(T[] page) {
|
protected void wrapUp(T[] page) {
|
||||||
// SearchResult.getItems() should do it
|
// SearchResult.getItems() should do it
|
||||||
}
|
}
|
||||||
|
|||||||
51
src/main/java/org/kohsuke/github/GHStargazer.java
Normal file
51
src/main/java/org/kohsuke/github/GHStargazer.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stargazer at a repository on GitHub.
|
||||||
|
*
|
||||||
|
* @author noctarius
|
||||||
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
|
public class GHStargazer {
|
||||||
|
|
||||||
|
private GHRepository repository;
|
||||||
|
private String starred_at;
|
||||||
|
private GHUser user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the repository that is stargazed
|
||||||
|
*
|
||||||
|
* @return the starred repository
|
||||||
|
*/
|
||||||
|
public GHRepository getRepository() {
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the date when the repository was starred, however old stars before
|
||||||
|
* August 2012, will all show the date the API was changed to support starred_at.
|
||||||
|
*
|
||||||
|
* @return the date the stargazer was added
|
||||||
|
*/
|
||||||
|
public Date getStarredAt() {
|
||||||
|
return GitHub.parseDate(starred_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user that starred the repository
|
||||||
|
*
|
||||||
|
* @return the stargazer user
|
||||||
|
*/
|
||||||
|
public GHUser getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapUp(GHRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
user.wrapUp(repository.root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a tag in {@link GHRepository}
|
* Represents a tag in {@link GHRepository}
|
||||||
*
|
*
|
||||||
* @see GHRepository#listTags()
|
* @see GHRepository#listTags()
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public class GHTag {
|
public class GHTag {
|
||||||
private GHRepository owner;
|
private GHRepository owner;
|
||||||
private GitHub root;
|
private GitHub root;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import java.util.TreeMap;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public class GHTeam {
|
public class GHTeam {
|
||||||
private String name,permission;
|
private String name,permission,slug;
|
||||||
private int id;
|
private int id;
|
||||||
private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together
|
private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together
|
||||||
|
|
||||||
@@ -43,17 +43,21 @@ public class GHTeam {
|
|||||||
return permission;
|
return permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSlug() {
|
||||||
|
return slug;
|
||||||
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the current members.
|
* Retrieves the current members.
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHUser> listMembers() throws IOException {
|
public PagedIterable<GHUser> listMembers() throws IOException {
|
||||||
return new PagedIterable<GHUser>() {
|
return new PagedIterable<GHUser>() {
|
||||||
public PagedIterator<GHUser> iterator() {
|
public PagedIterator<GHUser> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHUser>(org.root.retrieve().asIterator(api("/members"), GHUser[].class)) {
|
return new PagedIterator<GHUser>(org.root.retrieve().asIterator(api("/members"), GHUser[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHUser[] page) {
|
protected void wrapUp(GHUser[] page) {
|
||||||
GHUser.wrap(page, org.root);
|
GHUser.wrap(page, org.root);
|
||||||
@@ -64,8 +68,8 @@ public class GHTeam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Set<GHUser> getMembers() throws IOException {
|
public Set<GHUser> getMembers() throws IOException {
|
||||||
return Collections.unmodifiableSet(listMembers().asSet());
|
return Collections.unmodifiableSet(listMembers().asSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this team has the specified user as a member.
|
* Checks if this team has the specified user as a member.
|
||||||
@@ -89,8 +93,8 @@ public class GHTeam {
|
|||||||
|
|
||||||
public PagedIterable<GHRepository> listRepositories() {
|
public PagedIterable<GHRepository> listRepositories() {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(org.root.retrieve().asIterator(api("/repos"), GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(org.root.retrieve().asIterator(api("/repos"), GHRepository[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository r : page)
|
for (GHRepository r : page)
|
||||||
@@ -126,6 +130,13 @@ public class GHTeam {
|
|||||||
public void remove(GHRepository r) throws IOException {
|
public void remove(GHRepository r) throws IOException {
|
||||||
org.root.retrieve().method("DELETE").to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
|
org.root.retrieve().method("DELETE").to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes this team.
|
||||||
|
*/
|
||||||
|
public void delete() throws IOException {
|
||||||
|
org.root.retrieve().method("DELETE").to(api(""));
|
||||||
|
}
|
||||||
|
|
||||||
private String api(String tail) {
|
private String api(String tail) {
|
||||||
return "/teams/"+id+tail;
|
return "/teams/"+id+tail;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,6 +13,8 @@ import java.util.Date;
|
|||||||
* @see GHNotificationStream
|
* @see GHNotificationStream
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public class GHThread extends GHObject {
|
public class GHThread extends GHObject {
|
||||||
private GitHub root;
|
private GitHub root;
|
||||||
private GHRepository repository;
|
private GHRepository repository;
|
||||||
@@ -37,6 +41,14 @@ public class GHThread extends GHObject {
|
|||||||
return GitHub.parseDate(last_read_at);
|
return GitHub.parseDate(last_read_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This object has no HTML URL.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public URL getHtmlUrl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getReason() {
|
public String getReason() {
|
||||||
return reason;
|
return reason;
|
||||||
}
|
}
|
||||||
@@ -58,6 +70,45 @@ public class GHThread extends GHObject {
|
|||||||
public String getType() {
|
public String getType() {
|
||||||
return subject.type;
|
return subject.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLastCommentUrl() {
|
||||||
|
return subject.latest_comment_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this thread is about an issue, return that issue.
|
||||||
|
*
|
||||||
|
* @return null if this thread is not about an issue.
|
||||||
|
*/
|
||||||
|
public GHIssue getBoundIssue() throws IOException {
|
||||||
|
if (!"Issue".equals(subject.type) && "PullRequest".equals(subject.type))
|
||||||
|
return null;
|
||||||
|
return repository.getIssue(
|
||||||
|
Integer.parseInt(subject.url.substring(subject.url.lastIndexOf('/') + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this thread is about a pull request, return that pull request.
|
||||||
|
*
|
||||||
|
* @return null if this thread is not about a pull request.
|
||||||
|
*/
|
||||||
|
public GHPullRequest getBoundPullRequest() throws IOException {
|
||||||
|
if (!"PullRequest".equals(subject.type))
|
||||||
|
return null;
|
||||||
|
return repository.getPullRequest(
|
||||||
|
Integer.parseInt(subject.url.substring(subject.url.lastIndexOf('/') + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this thread is about a commit, return that commit.
|
||||||
|
*
|
||||||
|
* @return null if this thread is not about a commit.
|
||||||
|
*/
|
||||||
|
public GHCommit getBoundCommit() throws IOException {
|
||||||
|
if (!"Commit".equals(subject.type))
|
||||||
|
return null;
|
||||||
|
return repository.getCommit(subject.url.substring(subject.url.lastIndexOf('/') + 1));
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ GHThread wrap(GitHub root) {
|
/*package*/ GHThread wrap(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
|
|||||||
@@ -13,46 +13,46 @@ import java.util.List;
|
|||||||
* @see GHRepository#getTree(String)
|
* @see GHRepository#getTree(String)
|
||||||
*/
|
*/
|
||||||
public class GHTree {
|
public class GHTree {
|
||||||
/* package almost final */GitHub root;
|
/* package almost final */GitHub root;
|
||||||
|
|
||||||
private boolean truncated;
|
private boolean truncated;
|
||||||
private String sha, url;
|
private String sha, url;
|
||||||
private GHTreeEntry[] tree;
|
private GHTreeEntry[] tree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SHA for this trees
|
* The SHA for this trees
|
||||||
*/
|
*/
|
||||||
public String getSha() {
|
public String getSha() {
|
||||||
return sha;
|
return sha;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of entries of the trees
|
* Return an array of entries of the trees
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<GHTreeEntry> getTree() {
|
public List<GHTreeEntry> getTree() {
|
||||||
return Collections.unmodifiableList(Arrays.asList(tree));
|
return Collections.unmodifiableList(Arrays.asList(tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the number of items in the tree array exceeded the GitHub maximum limit.
|
* Returns true if the number of items in the tree array exceeded the GitHub maximum limit.
|
||||||
* @return true true if the number of items in the tree array exceeded the GitHub maximum limit otherwise false.
|
* @return true true if the number of items in the tree array exceeded the GitHub maximum limit otherwise false.
|
||||||
*/
|
*/
|
||||||
public boolean isTruncated() {
|
public boolean isTruncated() {
|
||||||
return truncated;
|
return truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The API URL of this tag, such as
|
* The API URL of this tag, such as
|
||||||
* "url": "https://api.github.com/repos/octocat/Hello-World/trees/fc6274d15fa3ae2ab983129fb037999f264ba9a7",
|
* "url": "https://api.github.com/repos/octocat/Hello-World/trees/fc6274d15fa3ae2ab983129fb037999f264ba9a7",
|
||||||
*/
|
*/
|
||||||
public URL getUrl() {
|
public URL getUrl() {
|
||||||
return GitHub.parseURL(url);
|
return GitHub.parseURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */GHTree wrap(GitHub root) {
|
/* package */GHTree wrap(GitHub root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ package org.kohsuke.github;
|
|||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -56,8 +55,14 @@ public class GHUser extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
@WithBridgeMethods(Set.class)
|
@WithBridgeMethods(Set.class)
|
||||||
public GHPersonSet<GHUser> getFollows() throws IOException {
|
public GHPersonSet<GHUser> getFollows() throws IOException {
|
||||||
GHUser[] followers = root.retrieve().to("/users/" + login + "/following", GHUser[].class);
|
return new GHPersonSet<GHUser>(listFollows().asList());
|
||||||
return new GHPersonSet<GHUser>(Arrays.asList(wrap(followers,root)));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the users that this user is following
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHUser> listFollows() {
|
||||||
|
return listUser("following");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,8 +70,26 @@ public class GHUser extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
@WithBridgeMethods(Set.class)
|
@WithBridgeMethods(Set.class)
|
||||||
public GHPersonSet<GHUser> getFollowers() throws IOException {
|
public GHPersonSet<GHUser> getFollowers() throws IOException {
|
||||||
GHUser[] followers = root.retrieve().to("/users/" + login + "/followers", GHUser[].class);
|
return new GHPersonSet<GHUser>(listFollowers().asList());
|
||||||
return new GHPersonSet<GHUser>(Arrays.asList(wrap(followers,root)));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists the users who are following this user.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHUser> listFollowers() {
|
||||||
|
return listUser("followers");
|
||||||
|
}
|
||||||
|
|
||||||
|
private PagedIterable<GHUser> listUser(final String suffix) {
|
||||||
|
return new PagedIterable<GHUser>() {
|
||||||
|
public PagedIterator<GHUser> _iterator(int pageSize) {
|
||||||
|
return new PagedIterator<GHUser>(root.retrieve().asIterator(getApiTailUrl(suffix), GHUser[].class, pageSize)) {
|
||||||
|
protected void wrapUp(GHUser[] page) {
|
||||||
|
GHUser.wrap(page,root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,9 +98,20 @@ public class GHUser extends GHPerson {
|
|||||||
* https://developer.github.com/v3/activity/watching/
|
* https://developer.github.com/v3/activity/watching/
|
||||||
*/
|
*/
|
||||||
public PagedIterable<GHRepository> listSubscriptions() {
|
public PagedIterable<GHRepository> listSubscriptions() {
|
||||||
|
return listRepositories("subscriptions");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists all the repositories that this user has starred.
|
||||||
|
*/
|
||||||
|
public PagedIterable<GHRepository> listStarredRepositories() {
|
||||||
|
return listRepositories("starred");
|
||||||
|
}
|
||||||
|
|
||||||
|
private PagedIterable<GHRepository> listRepositories(final String suffix) {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator(getApiTailUrl("subscriptions"), GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(root.retrieve().asIterator(getApiTailUrl(suffix), GHRepository[].class, pageSize)) {
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository c : page)
|
for (GHRepository c : page)
|
||||||
c.wrap(root);
|
c.wrap(root);
|
||||||
@@ -133,8 +167,8 @@ public class GHUser extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
||||||
return new PagedIterable<GHEventInfo>() {
|
return new PagedIterable<GHEventInfo>() {
|
||||||
public PagedIterator<GHEventInfo> iterator() {
|
public PagedIterator<GHEventInfo> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/users/%s/events", login), GHEventInfo[].class)) {
|
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/users/%s/events", login), GHEventInfo[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHEventInfo[] page) {
|
protected void wrapUp(GHEventInfo[] page) {
|
||||||
for (GHEventInfo c : page)
|
for (GHEventInfo c : page)
|
||||||
@@ -150,8 +184,8 @@ public class GHUser extends GHPerson {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHGist> listGists() throws IOException {
|
public PagedIterable<GHGist> listGists() throws IOException {
|
||||||
return new PagedIterable<GHGist>() {
|
return new PagedIterable<GHGist>() {
|
||||||
public PagedIterator<GHGist> iterator() {
|
public PagedIterator<GHGist> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHGist>(root.retrieve().asIterator(String.format("/users/%s/gists", login), GHGist[].class)) {
|
return new PagedIterator<GHGist>(root.retrieve().asIterator(String.format("/users/%s/gists", login), GHGist[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHGist[] page) {
|
protected void wrapUp(GHGist[] page) {
|
||||||
for (GHGist c : page)
|
for (GHGist c : page)
|
||||||
@@ -162,11 +196,6 @@ public class GHUser extends GHPerson {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "User:"+login;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return login.hashCode();
|
return login.hashCode();
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class GHUserSearchBuilder extends GHSearchBuilder<GHUser> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GHUserSearchBuilder sort(Sort sort) {
|
public GHUserSearchBuilder sort(Sort sort) {
|
||||||
req.with("sort",sort.toString().toLowerCase(Locale.ENGLISH));
|
req.with("sort",sort);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,12 +25,15 @@ package org.kohsuke.github;
|
|||||||
|
|
||||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
|
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
|
||||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
||||||
|
import static java.util.logging.Level.FINE;
|
||||||
|
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
@@ -46,12 +49,14 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.Charsets;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std;
|
import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std;
|
||||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root of the GitHub API.
|
* Root of the GitHub API.
|
||||||
@@ -60,7 +65,7 @@ import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
|||||||
* <p>
|
* <p>
|
||||||
* This library aims to be safe for use by multiple threads concurrently, although
|
* This library aims to be safe for use by multiple threads concurrently, although
|
||||||
* the library itself makes no attempt to control/serialize potentially conflicting
|
* the library itself makes no attempt to control/serialize potentially conflicting
|
||||||
* operations to GitHub, such as updating & deleting a repository at the same time.
|
* operations to GitHub, such as updating & deleting a repository at the same time.
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
@@ -127,16 +132,18 @@ public class GitHub {
|
|||||||
} else {
|
} else {
|
||||||
if (password!=null) {
|
if (password!=null) {
|
||||||
String authorization = (login + ':' + password);
|
String authorization = (login + ':' + password);
|
||||||
encodedAuthorization = "Basic "+new String(Base64.encodeBase64(authorization.getBytes()));
|
String charsetName = Charsets.UTF_8.name();
|
||||||
|
encodedAuthorization = "Basic "+new String(Base64.encodeBase64(authorization.getBytes(charsetName)), charsetName);
|
||||||
} else {// anonymous access
|
} else {// anonymous access
|
||||||
encodedAuthorization = null;
|
encodedAuthorization = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.rateLimitHandler = rateLimitHandler;
|
||||||
|
|
||||||
if (login==null && encodedAuthorization!=null)
|
if (login==null && encodedAuthorization!=null)
|
||||||
login = getMyself().getLogin();
|
login = getMyself().getLogin();
|
||||||
this.login = login;
|
this.login = login;
|
||||||
this.rateLimitHandler = rateLimitHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,6 +202,15 @@ public class GitHub {
|
|||||||
return new GitHubBuilder().build();
|
return new GitHubBuilder().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to GitHub Enterprise anonymously.
|
||||||
|
*
|
||||||
|
* All operations that requires authentication will fail.
|
||||||
|
*/
|
||||||
|
public static GitHub connectToEnterpriseAnonymously(String apiUrl) throws IOException {
|
||||||
|
return new GitHubBuilder().withEndpoint(apiUrl).build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this an anonymous connection
|
* Is this an anonymous connection
|
||||||
* @return {@code true} if operations that require authentication will fail.
|
* @return {@code true} if operations that require authentication will fail.
|
||||||
@@ -247,16 +263,18 @@ public class GitHub {
|
|||||||
// see issue #78
|
// see issue #78
|
||||||
GHRateLimit r = new GHRateLimit();
|
GHRateLimit r = new GHRateLimit();
|
||||||
r.limit = r.remaining = 1000000;
|
r.limit = r.remaining = 1000000;
|
||||||
|
long hours = 1000L * 60 * 60;
|
||||||
|
r.reset = new Date(System.currentTimeMillis() + 1 * hours );
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link GHUser} that represents yourself.
|
* Gets the {@link GHUser} that represents yourself.
|
||||||
*/
|
*/
|
||||||
@WithBridgeMethods(GHUser.class)
|
@WithBridgeMethods(GHUser.class)
|
||||||
public GHMyself getMyself() throws IOException {
|
public GHMyself getMyself() throws IOException {
|
||||||
requireCredential();
|
requireCredential();
|
||||||
|
|
||||||
GHMyself u = retrieve().to("/user", GHMyself.class);
|
GHMyself u = retrieve().to("/user", GHMyself.class);
|
||||||
|
|
||||||
@@ -264,20 +282,20 @@ public class GitHub {
|
|||||||
users.put(u.getLogin(), u);
|
users.put(u.getLogin(), u);
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the object that represents the named user.
|
* Obtains the object that represents the named user.
|
||||||
*/
|
*/
|
||||||
public GHUser getUser(String login) throws IOException {
|
public GHUser getUser(String login) throws IOException {
|
||||||
GHUser u = users.get(login);
|
GHUser u = users.get(login);
|
||||||
if (u == null) {
|
if (u == null) {
|
||||||
u = retrieve().to("/users/" + login, GHUser.class);
|
u = retrieve().to("/users/" + login, GHUser.class);
|
||||||
u.root = this;
|
u.root = this;
|
||||||
users.put(u.getLogin(), u);
|
users.put(u.getLogin(), u);
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -395,17 +413,28 @@ public class GitHub {
|
|||||||
/**
|
/**
|
||||||
* Creates a new repository.
|
* Creates a new repository.
|
||||||
*
|
*
|
||||||
* To create a repository in an organization, see
|
|
||||||
* {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean)}
|
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
* Newly created repository.
|
* Newly created repository.
|
||||||
|
* @deprecated
|
||||||
|
* Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
|
||||||
*/
|
*/
|
||||||
public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException {
|
public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException {
|
||||||
Requester requester = new Requester(this)
|
return createRepository(name).description(description).homepage(homepage).private_(!isPublic).create();
|
||||||
.with("name", name).with("description", description).with("homepage", homepage)
|
}
|
||||||
.with("public", isPublic ? 1 : 0);
|
|
||||||
return requester.method("POST").to("/user/repos", GHRepository.class).wrap(this);
|
/**
|
||||||
|
* Starts a builder that creates a new repository.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()}
|
||||||
|
* to finally createa repository.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* To create a repository in an organization, see
|
||||||
|
* {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean)}
|
||||||
|
*/
|
||||||
|
public GHCreateRepositoryBuilder createRepository(String name) {
|
||||||
|
return new GHCreateRepositoryBuilder(this,"/user/repos",name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -415,14 +444,14 @@ public class GitHub {
|
|||||||
*
|
*
|
||||||
* @see <a href="http://developer.github.com/v3/oauth/#create-a-new-authorization">Documentation</a>
|
* @see <a href="http://developer.github.com/v3/oauth/#create-a-new-authorization">Documentation</a>
|
||||||
*/
|
*/
|
||||||
public GHAuthorization createToken(Collection<String> scope, String note, String noteUrl) throws IOException{
|
public GHAuthorization createToken(Collection<String> scope, String note, String noteUrl) throws IOException{
|
||||||
Requester requester = new Requester(this)
|
Requester requester = new Requester(this)
|
||||||
.with("scopes", scope)
|
.with("scopes", scope)
|
||||||
.with("note", note)
|
.with("note", note)
|
||||||
.with("note_url", noteUrl);
|
.with("note_url", noteUrl);
|
||||||
|
|
||||||
return requester.method("POST").to("/authorizations", GHAuthorization.class).wrap(this);
|
return requester.method("POST").to("/authorizations", GHAuthorization.class).wrap(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the credential is valid.
|
* Ensures that the credential is valid.
|
||||||
@@ -431,6 +460,76 @@ public class GitHub {
|
|||||||
try {
|
try {
|
||||||
retrieve().to("/user", GHUser.class);
|
retrieve().to("/user", GHUser.class);
|
||||||
return true;
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (LOGGER.isLoggable(FINE))
|
||||||
|
LOGGER.log(FINE, "Exception validating credentials on " + this.apiUrl + " with login '" + this.login + "' " + e, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GHApiInfo {
|
||||||
|
private String rate_limit_url;
|
||||||
|
|
||||||
|
void check(String apiUrl) throws IOException {
|
||||||
|
if (rate_limit_url==null)
|
||||||
|
throw new IOException(apiUrl+" doesn't look like GitHub API URL");
|
||||||
|
|
||||||
|
// make sure that the URL is legitimate
|
||||||
|
new URL(rate_limit_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the connection.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Verify that the API URL and credentials are valid to access this GitHub.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method returns normally if the endpoint is reachable and verified to be GitHub API URL.
|
||||||
|
* Otherwise this method throws {@link IOException} to indicate the problem.
|
||||||
|
*/
|
||||||
|
public void checkApiUrlValidity() throws IOException {
|
||||||
|
try {
|
||||||
|
retrieve().to("/", GHApiInfo.class).check(apiUrl);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (isPrivateModeEnabled()) {
|
||||||
|
throw (IOException)new IOException("GitHub Enterprise server (" + apiUrl + ") with private mode enabled").initCause(e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures if a GitHub Enterprise server is configured in private mode.
|
||||||
|
*
|
||||||
|
* @return {@code true} if private mode is enabled. If it tries to use this method with GitHub, returns {@code
|
||||||
|
* false}.
|
||||||
|
*/
|
||||||
|
private boolean isPrivateModeEnabled() {
|
||||||
|
try {
|
||||||
|
HttpURLConnection uc = getConnector().connect(getApiURL("/"));
|
||||||
|
/*
|
||||||
|
$ curl -i https://github.mycompany.com/api/v3/
|
||||||
|
HTTP/1.1 401 Unauthorized
|
||||||
|
Server: GitHub.com
|
||||||
|
Date: Sat, 05 Mar 2016 19:45:01 GMT
|
||||||
|
Content-Type: application/json; charset=utf-8
|
||||||
|
Content-Length: 130
|
||||||
|
Status: 401 Unauthorized
|
||||||
|
X-GitHub-Media-Type: github.v3
|
||||||
|
X-XSS-Protection: 1; mode=block
|
||||||
|
X-Frame-Options: deny
|
||||||
|
Content-Security-Policy: default-src 'none'
|
||||||
|
Access-Control-Allow-Credentials: true
|
||||||
|
Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
|
||||||
|
Access-Control-Allow-Origin: *
|
||||||
|
X-GitHub-Request-Id: dbc70361-b11d-4131-9a7f-674b8edd0411
|
||||||
|
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
|
||||||
|
X-Content-Type-Options: nosniff
|
||||||
|
*/
|
||||||
|
return uc.getResponseCode() == HTTP_UNAUTHORIZED
|
||||||
|
&& uc.getHeaderField("X-GitHub-Media-Type") != null;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -488,8 +587,8 @@ public class GitHub {
|
|||||||
*/
|
*/
|
||||||
public PagedIterable<GHRepository> listAllPublicRepositories(final String since) {
|
public PagedIterable<GHRepository> listAllPublicRepositories(final String since) {
|
||||||
return new PagedIterable<GHRepository>() {
|
return new PagedIterable<GHRepository>() {
|
||||||
public PagedIterator<GHRepository> iterator() {
|
public PagedIterator<GHRepository> _iterator(int pageSize) {
|
||||||
return new PagedIterator<GHRepository>(retrieve().with("since",since).asIterator("/repositories", GHRepository[].class)) {
|
return new PagedIterator<GHRepository>(retrieve().with("since",since).asIterator("/repositories", GHRepository[].class, pageSize)) {
|
||||||
@Override
|
@Override
|
||||||
protected void wrapUp(GHRepository[] page) {
|
protected void wrapUp(GHRepository[] page) {
|
||||||
for (GHRepository c : page)
|
for (GHRepository c : page)
|
||||||
@@ -555,4 +654,6 @@ public class GitHub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static final String GITHUB_URL = "https://api.github.com";
|
/* package */ static final String GITHUB_URL = "https://api.github.com";
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(GitHub.class.getName());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.kohsuke.github.extras.ImpatientHttpConnector;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -14,7 +15,7 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Configures connection details and produces {@link GitHub}.
|
||||||
*
|
*
|
||||||
* @since 1.59
|
* @since 1.59
|
||||||
*/
|
*/
|
||||||
@@ -45,22 +46,22 @@ public class GitHubBuilder {
|
|||||||
* @throws IOException If there are no credentials defined in the ~/.github properties file or the process environment.
|
* @throws IOException If there are no credentials defined in the ~/.github properties file or the process environment.
|
||||||
*/
|
*/
|
||||||
public static GitHubBuilder fromCredentials() throws IOException {
|
public static GitHubBuilder fromCredentials() throws IOException {
|
||||||
Exception cause = null;
|
Exception cause = null;
|
||||||
GitHubBuilder builder;
|
GitHubBuilder builder;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
builder = fromPropertyFile();
|
builder = fromPropertyFile();
|
||||||
|
|
||||||
if (builder.user != null)
|
if (builder.oauthToken != null || builder.user != null)
|
||||||
return builder;
|
return builder;
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
// fall through
|
// fall through
|
||||||
cause = e;
|
cause = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder = fromEnvironment();
|
builder = fromEnvironment();
|
||||||
|
|
||||||
if (builder.user != null)
|
if (builder.oauthToken != null || builder.user != null)
|
||||||
return builder;
|
return builder;
|
||||||
else
|
else
|
||||||
throw (IOException)new IOException("Failed to resolve credentials from ~/.github or the environment.").initCause(cause);
|
throw (IOException)new IOException("Failed to resolve credentials from ~/.github or the environment.").initCause(cause);
|
||||||
@@ -77,8 +78,8 @@ public class GitHubBuilder {
|
|||||||
|
|
||||||
private static void loadIfSet(String envName, Properties p, String propName) {
|
private static void loadIfSet(String envName, Properties p, String propName) {
|
||||||
String v = System.getenv(envName);
|
String v = System.getenv(envName);
|
||||||
if (v != null)
|
if (v != null)
|
||||||
p.put(propName, v);
|
p.put(propName, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,12 +88,12 @@ public class GitHubBuilder {
|
|||||||
* different clients of this library will all recognize one consistent set of coordinates.
|
* different clients of this library will all recognize one consistent set of coordinates.
|
||||||
*/
|
*/
|
||||||
public static GitHubBuilder fromEnvironment(String loginVariableName, String passwordVariableName, String oauthVariableName, String endpointVariableName) throws IOException {
|
public static GitHubBuilder fromEnvironment(String loginVariableName, String passwordVariableName, String oauthVariableName, String endpointVariableName) throws IOException {
|
||||||
Properties env = new Properties();
|
Properties env = new Properties();
|
||||||
loadIfSet(loginVariableName,env,"login");
|
loadIfSet(loginVariableName,env,"login");
|
||||||
loadIfSet(passwordVariableName,env,"password");
|
loadIfSet(passwordVariableName,env,"password");
|
||||||
loadIfSet(oauthVariableName,env,"oauth");
|
loadIfSet(oauthVariableName,env,"oauth");
|
||||||
loadIfSet(endpointVariableName,env,"endpoint");
|
loadIfSet(endpointVariableName,env,"endpoint");
|
||||||
return fromProperties(env);
|
return fromProperties(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,7 +117,7 @@ public class GitHubBuilder {
|
|||||||
* login, password, oauth
|
* login, password, oauth
|
||||||
*/
|
*/
|
||||||
public static GitHubBuilder fromEnvironment() throws IOException {
|
public static GitHubBuilder fromEnvironment() throws IOException {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
for (Entry<String, String> e : System.getenv().entrySet()) {
|
for (Entry<String, String> e : System.getenv().entrySet()) {
|
||||||
String name = e.getKey().toLowerCase(Locale.ENGLISH);
|
String name = e.getKey().toLowerCase(Locale.ENGLISH);
|
||||||
if (name.startsWith("github_")) name=name.substring(7);
|
if (name.startsWith("github_")) name=name.substring(7);
|
||||||
@@ -184,11 +185,11 @@ public class GitHubBuilder {
|
|||||||
* the system default one.
|
* the system default one.
|
||||||
*/
|
*/
|
||||||
public GitHubBuilder withProxy(final Proxy p) {
|
public GitHubBuilder withProxy(final Proxy p) {
|
||||||
return withConnector(new HttpConnector() {
|
return withConnector(new ImpatientHttpConnector(new HttpConnector() {
|
||||||
public HttpURLConnection connect(URL url) throws IOException {
|
public HttpURLConnection connect(URL url) throws IOException {
|
||||||
return (HttpURLConnection) url.openConnection(p);
|
return (HttpURLConnection) url.openConnection(p);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GitHub build() throws IOException {
|
public GitHub build() throws IOException {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,6 +12,8 @@ import java.util.Date;
|
|||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
|
||||||
public class GitUser {
|
public class GitUser {
|
||||||
private String name, email, date;
|
private String name, email, date;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.kohsuke.github.extras.ImpatientHttpConnector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pluggability for customizing HTTP request behaviors or using altogether different library.
|
* Pluggability for customizing HTTP request behaviors or using altogether different library.
|
||||||
@@ -21,9 +24,9 @@ public interface HttpConnector {
|
|||||||
/**
|
/**
|
||||||
* Default implementation that uses {@link URL#openConnection()}.
|
* Default implementation that uses {@link URL#openConnection()}.
|
||||||
*/
|
*/
|
||||||
HttpConnector DEFAULT = new HttpConnector() {
|
HttpConnector DEFAULT = new ImpatientHttpConnector(new HttpConnector() {
|
||||||
public HttpURLConnection connect(URL url) throws IOException {
|
public HttpURLConnection connect(URL url) throws IOException {
|
||||||
return (HttpURLConnection) url.openConnection();
|
return (HttpURLConnection) url.openConnection();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
118
src/main/java/org/kohsuke/github/HttpException.java
Normal file
118
src/main/java/org/kohsuke/github/HttpException.java
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link IOException} for http exceptions because {@link HttpURLConnection} throws un-discerned
|
||||||
|
* {@link IOException} and it can help to know the http response code to decide how to handle an
|
||||||
|
* http exceptions.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a>
|
||||||
|
*/
|
||||||
|
public class HttpException extends IOException {
|
||||||
|
static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final int responseCode;
|
||||||
|
private final String responseMessage;
|
||||||
|
private final String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message The detail message (which is saved for later retrieval
|
||||||
|
* by the {@link #getMessage()} method)
|
||||||
|
* @param responseCode Http response code. {@code -1} if no code can be discerned.
|
||||||
|
* @param responseMessage Http response message
|
||||||
|
* @param url The url that was invoked
|
||||||
|
* @see HttpURLConnection#getResponseCode()
|
||||||
|
* @see HttpURLConnection#getResponseMessage()
|
||||||
|
*/
|
||||||
|
public HttpException(String message, int responseCode, String responseMessage, String url) {
|
||||||
|
super(message);
|
||||||
|
this.responseCode = responseCode;
|
||||||
|
this.responseMessage = responseMessage;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message The detail message (which is saved for later retrieval
|
||||||
|
* by the {@link #getMessage()} method)
|
||||||
|
* @param responseCode Http response code. {@code -1} if no code can be discerned.
|
||||||
|
* @param responseMessage Http response message
|
||||||
|
* @param url The url that was invoked
|
||||||
|
* @param cause The cause (which is saved for later retrieval by the
|
||||||
|
* {@link #getCause()} method). (A null value is permitted,
|
||||||
|
* and indicates that the cause is nonexistent or unknown.)
|
||||||
|
* @see HttpURLConnection#getResponseCode()
|
||||||
|
* @see HttpURLConnection#getResponseMessage()
|
||||||
|
*/
|
||||||
|
public HttpException(String message, int responseCode, String responseMessage, String url, Throwable cause) {
|
||||||
|
super(message);
|
||||||
|
initCause(cause);
|
||||||
|
this.responseCode = responseCode;
|
||||||
|
this.responseMessage = responseMessage;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param responseCode Http response code. {@code -1} if no code can be discerned.
|
||||||
|
* @param responseMessage Http response message
|
||||||
|
* @param url The url that was invoked
|
||||||
|
* @param cause The cause (which is saved for later retrieval by the
|
||||||
|
* {@link #getCause()} method). (A null value is permitted,
|
||||||
|
* and indicates that the cause is nonexistent or unknown.)
|
||||||
|
* @see HttpURLConnection#getResponseCode()
|
||||||
|
* @see HttpURLConnection#getResponseMessage()
|
||||||
|
*/
|
||||||
|
public HttpException(int responseCode, String responseMessage, String url, Throwable cause) {
|
||||||
|
super("Server returned HTTP response code: " + responseCode + ", message: '" + responseMessage + "'" +
|
||||||
|
" for URL: " + url);
|
||||||
|
initCause(cause);
|
||||||
|
this.responseCode = responseCode;
|
||||||
|
this.responseMessage = responseMessage;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param responseCode Http response code. {@code -1} if no code can be discerned.
|
||||||
|
* @param responseMessage Http response message
|
||||||
|
* @param url The url that was invoked
|
||||||
|
* @param cause The cause (which is saved for later retrieval by the
|
||||||
|
* {@link #getCause()} method). (A null value is permitted,
|
||||||
|
* and indicates that the cause is nonexistent or unknown.)
|
||||||
|
* @see HttpURLConnection#getResponseCode()
|
||||||
|
* @see HttpURLConnection#getResponseMessage()
|
||||||
|
*/
|
||||||
|
public HttpException(int responseCode, String responseMessage, @CheckForNull URL url, Throwable cause) {
|
||||||
|
this(responseCode, responseMessage, url == null ? null : url.toString(), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http response code of the request that cause the exception
|
||||||
|
*
|
||||||
|
* @return {@code -1} if no code can be discerned.
|
||||||
|
*/
|
||||||
|
public int getResponseCode() {
|
||||||
|
return responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http response message of the request that cause the exception
|
||||||
|
*
|
||||||
|
* @return {@code null} if no response message can be discerned.
|
||||||
|
*/
|
||||||
|
public String getResponseMessage() {
|
||||||
|
return responseMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The http URL that caused the exception
|
||||||
|
*
|
||||||
|
* @return url
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -11,7 +12,27 @@ import java.util.Set;
|
|||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
public abstract class PagedIterable<T> implements Iterable<T> {
|
public abstract class PagedIterable<T> implements Iterable<T> {
|
||||||
public abstract PagedIterator<T> iterator();
|
/**
|
||||||
|
* Page size. 0 is default.
|
||||||
|
*/
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pagination size.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* When set to non-zero, each API call will retrieve this many entries.
|
||||||
|
*/
|
||||||
|
public PagedIterable<T> withPageSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final PagedIterator<T> iterator() {
|
||||||
|
return _iterator(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract PagedIterator<T> _iterator(int pageSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Eagerly walk {@link Iterable} and return the result in a list.
|
* Eagerly walk {@link Iterable} and return the result in a list.
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,6 +10,8 @@ import java.util.Iterator;
|
|||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
|
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
|
||||||
|
"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"}, justification = "Constructed by JSON API")
|
||||||
public abstract class PagedSearchIterable<T> extends PagedIterable<T> {
|
public abstract class PagedSearchIterable<T> extends PagedIterable<T> {
|
||||||
private final GitHub root;
|
private final GitHub root;
|
||||||
|
|
||||||
@@ -19,6 +24,11 @@ public abstract class PagedSearchIterable<T> extends PagedIterable<T> {
|
|||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PagedSearchIterable<T> withPageSize(int size) {
|
||||||
|
return (PagedSearchIterable<T>)super.withPageSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the total number of hit, including the results that's not yet fetched.
|
* Returns the total number of hit, including the results that's not yet fetched.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -42,17 +43,21 @@ import java.net.URLEncoder;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
import javax.annotation.WillClose;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.logging.Level.FINE;
|
||||||
import static org.kohsuke.github.GitHub.*;
|
import static org.kohsuke.github.GitHub.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,6 +105,11 @@ class Requester {
|
|||||||
headers.put(name,value);
|
headers.put(name,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Requester withHeader(String name, String value) {
|
||||||
|
setHeader(name,value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request with authentication credential.
|
* Makes a request with authentication credential.
|
||||||
*/
|
*/
|
||||||
@@ -116,7 +126,7 @@ class Requester {
|
|||||||
|
|
||||||
public Requester with(String key, Integer value) {
|
public Requester with(String key, Integer value) {
|
||||||
if (value!=null)
|
if (value!=null)
|
||||||
_with(key, value.intValue());
|
_with(key, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +137,14 @@ class Requester {
|
|||||||
return _with(key, value);
|
return _with(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Requester with(String key, Enum e) {
|
||||||
|
if (e==null) return _with(key, null);
|
||||||
|
|
||||||
|
// by convention Java constant names are upper cases, but github uses
|
||||||
|
// lower-case constants. GitHub also uses '-', which in Java we always
|
||||||
|
// replace by '_'
|
||||||
|
return with(key, e.toString().toLowerCase(Locale.ENGLISH).replace('_', '-'));
|
||||||
|
}
|
||||||
|
|
||||||
public Requester with(String key, String value) {
|
public Requester with(String key, String value) {
|
||||||
return _with(key, value);
|
return _with(key, value);
|
||||||
@@ -140,7 +158,7 @@ class Requester {
|
|||||||
return _with(key, value);
|
return _with(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Requester with(InputStream body) {
|
public Requester with(@WillClose/*later*/ InputStream body) {
|
||||||
this.body = body;
|
this.body = body;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -203,19 +221,24 @@ class Requester {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public <T> T to(String tailApiUrl, Class<T> type, String method) throws IOException {
|
public <T> T to(String tailApiUrl, Class<T> type, String method) throws IOException {
|
||||||
return method(method).to(tailApiUrl,type);
|
return method(method).to(tailApiUrl, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings("SBSC_USE_STRINGBUFFER_CONCATENATION")
|
||||||
private <T> T _to(String tailApiUrl, Class<T> type, T instance) throws IOException {
|
private <T> T _to(String tailApiUrl, Class<T> type, T instance) throws IOException {
|
||||||
while (true) {// loop while API rate limit is hit
|
if (METHODS_WITHOUT_BODY.contains(method) && !args.isEmpty()) {
|
||||||
if (method.equals("GET") && !args.isEmpty()) {
|
boolean questionMarkFound = tailApiUrl.indexOf('?') != -1;
|
||||||
StringBuilder qs=new StringBuilder();
|
tailApiUrl += questionMarkFound ? '&' : '?';
|
||||||
for (Entry arg : args) {
|
for (Iterator<Entry> it = args.listIterator(); it.hasNext();) {
|
||||||
qs.append(qs.length()==0 ? '?' : '&');
|
Entry arg = it.next();
|
||||||
qs.append(arg.key).append('=').append(URLEncoder.encode(arg.value.toString(),"UTF-8"));
|
tailApiUrl += arg.key + '=' + URLEncoder.encode(arg.value.toString(),"UTF-8");
|
||||||
|
if (it.hasNext()) {
|
||||||
|
tailApiUrl += '&';
|
||||||
}
|
}
|
||||||
tailApiUrl += qs.toString();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {// loop while API rate limit is hit
|
||||||
setupConnection(root.getApiURL(tailApiUrl));
|
setupConnection(root.getApiURL(tailApiUrl));
|
||||||
|
|
||||||
buildRequest();
|
buildRequest();
|
||||||
@@ -252,6 +275,7 @@ class Requester {
|
|||||||
*/
|
*/
|
||||||
public int asHttpStatusCode(String tailApiUrl) throws IOException {
|
public int asHttpStatusCode(String tailApiUrl) throws IOException {
|
||||||
while (true) {// loop while API rate limit is hit
|
while (true) {// loop while API rate limit is hit
|
||||||
|
method("GET");
|
||||||
setupConnection(root.getApiURL(tailApiUrl));
|
setupConnection(root.getApiURL(tailApiUrl));
|
||||||
|
|
||||||
buildRequest();
|
buildRequest();
|
||||||
@@ -269,7 +293,7 @@ class Requester {
|
|||||||
setupConnection(root.getApiURL(tailApiUrl));
|
setupConnection(root.getApiURL(tailApiUrl));
|
||||||
|
|
||||||
buildRequest();
|
buildRequest();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return wrapStream(uc.getInputStream());
|
return wrapStream(uc.getInputStream());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -287,7 +311,7 @@ class Requester {
|
|||||||
* Set up the request parameters or POST payload.
|
* Set up the request parameters or POST payload.
|
||||||
*/
|
*/
|
||||||
private void buildRequest() throws IOException {
|
private void buildRequest() throws IOException {
|
||||||
if (!method.equals("GET")) {
|
if (isMethodWithBody()) {
|
||||||
uc.setDoOutput(true);
|
uc.setDoOutput(true);
|
||||||
uc.setRequestProperty("Content-type", contentType);
|
uc.setRequestProperty("Content-type", contentType);
|
||||||
|
|
||||||
@@ -311,106 +335,121 @@ class Requester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isMethodWithBody() {
|
||||||
|
return !METHODS_WITHOUT_BODY.contains(method);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads pagenated resources.
|
* Loads pagenated resources.
|
||||||
*
|
*
|
||||||
* Every iterator call reports a new batch.
|
* Every iterator call reports a new batch.
|
||||||
*/
|
*/
|
||||||
/*package*/ <T> Iterator<T> asIterator(String _tailApiUrl, final Class<T> type) {
|
/*package*/ <T> Iterator<T> asIterator(String tailApiUrl, Class<T> type, int pageSize) {
|
||||||
method("GET");
|
method("GET");
|
||||||
|
|
||||||
|
if (pageSize!=0)
|
||||||
|
args.add(new Entry("per_page",pageSize));
|
||||||
|
|
||||||
|
StringBuilder s = new StringBuilder(tailApiUrl);
|
||||||
if (!args.isEmpty()) {
|
if (!args.isEmpty()) {
|
||||||
boolean first=true;
|
boolean first = true;
|
||||||
try {
|
try {
|
||||||
for (Entry a : args) {
|
for (Entry a : args) {
|
||||||
_tailApiUrl += first ? '?' : '&';
|
s.append(first ? '?' : '&');
|
||||||
first = false;
|
first = false;
|
||||||
_tailApiUrl += URLEncoder.encode(a.key,"UTF-8")+'='+URLEncoder.encode(a.value.toString(),"UTF-8");
|
s.append(URLEncoder.encode(a.key, "UTF-8"));
|
||||||
|
s.append('=');
|
||||||
|
s.append(URLEncoder.encode(a.value.toString(), "UTF-8"));
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new AssertionError(e); // UTF-8 is mandatory
|
throw new AssertionError(e); // UTF-8 is mandatory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String tailApiUrl = _tailApiUrl;
|
try {
|
||||||
|
return new PagingIterator<T>(type, root.getApiURL(s.toString()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Iterator<T>() {
|
class PagingIterator<T> implements Iterator<T> {
|
||||||
/**
|
|
||||||
* The next batch to be returned from {@link #next()}.
|
|
||||||
*/
|
|
||||||
T next;
|
|
||||||
/**
|
|
||||||
* URL of the next resource to be retrieved, or null if no more data is available.
|
|
||||||
*/
|
|
||||||
URL url;
|
|
||||||
|
|
||||||
{
|
private final Class<T> type;
|
||||||
try {
|
|
||||||
url = root.getApiURL(tailApiUrl);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
/**
|
||||||
fetch();
|
* The next batch to be returned from {@link #next()}.
|
||||||
return next!=null;
|
*/
|
||||||
}
|
private T next;
|
||||||
|
|
||||||
public T next() {
|
/**
|
||||||
fetch();
|
* URL of the next resource to be retrieved, or null if no more data is available.
|
||||||
T r = next;
|
*/
|
||||||
if (r==null) throw new NoSuchElementException();
|
private URL url;
|
||||||
next = null;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
PagingIterator(Class<T> type, URL url) {
|
||||||
throw new UnsupportedOperationException();
|
this.url = url;
|
||||||
}
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
private void fetch() {
|
public boolean hasNext() {
|
||||||
if (next!=null) return; // already fetched
|
fetch();
|
||||||
if (url==null) return; // no more data to fetch
|
return next!=null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
public T next() {
|
||||||
while (true) {// loop while API rate limit is hit
|
fetch();
|
||||||
setupConnection(url);
|
T r = next;
|
||||||
try {
|
if (r==null) throw new NoSuchElementException();
|
||||||
next = parse(type,null);
|
next = null;
|
||||||
assert next!=null;
|
return r;
|
||||||
findNextURL();
|
}
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
|
||||||
handleApiError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public void remove() {
|
||||||
* Locate the next page from the pagination "Link" tag.
|
throw new UnsupportedOperationException();
|
||||||
*/
|
}
|
||||||
private void findNextURL() throws MalformedURLException {
|
|
||||||
url = null; // start defensively
|
|
||||||
String link = uc.getHeaderField("Link");
|
|
||||||
if (link==null) return;
|
|
||||||
|
|
||||||
for (String token : link.split(", ")) {
|
private void fetch() {
|
||||||
if (token.endsWith("rel=\"next\"")) {
|
if (next!=null) return; // already fetched
|
||||||
// found the next page. This should look something like
|
if (url==null) return; // no more data to fetch
|
||||||
// <https://api.github.com/repos?page=3&per_page=100>; rel="next"
|
|
||||||
int idx = token.indexOf('>');
|
try {
|
||||||
url = new URL(token.substring(1,idx));
|
while (true) {// loop while API rate limit is hit
|
||||||
|
setupConnection(url);
|
||||||
|
try {
|
||||||
|
next = parse(type,null);
|
||||||
|
assert next!=null;
|
||||||
|
findNextURL();
|
||||||
return;
|
return;
|
||||||
|
} catch (IOException e) {
|
||||||
|
handleApiError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
// no more "next" link. we are done.
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locate the next page from the pagination "Link" tag.
|
||||||
|
*/
|
||||||
|
private void findNextURL() throws MalformedURLException {
|
||||||
|
url = null; // start defensively
|
||||||
|
String link = uc.getHeaderField("Link");
|
||||||
|
if (link==null) return;
|
||||||
|
|
||||||
|
for (String token : link.split(", ")) {
|
||||||
|
if (token.endsWith("rel=\"next\"")) {
|
||||||
|
// found the next page. This should look something like
|
||||||
|
// <https://api.github.com/repos?page=3&per_page=100>; rel="next"
|
||||||
|
int idx = token.indexOf('>');
|
||||||
|
url = new URL(token.substring(1,idx));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no more "next" link. we are done.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -428,6 +467,11 @@ class Requester {
|
|||||||
uc.setRequestProperty(e.getKey(), v);
|
uc.setRequestProperty(e.getKey(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setRequestMethod(uc);
|
||||||
|
uc.setRequestProperty("Accept-Encoding", "gzip");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRequestMethod(HttpURLConnection uc) throws IOException {
|
||||||
try {
|
try {
|
||||||
uc.setRequestMethod(method);
|
uc.setRequestMethod(method);
|
||||||
} catch (ProtocolException e) {
|
} catch (ProtocolException e) {
|
||||||
@@ -439,26 +483,53 @@ class Requester {
|
|||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
throw (IOException)new IOException("Failed to set the custom verb").initCause(x);
|
throw (IOException)new IOException("Failed to set the custom verb").initCause(x);
|
||||||
}
|
}
|
||||||
|
// sun.net.www.protocol.https.DelegatingHttpsURLConnection delegates to another HttpURLConnection
|
||||||
|
try {
|
||||||
|
Field $delegate = uc.getClass().getDeclaredField("delegate");
|
||||||
|
$delegate.setAccessible(true);
|
||||||
|
Object delegate = $delegate.get(uc);
|
||||||
|
if (delegate instanceof HttpURLConnection) {
|
||||||
|
HttpURLConnection nested = (HttpURLConnection) delegate;
|
||||||
|
setRequestMethod(nested);
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException x) {
|
||||||
|
// no problem
|
||||||
|
} catch (IllegalAccessException x) {
|
||||||
|
throw (IOException)new IOException("Failed to set the custom verb").initCause(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uc.setRequestProperty("Accept-Encoding", "gzip");
|
if (!uc.getRequestMethod().equals(method))
|
||||||
|
throw new IllegalStateException("Failed to set the request method to "+method);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T parse(Class<T> type, T instance) throws IOException {
|
private <T> T parse(Class<T> type, T instance) throws IOException {
|
||||||
if (uc.getResponseCode()==304)
|
|
||||||
return null; // special case handling for 304 unmodified, as the content will be ""
|
|
||||||
InputStreamReader r = null;
|
InputStreamReader r = null;
|
||||||
|
int responseCode = -1;
|
||||||
|
String responseMessage = null;
|
||||||
try {
|
try {
|
||||||
|
responseCode = uc.getResponseCode();
|
||||||
|
responseMessage = uc.getResponseMessage();
|
||||||
|
if (responseCode == 304) {
|
||||||
|
return null; // special case handling for 304 unmodified, as the content will be ""
|
||||||
|
}
|
||||||
|
|
||||||
r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
|
r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
|
||||||
String data = IOUtils.toString(r);
|
String data = IOUtils.toString(r);
|
||||||
if (type!=null)
|
if (type!=null)
|
||||||
try {
|
try {
|
||||||
return MAPPER.readValue(data,type);
|
return MAPPER.readValue(data,type);
|
||||||
} catch (JsonMappingException e) {
|
} catch (JsonMappingException e) {
|
||||||
throw (IOException)new IOException("Failed to deserialize "+data).initCause(e);
|
throw (IOException)new IOException("Failed to deserialize " +data).initCause(e);
|
||||||
}
|
}
|
||||||
if (instance!=null)
|
if (instance!=null)
|
||||||
return MAPPER.readerForUpdating(instance).<T>readValue(data);
|
return MAPPER.readerForUpdating(instance).<T>readValue(data);
|
||||||
return null;
|
return null;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in HttpException
|
||||||
|
// to preserve backward compatibility
|
||||||
|
throw e;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new HttpException(responseCode, responseMessage, uc.getURL(), e);
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(r);
|
IOUtils.closeQuietly(r);
|
||||||
}
|
}
|
||||||
@@ -479,8 +550,23 @@ class Requester {
|
|||||||
* Handle API error by either throwing it or by returning normally to retry.
|
* Handle API error by either throwing it or by returning normally to retry.
|
||||||
*/
|
*/
|
||||||
/*package*/ void handleApiError(IOException e) throws IOException {
|
/*package*/ void handleApiError(IOException e) throws IOException {
|
||||||
|
int responseCode;
|
||||||
|
try {
|
||||||
|
responseCode = uc.getResponseCode();
|
||||||
|
} catch (IOException e2) {
|
||||||
|
// likely to be a network exception (e.g. SSLHandshakeException),
|
||||||
|
// uc.getResponseCode() and any other getter on the response will cause an exception
|
||||||
|
if (LOGGER.isLoggable(FINE))
|
||||||
|
LOGGER.log(FINE, "Silently ignore exception retrieving response code for '" + uc.getURL() + "'" +
|
||||||
|
" handling exception " + e, e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds
|
||||||
|
throw e;
|
||||||
|
|
||||||
if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) {
|
if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) {
|
||||||
root.rateLimitHandler.onError(e,uc);
|
root.rateLimitHandler.onError(e,uc);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream es = wrapStream(uc.getErrorStream());
|
InputStream es = wrapStream(uc.getErrorStream());
|
||||||
@@ -498,10 +584,6 @@ class Requester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> toSet(String s) {
|
private static final List<String> METHODS_WITHOUT_BODY = asList("GET", "DELETE");
|
||||||
Set<String> r = new HashSet<String>();
|
private static final Logger LOGGER = Logger.getLogger(Requester.class.getName());
|
||||||
for (String t : s.split(","))
|
|
||||||
r.add(t.trim());
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the result of a search
|
* Represents the result of a search
|
||||||
*
|
*
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
*/
|
*/
|
||||||
abstract class SearchResult<T> {
|
abstract class SearchResult<T> {
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||||
int total_count;
|
int total_count;
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||||
boolean incomplete_results;
|
boolean incomplete_results;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
16
src/main/java/org/kohsuke/github/SkipFromToString.java
Normal file
16
src/main/java/org/kohsuke/github/SkipFromToString.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignores this field for {@link GHObject#toString()}
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@interface SkipFromToString {
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.kohsuke.github.extras;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import org.kohsuke.github.HttpConnector;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HttpConnector} wrapper that sets timeout
|
||||||
|
*
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public class ImpatientHttpConnector implements HttpConnector {
|
||||||
|
private final HttpConnector base;
|
||||||
|
private final int readTimeout, connectTimeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param connectTimeout
|
||||||
|
* HTTP connection timeout in milliseconds
|
||||||
|
* @param readTimeout
|
||||||
|
* HTTP read timeout in milliseconds
|
||||||
|
*/
|
||||||
|
public ImpatientHttpConnector(HttpConnector base, int connectTimeout, int readTimeout) {
|
||||||
|
this.base = base;
|
||||||
|
this.connectTimeout = connectTimeout;
|
||||||
|
this.readTimeout = readTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImpatientHttpConnector(HttpConnector base, int timeout) {
|
||||||
|
this(base,timeout,timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImpatientHttpConnector(HttpConnector base) {
|
||||||
|
this(base,CONNECT_TIMEOUT,READ_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpURLConnection connect(URL url) throws IOException {
|
||||||
|
HttpURLConnection con = base.connect(url);
|
||||||
|
con.setConnectTimeout(connectTimeout);
|
||||||
|
con.setReadTimeout(readTimeout);
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default connection timeout in milliseconds
|
||||||
|
*/
|
||||||
|
@SuppressFBWarnings("MS_SHOULD_BE_FINAL")
|
||||||
|
public static int CONNECT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default read timeout in milliseconds
|
||||||
|
*/
|
||||||
|
@SuppressFBWarnings("MS_SHOULD_BE_FINAL")
|
||||||
|
public static int READ_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import org.kohsuke.github.GHRepository;
|
import org.kohsuke.github.GHRepository;
|
||||||
|
import org.kohsuke.github.GHUser;
|
||||||
import org.kohsuke.github.GitHub;
|
import org.kohsuke.github.GitHub;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -14,4 +15,11 @@ public class Foo {
|
|||||||
}
|
}
|
||||||
System.out.println(lst.size());
|
System.out.println(lst.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testRateLimit() throws Exception {
|
||||||
|
GitHub g = GitHub.connectAnonymously();
|
||||||
|
for (GHUser u : g.getOrganization("jenkinsci").listMembers()) {
|
||||||
|
u.getFollowersCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ public abstract class AbstractGitHubApiTestBase extends Assert {
|
|||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
// use the non-standard credential preferentially, so that developers of this library do not have
|
// use the non-standard credential preferentially, so that developers of this library do not have
|
||||||
// to clutter their event stream.
|
// to clutter their event stream.
|
||||||
gitHub = GitHubBuilder.fromPropertyFile(f.getPath()).build();
|
gitHub = GitHubBuilder.fromPropertyFile(f.getPath()).withRateLimitHandler(RateLimitHandler.FAIL).build();
|
||||||
} else {
|
} else {
|
||||||
gitHub = GitHub.connect();
|
gitHub = GitHubBuilder.fromCredentials().withRateLimitHandler(RateLimitHandler.FAIL).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.io.IOException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +39,22 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
getUser().getRepository(targetName).delete();
|
getUser().getRepository(targetName).delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepositoryWithAutoInitializationCRUD() throws Exception {
|
||||||
|
String name = "github-api-test-autoinit";
|
||||||
|
deleteRepository(name);
|
||||||
|
GHRepository r = gitHub.createRepository(name)
|
||||||
|
.description("a test repository for auto init")
|
||||||
|
.homepage("http://github-api.kohsuke.org/")
|
||||||
|
.autoInit(true).create();
|
||||||
|
r.enableIssueTracker(false);
|
||||||
|
r.enableDownloads(false);
|
||||||
|
r.enableWiki(false);
|
||||||
|
Thread.sleep(3000);
|
||||||
|
assertNotNull(r.getReadme());
|
||||||
|
getUser().getRepository(name).delete();
|
||||||
|
}
|
||||||
|
|
||||||
private void deleteRepository(final String name) throws IOException {
|
private void deleteRepository(final String name) throws IOException {
|
||||||
GHRepository repository = getUser().getRepository(name);
|
GHRepository repository = getUser().getRepository(name);
|
||||||
if(repository != null) {
|
if(repository != null) {
|
||||||
@@ -206,10 +223,12 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMyTeamsContainsAllMyOrganizations() throws IOException {
|
public void testMyOrganizationsContainMyTeams() throws IOException {
|
||||||
Map<String, Set<GHTeam>> teams = gitHub.getMyTeams();
|
Map<String, Set<GHTeam>> teams = gitHub.getMyTeams();
|
||||||
Map<String, GHOrganization> myOrganizations = gitHub.getMyOrganizations();
|
Map<String, GHOrganization> myOrganizations = gitHub.getMyOrganizations();
|
||||||
assertEquals(teams.keySet(), myOrganizations.keySet());
|
//GitHub no longer has default 'owners' team, so there may be organization memberships without a team
|
||||||
|
//https://help.github.com/articles/about-improved-organization-permissions/
|
||||||
|
assertTrue(myOrganizations.keySet().containsAll(teams.keySet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -286,7 +305,8 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetTeamsForRepo() throws Exception {
|
public void testGetTeamsForRepo() throws Exception {
|
||||||
kohsuke();
|
kohsuke();
|
||||||
assertEquals(1, gitHub.getOrganization("github-api-test-org").getRepository("testGetTeamsForRepo").getTeams().size());
|
// 'Core Developers' and 'Owners'
|
||||||
|
assertEquals(2, gitHub.getOrganization("github-api-test-org").getRepository("testGetTeamsForRepo").getTeams().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -319,12 +339,21 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
assertNotNull(e);
|
assertNotNull(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOrgTeamBySlug() throws Exception {
|
||||||
|
kohsuke();
|
||||||
|
GHTeam e = gitHub.getOrganization("github-api-test-org").getTeamBySlug("core-developers");
|
||||||
|
assertNotNull(e);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCommit() throws Exception {
|
public void testCommit() throws Exception {
|
||||||
GHCommit commit = gitHub.getUser("jenkinsci").getRepository("jenkins").getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7");
|
GHCommit commit = gitHub.getUser("jenkinsci").getRepository("jenkins").getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7");
|
||||||
System.out.println(commit);
|
System.out.println(commit);
|
||||||
assertEquals(1, commit.getParents().size());
|
assertEquals(1, commit.getParents().size());
|
||||||
assertEquals(1,commit.getFiles().size());
|
assertEquals(1,commit.getFiles().size());
|
||||||
|
assertEquals("https://github.com/jenkinsci/jenkins/commit/08c1c9970af4d609ae754fbe803e06186e3206f7",
|
||||||
|
commit.getHtmlUrl().toString());
|
||||||
|
|
||||||
File f = commit.getFiles().get(0);
|
File f = commit.getFiles().get(0);
|
||||||
assertEquals(48,f.getLinesChanged());
|
assertEquals(48,f.getLinesChanged());
|
||||||
@@ -351,7 +380,7 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
sha1.add(c.getSHA1());
|
sha1.add(c.getSHA1());
|
||||||
}
|
}
|
||||||
assertEquals("1cccddb22e305397151b2b7b87b4b47d74ca337b",sha1.get(0));
|
assertEquals("1cccddb22e305397151b2b7b87b4b47d74ca337b",sha1.get(0));
|
||||||
assertEquals(29,sha1.size());
|
assertEquals(29, sha1.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -574,6 +603,8 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
.prerelease(false)
|
.prerelease(false)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
Thread.sleep(3000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
for (GHTag tag : r.listTags()) {
|
for (GHTag tag : r.listTags()) {
|
||||||
@@ -598,10 +629,10 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRef() throws IOException {
|
public void testRef() throws IOException {
|
||||||
GHRef masterRef = gitHub.getRepository("jenkinsci/jenkins").getRef("heads/master");
|
GHRef masterRef = gitHub.getRepository("jenkinsci/jenkins").getRef("heads/master");
|
||||||
assertEquals("https://api.github.com/repos/jenkinsci/jenkins/git/refs/heads/master", masterRef.getUrl().toString());
|
assertEquals("https://api.github.com/repos/jenkinsci/jenkins/git/refs/heads/master", masterRef.getUrl().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void directoryListing() throws IOException {
|
public void directoryListing() throws IOException {
|
||||||
@@ -618,8 +649,8 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddDeployKey() throws IOException {
|
public void testAddDeployKey() throws IOException {
|
||||||
GHRepository myRepository = Iterables.get(gitHub.getMyself().getRepositories().values(),0);
|
GHRepository myRepository = getTestRepository();
|
||||||
final GHDeployKey newDeployKey = myRepository.addDeployKey("test", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUt0RAycC5cS42JKh6SecfFZBR1RrF+2hYMctz4mk74/arBE+wFb7fnSHGzdGKX2h5CFOWODifRCJVhB7hlVxodxe+QkQQYAEL/x1WVCJnGgTGQGOrhOMj95V3UE5pQKhsKD608C+u5tSofcWXLToP1/wZ7U4/AHjqYi08OLsWToHCax55TZkvdt2jo0hbIoYU+XI9Q8Uv4ONDN1oabiOdgeKi8+crvHAuvNleiBhWVBzFh8KdfzaH5uNdw7ihhFjEd1vzqACsjCINCjdMfzl6jD9ExuWuE92nZJnucls2cEoNC6k2aPmrZDg9hA32FXVpyseY+bDUWFU6LO2LG6PB kohsuke@atlas");
|
final GHDeployKey newDeployKey = myRepository.addDeployKey("test", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUt0RAycC5cS42JKh6SecfFZBR1RrF+2hYMctz4mk74/arBE+wFb7fnSHGzdGKX2h5CFOWODifRCJVhB7hlVxodxe+QkQQYAEL/x1WVCJnGgTGQGOrhOMj95V3UE5pQKhsKD608C+u5tSofcWXLToP1/wZ7U4/AHjqYi08OLsWToHCax55TZkvdt2jo0hbIoYU+XI9Q8Uv4ONDN1oabiOdgeKi8+crvHAuvNleiBhWVBzFh8KdfzaH5uNdw7ihhFjEd1vzqACsjCINCjdMfzl6jD9ExuWuE92nZJnucls2cEoNC6k2aPmrZDg9hA32FXVpyseY+bDUWFU6LO2LG6PB kohsuke@atlas");
|
||||||
try {
|
try {
|
||||||
assertNotNull(newDeployKey.getId());
|
assertNotNull(newDeployKey.getId());
|
||||||
|
|
||||||
@@ -636,11 +667,11 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCommitStatusContext() throws IOException {
|
public void testCommitStatusContext() throws IOException {
|
||||||
GHRepository myRepository = Iterables.get(gitHub.getMyself().getRepositories().values(), 0);
|
GHRepository myRepository = getTestRepository();
|
||||||
GHRef masterRef = myRepository.getRef("heads/master");
|
GHRef masterRef = myRepository.getRef("heads/master");
|
||||||
GHCommitStatus commitStatus = myRepository.createCommitStatus(masterRef.getObject().getSha(), GHCommitState.SUCCESS, "http://www.example.com", "test", "test/context");
|
GHCommitStatus commitStatus = myRepository.createCommitStatus(masterRef.getObject().getSha(), GHCommitState.SUCCESS, "http://www.example.com", "test", "test/context");
|
||||||
assertEquals("test/context", commitStatus.getContext());
|
assertEquals("test/context", commitStatus.getContext());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -671,28 +702,28 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTrees() throws IOException {
|
public void testTrees() throws IOException {
|
||||||
GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTree("master");
|
GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTree("master");
|
||||||
boolean foundReadme = false;
|
boolean foundReadme = false;
|
||||||
for(GHTreeEntry e : masterTree.getTree()){
|
for(GHTreeEntry e : masterTree.getTree()){
|
||||||
if("readme".equalsIgnoreCase(e.getPath().replaceAll(".md", ""))){
|
if("readme".equalsIgnoreCase(e.getPath().replaceAll("\\.md", ""))){
|
||||||
foundReadme = true;
|
foundReadme = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue(foundReadme);
|
assertTrue(foundReadme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTreesRecursive() throws IOException {
|
public void testTreesRecursive() throws IOException {
|
||||||
GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTreeRecursive("master", 1);
|
GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTreeRecursive("master", 1);
|
||||||
boolean foundThisFile = false;
|
boolean foundThisFile = false;
|
||||||
for(GHTreeEntry e : masterTree.getTree()){
|
for(GHTreeEntry e : masterTree.getTree()){
|
||||||
if(e.getPath().endsWith(AppTest.class.getSimpleName() + ".java")){
|
if(e.getPath().endsWith(AppTest.class.getSimpleName() + ".java")){
|
||||||
foundThisFile = true;
|
foundThisFile = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue(foundThisFile);
|
assertTrue(foundThisFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -773,7 +804,7 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
assertTrue(actual.contains("href=\"https://github.com/kohsuke\""));
|
assertTrue(actual.contains("href=\"https://github.com/kohsuke\""));
|
||||||
assertTrue(actual.contains("href=\"https://github.com/kohsuke/github-api/pull/1\""));
|
assertTrue(actual.contains("href=\"https://github.com/kohsuke/github-api/pull/1\""));
|
||||||
assertTrue(actual.contains("class=\"user-mention\""));
|
assertTrue(actual.contains("class=\"user-mention\""));
|
||||||
assertTrue(actual.contains("class=\"issue-link\""));
|
assertTrue(actual.contains("class=\"issue-link "));
|
||||||
assertTrue(actual.contains("to fix issue"));
|
assertTrue(actual.contains("to fix issue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,6 +858,18 @@ public class AppTest extends AbstractGitHubApiTestBase {
|
|||||||
gitHub.listNotifications().markAsRead();
|
gitHub.listNotifications().markAsRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just basic code coverage to make sure toString() doesn't blow up
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void checkToString() throws Exception {
|
||||||
|
GHUser u = gitHub.getUser("rails");
|
||||||
|
System.out.println(u);
|
||||||
|
GHRepository r = u.getRepository("rails");
|
||||||
|
System.out.println(r);
|
||||||
|
System.out.println(r.getIssue(1));
|
||||||
|
}
|
||||||
|
|
||||||
private void kohsuke() {
|
private void kohsuke() {
|
||||||
String login = getUser().getLogin();
|
String login = getUser().getLogin();
|
||||||
Assume.assumeTrue(login.equals("kohsuke") || login.equals("kohsuke2"));
|
Assume.assumeTrue(login.equals("kohsuke") || login.equals("kohsuke2"));
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -13,4 +15,14 @@ public class CommitTest extends AbstractGitHubApiTestBase {
|
|||||||
GHTag t = gitHub.getRepository("stapler/stapler").listTags().iterator().next();
|
GHTag t = gitHub.getRepository("stapler/stapler").listTags().iterator().next();
|
||||||
t.getCommit().getLastStatus();
|
t.getCommit().getLastStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // issue 230
|
||||||
|
public void listFiles() throws Exception {
|
||||||
|
GHRepository repo = gitHub.getRepository("stapler/stapler");
|
||||||
|
PagedIterable<GHCommit> commits = repo.queryCommits().path("pom.xml").list();
|
||||||
|
for (GHCommit commit : Iterables.limit(commits, 10)) {
|
||||||
|
GHCommit expected = repo.getCommit( commit.getSHA1() );
|
||||||
|
assertEquals(expected.getFiles().size(), commit.getFiles().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ public class GHContentIntegrationTest extends AbstractGitHubApiTestBase {
|
|||||||
repo = gitHub.getRepository("github-api-test-org/GHContentIntegrationTest").fork();
|
repo = gitHub.getRepository("github-api-test-org/GHContentIntegrationTest").fork();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBranchProtection() throws Exception {
|
||||||
|
GHBranch b = repo.getBranch("master");
|
||||||
|
b.enableProtection(EnforcementLevel.NON_ADMINS, "foo/bar");
|
||||||
|
b.disableProtection();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFileContent() throws Exception {
|
public void testGetFileContent() throws Exception {
|
||||||
GHContent content = repo.getFileContent("ghcontent-ro/a-file-with-content");
|
GHContent content = repo.getFileContent("ghcontent-ro/a-file-with-content");
|
||||||
@@ -43,6 +50,14 @@ public class GHContentIntegrationTest extends AbstractGitHubApiTestBase {
|
|||||||
assertTrue(entries.size() == 3);
|
assertTrue(entries.size() == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDirectoryContentTrailingSlash() throws Exception {
|
||||||
|
//Used to truncate the ?ref=master, see gh-224 https://github.com/kohsuke/github-api/pull/224
|
||||||
|
List<GHContent> entries = repo.getDirectoryContent("ghcontent-ro/a-dir-with-3-entries/", "master");
|
||||||
|
|
||||||
|
assertTrue(entries.get(0).getUrl().endsWith("?ref=master"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCRUDContent() throws Exception {
|
public void testCRUDContent() throws Exception {
|
||||||
GHContentUpdateResponse created = repo.createContent("this is an awesome file I created\n", "Creating a file for integration tests.", createdFilename);
|
GHContentUpdateResponse created = repo.createContent("this is an awesome file I created\n", "Creating a file for integration tests.", createdFilename);
|
||||||
@@ -58,7 +73,8 @@ public class GHContentIntegrationTest extends AbstractGitHubApiTestBase {
|
|||||||
|
|
||||||
assertNotNull(updatedContentResponse.getCommit());
|
assertNotNull(updatedContentResponse.getCommit());
|
||||||
assertNotNull(updatedContentResponse.getContent());
|
assertNotNull(updatedContentResponse.getContent());
|
||||||
assertEquals("this is some new content\n", updatedContent.getContent());
|
// due to what appears to be a cache propagation delay, this test is too flaky
|
||||||
|
// assertEquals("this is some new content\n", updatedContent.getContent());
|
||||||
|
|
||||||
GHContentUpdateResponse deleteResponse = updatedContent.delete("Enough of this foolishness!");
|
GHContentUpdateResponse deleteResponse = updatedContent.delete("Enough of this foolishness!");
|
||||||
|
|
||||||
|
|||||||
43
src/test/java/org/kohsuke/github/GHOrganizationTest.java
Normal file
43
src/test/java/org/kohsuke/github/GHOrganizationTest.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class GHOrganizationTest extends AbstractGitHubApiTestBase {
|
||||||
|
|
||||||
|
public static final String GITHUB_API_TEST = "github-api-test";
|
||||||
|
private GHOrganization org;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
org = gitHub.getOrganization("github-api-test-org");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateRepository() throws IOException {
|
||||||
|
GHRepository repository = org.createRepository(GITHUB_API_TEST,
|
||||||
|
"a test repository used to test kohsuke's github-api", "http://github-api.kohsuke.org/", "Core Developers", true);
|
||||||
|
Assert.assertNotNull(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateRepositoryWithAutoInitialization() throws IOException {
|
||||||
|
GHRepository repository = org.createRepository(GITHUB_API_TEST)
|
||||||
|
.description("a test repository used to test kohsuke's github-api")
|
||||||
|
.homepage("http://github-api.kohsuke.org/")
|
||||||
|
.team(org.getTeamByName("Core Developers"))
|
||||||
|
.autoInit(true).create();
|
||||||
|
Assert.assertNotNull(repository);
|
||||||
|
Assert.assertNotNull(repository.getReadme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanUp() throws Exception {
|
||||||
|
GHRepository repository = org.getRepository(GITHUB_API_TEST);
|
||||||
|
repository.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,50 +1,57 @@
|
|||||||
package org.kohsuke.github;
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test for {@link GitHub}.
|
* Unit test for {@link GitHub}.
|
||||||
*/
|
*/
|
||||||
public class GitHubTest extends TestCase {
|
public class GitHubTest {
|
||||||
|
@Test
|
||||||
public void testGitHubServerWithHttp() throws Exception {
|
public void testGitHubServerWithHttp() throws Exception {
|
||||||
GitHub hub = GitHub.connectToEnterprise("http://enterprise.kohsuke.org/api/v3", "bogus","bogus");
|
GitHub hub = GitHub.connectToEnterprise("http://enterprise.kohsuke.org/api/v3", "bogus","bogus");
|
||||||
assertEquals("http://enterprise.kohsuke.org/api/v3/test", hub.getApiURL("/test").toString());
|
assertEquals("http://enterprise.kohsuke.org/api/v3/test", hub.getApiURL("/test").toString());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
public void testGitHubServerWithHttps() throws Exception {
|
public void testGitHubServerWithHttps() throws Exception {
|
||||||
GitHub hub = GitHub.connectToEnterprise("https://enterprise.kohsuke.org/api/v3", "bogus","bogus");
|
GitHub hub = GitHub.connectToEnterprise("https://enterprise.kohsuke.org/api/v3", "bogus","bogus");
|
||||||
assertEquals("https://enterprise.kohsuke.org/api/v3/test", hub.getApiURL("/test").toString());
|
assertEquals("https://enterprise.kohsuke.org/api/v3/test", hub.getApiURL("/test").toString());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
public void testGitHubServerWithoutServer() throws Exception {
|
public void testGitHubServerWithoutServer() throws Exception {
|
||||||
GitHub hub = GitHub.connectUsingPassword("kohsuke", "bogus");
|
GitHub hub = GitHub.connectUsingPassword("kohsuke", "bogus");
|
||||||
assertEquals("https://api.github.com/test", hub.getApiURL("/test").toString());
|
assertEquals("https://api.github.com/test", hub.getApiURL("/test").toString());
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
public void testGitHubBuilderFromEnvironment() throws IOException {
|
public void testGitHubBuilderFromEnvironment() throws IOException {
|
||||||
|
|
||||||
Map<String, String>props = new HashMap<String, String>();
|
Map<String, String>props = new HashMap<String, String>();
|
||||||
|
|
||||||
props.put("login", "bogus");
|
props.put("login", "bogus");
|
||||||
props.put("oauth", "bogus");
|
props.put("oauth", "bogus");
|
||||||
props.put("password", "bogus");
|
props.put("password", "bogus");
|
||||||
|
|
||||||
setupEnvironment(props);
|
setupEnvironment(props);
|
||||||
|
|
||||||
GitHubBuilder builder = GitHubBuilder.fromEnvironment();
|
GitHubBuilder builder = GitHubBuilder.fromEnvironment();
|
||||||
|
|
||||||
assertEquals("bogus", builder.user);
|
assertEquals("bogus", builder.user);
|
||||||
assertEquals("bogus", builder.oauthToken);
|
assertEquals("bogus", builder.oauthToken);
|
||||||
assertEquals("bogus", builder.password);
|
assertEquals("bogus", builder.password);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -55,59 +62,73 @@ public class GitHubTest extends TestCase {
|
|||||||
* Its used to wire in values for the github credentials to test that the GitHubBuilder works properly to resolve them.
|
* Its used to wire in values for the github credentials to test that the GitHubBuilder works properly to resolve them.
|
||||||
*/
|
*/
|
||||||
private void setupEnvironment(Map<String, String> newenv) {
|
private void setupEnvironment(Map<String, String> newenv) {
|
||||||
try
|
try {
|
||||||
{
|
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
|
||||||
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
|
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
|
||||||
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
|
theEnvironmentField.setAccessible(true);
|
||||||
theEnvironmentField.setAccessible(true);
|
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
|
||||||
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
|
env.putAll(newenv);
|
||||||
env.putAll(newenv);
|
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
|
||||||
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
|
theCaseInsensitiveEnvironmentField.setAccessible(true);
|
||||||
theCaseInsensitiveEnvironmentField.setAccessible(true);
|
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
|
||||||
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
|
cienv.putAll(newenv);
|
||||||
cienv.putAll(newenv);
|
} catch (NoSuchFieldException e) {
|
||||||
}
|
try {
|
||||||
catch (NoSuchFieldException e)
|
Class[] classes = Collections.class.getDeclaredClasses();
|
||||||
{
|
Map<String, String> env = System.getenv();
|
||||||
try {
|
for (Class cl : classes) {
|
||||||
Class[] classes = Collections.class.getDeclaredClasses();
|
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
|
||||||
Map<String, String> env = System.getenv();
|
Field field = cl.getDeclaredField("m");
|
||||||
for(Class cl : classes) {
|
field.setAccessible(true);
|
||||||
if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
|
Object obj = field.get(env);
|
||||||
Field field = cl.getDeclaredField("m");
|
Map<String, String> map = (Map<String, String>) obj;
|
||||||
field.setAccessible(true);
|
map.clear();
|
||||||
Object obj = field.get(env);
|
map.putAll(newenv);
|
||||||
Map<String, String> map = (Map<String, String>) obj;
|
}
|
||||||
map.clear();
|
}
|
||||||
map.putAll(newenv);
|
} catch (Exception e2) {
|
||||||
}
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Exception e2) {
|
} catch (Exception e1) {
|
||||||
e2.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
} catch (Exception e1) {
|
}
|
||||||
e1.printStackTrace();
|
@Test
|
||||||
}
|
public void testGitHubBuilderFromCustomEnvironment() throws IOException {
|
||||||
|
Map<String, String> props = new HashMap<String, String>();
|
||||||
}
|
|
||||||
|
props.put("customLogin", "bogusLogin");
|
||||||
public void testGitHubBuilderFromCustomEnvironment() throws IOException {
|
props.put("customOauth", "bogusOauth");
|
||||||
|
props.put("customPassword", "bogusPassword");
|
||||||
Map<String, String>props = new HashMap<String, String>();
|
props.put("customEndpoint", "bogusEndpoint");
|
||||||
|
|
||||||
props.put("customLogin", "bogusLogin");
|
setupEnvironment(props);
|
||||||
props.put("customOauth", "bogusOauth");
|
|
||||||
props.put("customPassword", "bogusPassword");
|
GitHubBuilder builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint");
|
||||||
props.put("customEndpoint", "bogusEndpoint");
|
|
||||||
|
assertEquals("bogusLogin", builder.user);
|
||||||
setupEnvironment(props);
|
assertEquals("bogusOauth", builder.oauthToken);
|
||||||
|
assertEquals("bogusPassword", builder.password);
|
||||||
GitHubBuilder builder = GitHubBuilder.fromEnvironment("customLogin", "customPassword", "customOauth", "customEndpoint");
|
assertEquals("bogusEndpoint", builder.endpoint);
|
||||||
|
}
|
||||||
assertEquals("bogusLogin", builder.user);
|
|
||||||
assertEquals("bogusOauth", builder.oauthToken);
|
@Test
|
||||||
assertEquals("bogusPassword", builder.password);
|
public void testGitHubEnterpriseDoesNotHaveRateLimit() throws IOException {
|
||||||
assertEquals("bogusEndpoint", builder.endpoint);
|
GitHub github = spy(new GitHubBuilder().build());
|
||||||
|
when(github.retrieve()).thenThrow(FileNotFoundException.class);
|
||||||
|
|
||||||
|
GHRateLimit rateLimit = github.getRateLimit();
|
||||||
|
assertThat(rateLimit.getResetDate(), notNullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGitHubIsApiUrlValid() throws IOException {
|
||||||
|
GitHub github = GitHub.connectAnonymously();
|
||||||
|
//GitHub github = GitHub.connectToEnterpriseAnonymously("https://github.mycompany.com/api/v3/");
|
||||||
|
try {
|
||||||
|
github.checkApiUrlValidity();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
assertTrue(ioe.getMessage().contains("private mode enabled"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Kohsuke Kawaguchi
|
* @author Kohsuke Kawaguchi
|
||||||
@@ -18,7 +19,58 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
|
|||||||
assertEquals(name, p.getTitle());
|
assertEquals(name, p.getTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // Requires push access to the test repo to pass
|
@Test
|
||||||
|
public void createPullRequestComment() throws Exception {
|
||||||
|
String name = rnd.next();
|
||||||
|
GHPullRequest p = getRepository().createPullRequest(name, "stable", "master", "## test");
|
||||||
|
p.comment("Some comment");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPullRequestReviewComments() throws Exception {
|
||||||
|
String name = rnd.next();
|
||||||
|
GHPullRequest p = getRepository().createPullRequest(name, "stable", "master", "## test");
|
||||||
|
System.out.println(p.getUrl());
|
||||||
|
assertTrue(p.listReviewComments().asList().isEmpty());
|
||||||
|
p.createReviewComment("Sample review comment", p.getHead().getSha(), "cli/pom.xml", 5);
|
||||||
|
List<GHPullRequestReviewComment> comments = p.listReviewComments().asList();
|
||||||
|
assertEquals(1, comments.size());
|
||||||
|
GHPullRequestReviewComment comment = comments.get(0);
|
||||||
|
assertEquals("Sample review comment", comment.getBody());
|
||||||
|
|
||||||
|
comment.update("Updated review comment");
|
||||||
|
comments = p.listReviewComments().asList();
|
||||||
|
assertEquals(1, comments.size());
|
||||||
|
comment = comments.get(0);
|
||||||
|
assertEquals("Updated review comment", comment.getBody());
|
||||||
|
|
||||||
|
comment.delete();
|
||||||
|
comments = p.listReviewComments().asList();
|
||||||
|
assertTrue(comments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMergeCommitSHA() throws Exception {
|
||||||
|
String name = rnd.next();
|
||||||
|
GHPullRequest p = getRepository().createPullRequest(name, "mergeable-branch", "master", "## test");
|
||||||
|
for (int i=0; i<100; i++) {
|
||||||
|
GHPullRequest updated = getRepository().getPullRequest(p.getNumber());
|
||||||
|
if (updated.getMergeCommitSha()!=null) {
|
||||||
|
// make sure commit exists
|
||||||
|
GHCommit commit = getRepository().getCommit(updated.getMergeCommitSha());
|
||||||
|
assertNotNull(commit);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergeability computation takes time. give it more chance
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
// hmm?
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
// Requires push access to the test repo to pass
|
||||||
public void setLabels() throws Exception {
|
public void setLabels() throws Exception {
|
||||||
GHPullRequest p = getRepository().createPullRequest(rnd.next(), "stable", "master", "## test");
|
GHPullRequest p = getRepository().createPullRequest(rnd.next(), "stable", "master", "## test");
|
||||||
String label = rnd.next();
|
String label = rnd.next();
|
||||||
@@ -29,7 +81,8 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
|
|||||||
assertEquals(label, labels.iterator().next().getName());
|
assertEquals(label, labels.iterator().next().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // Requires push access to the test repo to pass
|
@Test
|
||||||
|
// Requires push access to the test repo to pass
|
||||||
public void setAssignee() throws Exception {
|
public void setAssignee() throws Exception {
|
||||||
GHPullRequest p = getRepository().createPullRequest(rnd.next(), "stable", "master", "## test");
|
GHPullRequest p = getRepository().createPullRequest(rnd.next(), "stable", "master", "## test");
|
||||||
GHMyself user = gitHub.getMyself();
|
GHMyself user = gitHub.getMyself();
|
||||||
@@ -49,7 +102,7 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
|
|||||||
PagedIterable<GHPullRequest> ghPullRequests = getRepository().listPullRequests(GHIssueState.OPEN);
|
PagedIterable<GHPullRequest> ghPullRequests = getRepository().listPullRequests(GHIssueState.OPEN);
|
||||||
for (GHPullRequest pr : ghPullRequests) {
|
for (GHPullRequest pr : ghPullRequests) {
|
||||||
assertNotNull(pr.getUser().root);
|
assertNotNull(pr.getUser().root);
|
||||||
assertFalse(pr.getMergeable());
|
pr.getMergeable();
|
||||||
assertNotNull(pr.getUser().root);
|
assertNotNull(pr.getUser().root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class RepositoryMockTest {
|
|||||||
|
|
||||||
|
|
||||||
when(requester.asIterator("/repos/*/*/collaborators",
|
when(requester.asIterator("/repos/*/*/collaborators",
|
||||||
GHUser[].class)).thenReturn(iterator, iterator);
|
GHUser[].class, 0)).thenReturn(iterator, iterator);
|
||||||
|
|
||||||
|
|
||||||
PagedIterable<GHUser> pagedIterable = Mockito.mock(PagedIterable.class);
|
PagedIterable<GHUser> pagedIterable = Mockito.mock(PagedIterable.class);
|
||||||
|
|||||||
30
src/test/java/org/kohsuke/github/UserTest.java
Normal file
30
src/test/java/org/kohsuke/github/UserTest.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package org.kohsuke.github;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kohsuke Kawaguchi
|
||||||
|
*/
|
||||||
|
public class UserTest extends AbstractGitHubApiTestBase {
|
||||||
|
@Test
|
||||||
|
public void listFollowsAndFollowers() throws IOException {
|
||||||
|
GHUser u = gitHub.getUser("rtyler");
|
||||||
|
assertNotEquals(
|
||||||
|
count50(u.listFollowers()),
|
||||||
|
count50(u.listFollows()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<GHUser> count50(PagedIterable<GHUser> l) {
|
||||||
|
Set<GHUser> users = new HashSet<GHUser>();
|
||||||
|
PagedIterator<GHUser> itr = l.iterator();
|
||||||
|
for (int i=0; i<50 && itr.hasNext(); i++) {
|
||||||
|
users.add(itr.next());
|
||||||
|
}
|
||||||
|
assertEquals(50, users.size());
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user