mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-11 00:11:25 +00:00
Compare commits
25 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55e218ac37 | ||
|
|
7d1f636cdd | ||
|
|
a4b8b9b09b | ||
|
|
4e8e28d27c | ||
|
|
4b52414435 | ||
|
|
811b96bcbe | ||
|
|
f3207855ca | ||
|
|
9f3c5b93e3 | ||
|
|
a56357f0c1 | ||
|
|
f8d14d2e56 | ||
|
|
b0c30759c8 | ||
|
|
54037e6e10 | ||
|
|
fc260d4a37 | ||
|
|
387d4e5bc9 | ||
|
|
4ffd46b391 | ||
|
|
3b49370c06 | ||
|
|
925d26e54c | ||
|
|
1283006b53 | ||
|
|
83a718c9db | ||
|
|
2abf03ccb7 | ||
|
|
a59810a487 | ||
|
|
9cc9e06ad1 | ||
|
|
0108a0c146 | ||
|
|
4188758d84 | ||
|
|
2144100f81 |
3
pom.xml
3
pom.xml
@@ -7,7 +7,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>github-api</artifactId>
|
||||
<version>1.46</version>
|
||||
<version>1.48</version>
|
||||
<name>GitHub API for Java</name>
|
||||
<url>http://github-api.kohsuke.org/</url>
|
||||
<description>GitHub API for Java</description>
|
||||
@@ -16,6 +16,7 @@
|
||||
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
|
||||
<url>http://${project.artifactId}.kohsuke.org/</url>
|
||||
<tag>github-api-1.48</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
||||
171
src/main/java/org/kohsuke/github/GHContent.java
Normal file
171
src/main/java/org/kohsuke/github/GHContent.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
* A Content of a repository.
|
||||
*
|
||||
* @author Alexandre COLLIGNON
|
||||
*/
|
||||
public final class GHContent {
|
||||
private GHRepository owner;
|
||||
|
||||
private String type;
|
||||
private String encoding;
|
||||
private long size;
|
||||
private String sha;
|
||||
private String name;
|
||||
private String path;
|
||||
private String content;
|
||||
private String url; // this is the API url
|
||||
private String git_url; // this is the Blob url
|
||||
private String html_url; // this is the UI
|
||||
|
||||
public GHRepository getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getSha() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the decoded content that is stored at this location.
|
||||
*
|
||||
* Due to the nature of GitHub's API, you're not guaranteed that
|
||||
* the content will already be populated, so this may trigger
|
||||
* network activity, and can throw an IOException.
|
||||
**/
|
||||
public String getContent() throws IOException {
|
||||
return new String(DatatypeConverter.parseBase64Binary(getEncodedContent()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw content that is stored at this location.
|
||||
*
|
||||
* Due to the nature of GitHub's API, you're not guaranteed that
|
||||
* the content will already be populated, so this may trigger
|
||||
* network activity, and can throw an IOException.
|
||||
**/
|
||||
public String getEncodedContent() throws IOException {
|
||||
if (content != null)
|
||||
return content;
|
||||
|
||||
GHContent retrievedContent = owner.getFileContent(path);
|
||||
|
||||
this.size = retrievedContent.size;
|
||||
this.sha = retrievedContent.sha;
|
||||
this.content = retrievedContent.content;
|
||||
this.url = retrievedContent.url;
|
||||
this.git_url = retrievedContent.git_url;
|
||||
this.html_url = retrievedContent.html_url;
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getGitUrl() {
|
||||
return git_url;
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return html_url;
|
||||
}
|
||||
|
||||
public boolean isFile() {
|
||||
return "file".equals(type);
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return "dir".equals(type);
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse update(String newContent, String commitMessage) throws IOException {
|
||||
return update(newContent, commitMessage, null);
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse update(String newContent, String commitMessage, String branch) throws IOException {
|
||||
String encodedContent = DatatypeConverter.printBase64Binary(newContent.getBytes());
|
||||
|
||||
Requester requester = new Requester(owner.root)
|
||||
.with("path", path)
|
||||
.with("message", commitMessage)
|
||||
.with("sha", sha)
|
||||
.with("content", encodedContent)
|
||||
.method("PUT");
|
||||
|
||||
if (branch != null) {
|
||||
requester.with("branch", branch);
|
||||
}
|
||||
|
||||
GHContentUpdateResponse response = requester.to(getApiRoute(), GHContentUpdateResponse.class);
|
||||
|
||||
response.getContent().wrap(owner);
|
||||
response.getCommit().wrapUp(owner);
|
||||
|
||||
this.content = encodedContent;
|
||||
return response;
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse delete(String message) throws IOException {
|
||||
return delete(message, null);
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse delete(String commitMessage, String branch) throws IOException {
|
||||
Requester requester = new Requester(owner.root)
|
||||
.with("path", path)
|
||||
.with("message", commitMessage)
|
||||
.with("sha", sha)
|
||||
.method("DELETE");
|
||||
|
||||
if (branch != null) {
|
||||
requester.with("branch", branch);
|
||||
}
|
||||
|
||||
GHContentUpdateResponse response = requester.to(getApiRoute(), GHContentUpdateResponse.class);
|
||||
|
||||
response.getCommit().wrapUp(owner);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/contents/" + path;
|
||||
}
|
||||
|
||||
GHContent wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static GHContent[] wrap(GHContent[] contents, GHRepository repository) {
|
||||
for (GHContent unwrappedContent : contents) {
|
||||
unwrappedContent.wrap(repository);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* The response that is returned when updating
|
||||
* repository content.
|
||||
**/
|
||||
public final class GHContentUpdateResponse {
|
||||
private GHContent content;
|
||||
private GHCommit commit;
|
||||
|
||||
public GHContent getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public GHCommit getCommit() {
|
||||
return commit;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ package org.kohsuke.github;
|
||||
* See http://developer.github.com/v3/events/types/
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHEventInfo
|
||||
*/
|
||||
public enum GHEvent {
|
||||
COMMIT_COMMENT,
|
||||
@@ -22,6 +23,7 @@ public enum GHEvent {
|
||||
MEMBER,
|
||||
PUBLIC,
|
||||
PULL_REQUEST,
|
||||
PULL_REQUEST_REVIEW_COMMENT,
|
||||
PUSH,
|
||||
TEAM_ADD,
|
||||
WATCH
|
||||
|
||||
@@ -10,9 +10,9 @@ import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
public class GHKey {
|
||||
/*package almost final*/ GitHub root;
|
||||
|
||||
private String url, key, title;
|
||||
private boolean verified;
|
||||
private int id;
|
||||
protected String url, key, title;
|
||||
protected boolean verified;
|
||||
protected int id;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
||||
@@ -34,6 +34,9 @@ public class GHMyself extends GHUser {
|
||||
/**
|
||||
* Returns the read-only list of all the pulic keys of the current user.
|
||||
*
|
||||
* NOTE: When using OAuth authenticaiton, the READ/WRITE User scope is
|
||||
* required by the GitHub APIs, otherwise you will get a 404 NOT FOUND.
|
||||
*
|
||||
* @return
|
||||
* Always non-null.
|
||||
*/
|
||||
@@ -41,6 +44,21 @@ public class GHMyself extends GHUser {
|
||||
return Collections.unmodifiableList(Arrays.asList(root.retrieve().to("/user/keys", GHKey[].class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the read-only list of all the pulic verified keys of the current user.
|
||||
*
|
||||
* Differently from the getPublicKeys() method, the retrieval of the user's
|
||||
* verified public keys does not require any READ/WRITE OAuth Scope to the
|
||||
* user's profile.
|
||||
*
|
||||
* @return
|
||||
* Always non-null.
|
||||
*/
|
||||
public List<GHVerifiedKey> getPublicVerifiedKeys() throws IOException {
|
||||
return Collections.unmodifiableList(Arrays.asList(root.retrieve().to(
|
||||
"/users/" + getLogin() + "/keys", GHVerifiedKey[].class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the organization that this user belongs to.
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
|
||||
@@ -143,7 +144,24 @@ public class GHRepository {
|
||||
}
|
||||
|
||||
public List<GHIssue> getIssues(GHIssueState state) throws IOException {
|
||||
return Arrays.asList(GHIssue.wrap(root.retrieve().to("/repos/" + owner.login + "/" + name + "/issues?state=" + state.toString().toLowerCase(), GHIssue[].class), this));
|
||||
return listIssues(state).asList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists up all the issues in this repository.
|
||||
*/
|
||||
public PagedIterable<GHIssue> listIssues(final GHIssueState state) {
|
||||
return new PagedIterable<GHIssue>() {
|
||||
public PagedIterator<GHIssue> iterator() {
|
||||
return new PagedIterator<GHIssue>(root.retrieve().asIterator(getApiTailUrl("issues?state="+state.toString().toLowerCase(Locale.ENGLISH)), GHIssue[].class)) {
|
||||
@Override
|
||||
protected void wrapUp(GHIssue[] page) {
|
||||
for (GHIssue c : page)
|
||||
c.wrap(GHRepository.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public GHReleaseBuilder createRelease(String tag) {
|
||||
@@ -716,7 +734,66 @@ public class GHRepository {
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
public GHContent getFileContent(String path) throws IOException {
|
||||
return getFileContent(path, null);
|
||||
}
|
||||
|
||||
public GHContent getFileContent(String path, String ref) throws IOException {
|
||||
Requester requester = root.retrieve();
|
||||
String target = String.format("/repos/%s/%s/contents/%s", owner.login, name, path);
|
||||
|
||||
if (ref != null)
|
||||
target = target + "?ref=" + ref;
|
||||
|
||||
return requester.to(target, GHContent.class).wrap(this);
|
||||
}
|
||||
|
||||
public List<GHContent> getDirectoryContent(String path) throws IOException {
|
||||
return getDirectoryContent(path, null);
|
||||
}
|
||||
|
||||
public List<GHContent> getDirectoryContent(String path, String ref) throws IOException {
|
||||
Requester requester = root.retrieve();
|
||||
String target = String.format("/repos/%s/%s/contents/%s", owner.login, name, path);
|
||||
|
||||
if (ref != null)
|
||||
target = target + "?ref=" + ref;
|
||||
|
||||
GHContent[] files = requester.to(target, GHContent[].class);
|
||||
|
||||
GHContent.wrap(files, this);
|
||||
|
||||
return Arrays.asList(files);
|
||||
}
|
||||
|
||||
public GHContent getReadme() throws Exception {
|
||||
return getFileContent("readme");
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse createContent(String content, String commitMessage, String path) throws IOException {
|
||||
return createContent(content, commitMessage, path, null);
|
||||
}
|
||||
|
||||
public GHContentUpdateResponse createContent(String content, String commitMessage, String path, String branch) throws IOException {
|
||||
Requester requester = new Requester(root)
|
||||
.with("path", path)
|
||||
.with("message", commitMessage)
|
||||
.with("content", DatatypeConverter.printBase64Binary(content.getBytes()))
|
||||
.method("PUT");
|
||||
|
||||
if (branch != null) {
|
||||
requester.with("branch", branch);
|
||||
}
|
||||
|
||||
GHContentUpdateResponse response = requester.to(getApiTailUrl("contents/" + path), GHContentUpdateResponse.class);
|
||||
|
||||
response.getContent().wrap(this);
|
||||
response.getCommit().wrapUp(this);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public GHMilestone createMilestone(String title, String description) throws IOException {
|
||||
return new Requester(root)
|
||||
.with("title", title).with("description", description).method("POST").to(getApiTailUrl("milestones"), GHMilestone.class).wrap(this);
|
||||
|
||||
13
src/main/java/org/kohsuke/github/GHVerifiedKey.java
Normal file
13
src/main/java/org/kohsuke/github/GHVerifiedKey.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
public class GHVerifiedKey extends GHKey {
|
||||
|
||||
public GHVerifiedKey() {
|
||||
this.verified = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return (title == null ? "key-" + id : title);
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,9 @@ public class AppTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testRepoCRUD() throws Exception {
|
||||
GHRepository existing = gitHub.getMyself().getRepository("github-api-test");
|
||||
if (existing!=null)
|
||||
existing.delete();
|
||||
GHRepository r = gitHub.createRepository("github-api-test", "a test repository", "http://github-api.kohsuke.org/", true);
|
||||
r.enableIssueTracker(false);
|
||||
r.enableDownloads(false);
|
||||
@@ -79,6 +82,12 @@ public class AppTest extends TestCase {
|
||||
o.close();
|
||||
}
|
||||
|
||||
public void testGetIssues() throws Exception {
|
||||
List<GHIssue> closedIssues = gitHub.getUser("kohsuke").getRepository("github-api").getIssues(GHIssueState.CLOSED);
|
||||
// prior to using PagedIterable GHRepository.getIssues(GHIssueState) would only retrieve 30 issues
|
||||
assertTrue(closedIssues.size() > 30);
|
||||
}
|
||||
|
||||
public void testRateLimit() throws IOException {
|
||||
System.out.println(gitHub.getRateLimit());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Integration test for {@link GHContent}.
|
||||
*/
|
||||
public class GHContentIntegrationTest extends TestCase {
|
||||
|
||||
private GitHub gitHub;
|
||||
private GHRepository repo;
|
||||
private String createdFilename;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
gitHub = GitHub.connect();
|
||||
repo = gitHub.getRepository("acollign/github-api-test").fork();
|
||||
createdFilename = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public void testGetFileContent() throws Exception {
|
||||
GHContent content = repo.getFileContent("ghcontent-ro/a-file-with-content");
|
||||
|
||||
assertTrue(content.isFile());
|
||||
assertEquals("thanks for reading me\n", content.getContent());
|
||||
}
|
||||
|
||||
public void testGetEmptyFileContent() throws Exception {
|
||||
GHContent content = repo.getFileContent("ghcontent-ro/an-empty-file");
|
||||
|
||||
assertTrue(content.isFile());
|
||||
assertEquals("", content.getContent());
|
||||
}
|
||||
|
||||
public void testGetDirectoryContent() throws Exception {
|
||||
List<GHContent> entries = repo.getDirectoryContent("ghcontent-ro/a-dir-with-3-entries");
|
||||
|
||||
assertTrue(entries.size() == 3);
|
||||
}
|
||||
|
||||
public void testCRUDContent() throws Exception {
|
||||
GHContentUpdateResponse created = repo.createContent("this is an awesome file I created\n", "Creating a file for integration tests.", createdFilename);
|
||||
GHContent createdContent = created.getContent();
|
||||
|
||||
assertNotNull(created.getCommit());
|
||||
assertNotNull(created.getContent());
|
||||
assertNotNull(createdContent.getContent());
|
||||
assertEquals("this is an awesome file I created\n", createdContent.getContent());
|
||||
|
||||
GHContentUpdateResponse updatedContentResponse = createdContent.update("this is some new content\n", "Updated file for integration tests.");
|
||||
GHContent updatedContent = updatedContentResponse.getContent();
|
||||
|
||||
assertNotNull(updatedContentResponse.getCommit());
|
||||
assertNotNull(updatedContentResponse.getContent());
|
||||
assertEquals("this is some new content\n", updatedContent.getContent());
|
||||
|
||||
GHContentUpdateResponse deleteResponse = updatedContent.delete("Enough of this foolishness!");
|
||||
|
||||
assertNotNull(deleteResponse.getCommit());
|
||||
assertNull(deleteResponse.getContent());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user