diff --git a/pom.xml b/pom.xml
index 6298239952..3f8f786b1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,16 +3,16 @@
org.kohsuke
github-api
jar
- 1.4
+ 1.5
GitHub API for Java
http://kohsuke.org/github-api/
GitHub API for Java
-
-
- java.net-m2-repository
- java-net:/maven2-repository/trunk/repository/
-
+
+
+ maven.jenkins-ci.org
+ http://maven.jenkins-ci.org:8081/content/repositories/releases/
+
kohsuke.org
scp://kohsuke.org/home/kohsuke/kohsuke.org/github-api/
@@ -52,6 +52,11 @@
wagon-svn
1.9
+
+ org.apache.maven.wagon
+ wagon-ssh
+ 1.0-beta-7
+
diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java
index 719fb978f2..027c4529c3 100644
--- a/src/main/java/org/kohsuke/github/GHPerson.java
+++ b/src/main/java/org/kohsuke/github/GHPerson.java
@@ -1,13 +1,10 @@
package org.kohsuke.github;
import java.io.IOException;
-import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
-import static org.kohsuke.github.GitHub.*;
-
/**
* Common part of {@link GHUser} and {@link GHOrganization}.
*
@@ -31,7 +28,11 @@ public abstract class GHPerson {
public synchronized Map getRepositories() throws IOException {
if (repositories==null) {
repositories = Collections.synchronizedMap(new TreeMap());
- repositories.putAll(root.retrieve("/repos/show/" + login, JsonRepositories.class).wrap(root));
+ for (int i=1; ; i++) {
+ Map map = root.retrieve("/repos/show/" + login + "?page=" + i, JsonRepositories.class).wrap(root);
+ repositories.putAll(map);
+ if (map.isEmpty()) break;
+ }
}
return Collections.unmodifiableMap(repositories);
diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java
index d07ab6029b..140c30c254 100644
--- a/src/main/java/org/kohsuke/github/GHRepository.java
+++ b/src/main/java/org/kohsuke/github/GHRepository.java
@@ -23,17 +23,22 @@
*/
package org.kohsuke.github;
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.net.URL;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -52,6 +57,7 @@ public class GHRepository {
private String description, homepage, url, name, owner;
private boolean has_issues, has_wiki, fork, _private, has_downloads;
private int watchers,forks;
+ private String created_at, pushed_at;
public String getDescription() {
return description;
@@ -108,6 +114,23 @@ public int getWatchers() {
return watchers;
}
+ public Date getPushedAt() {
+ return parseDate(pushed_at);
+ }
+
+ public Date getCreatedAt() {
+ return parseDate(created_at);
+ }
+
+ private Date parseDate(String timestamp) {
+ try {
+ return new SimpleDateFormat(TIME_FORMAT).parse(timestamp);
+ } catch (ParseException e) {
+ throw new IllegalStateException("Unable to parse the timestamp: "+pushed_at);
+ }
+ }
+
+
/**
* Gets the collaborators on this repository.
* This set always appear to include the owner.
@@ -154,12 +177,62 @@ public void delete() throws IOException {
}
/**
- * Forks this repository.
+ * Forks this repository as your repository.
+ *
+ * @return
+ * Newly forked repository that belong to you.
*/
public GHRepository fork() throws IOException {
return new Poster(root).withCredential().to("/repos/fork/" + owner + "/" + name, JsonRepository.class).wrap(root);
}
+ /**
+ * Forks this repository into an organization.
+ *
+ * @return
+ * Newly forked repository that belong to you.
+ */
+ public GHRepository forkTo(GHOrganization org) throws IOException {
+ WebClient wc = root.createWebClient();
+ HtmlPage pg = (HtmlPage)wc.getPage(getUrl());
+ for (HtmlForm f : pg.getForms()) {
+ if (!f.getActionAttribute().endsWith("/fork")) continue;
+ try {
+ if (org.getLogin().equals(f.getInputByName("organization").getValueAttribute())) {
+ // found it
+ f.submit((HtmlButton)f.getElementsByTagName("button").get(0));
+ return org.refreshRepository(name);
+ }
+ } catch (ElementNotFoundException e) {
+ // continue
+ }
+ }
+
+ throw new IllegalArgumentException("Either you don't have the privilege to fork into "+org.getLogin()+" or there's a bug in HTML scraping");
+ }
+
+ /**
+ * Rename this repository.
+ */
+ public void renameTo(String newName) throws IOException {
+ WebClient wc = root.createWebClient();
+ HtmlPage pg = (HtmlPage)wc.getPage(getUrl()+"/admin");
+ for (HtmlForm f : pg.getForms()) {
+ if (!f.getActionAttribute().endsWith("/rename")) continue;
+ try {
+ f.getInputByName("name").setValueAttribute(newName);
+ f.submit((HtmlButton)f.getElementsByTagName("button").get(0));
+ name = newName;
+ return;
+ } catch (ElementNotFoundException e) {
+ // continue
+ }
+ }
+
+ throw new IllegalArgumentException("Either you don't have the privilege to rename "+owner+'/'+name+" or there's a bug in HTML scraping");
+ }
+
+
private void verifyMine() throws IOException {
if (!root.login.equals(owner))
throw new IOException("Operation not applicable to a repository owned by someone else: "+owner);
@@ -269,4 +342,6 @@ private HtmlForm getForm() throws IOException {
public String toString() {
return "Repository:"+owner+":"+name;
}
+
+ private static final String TIME_FORMAT = "yyyy/MM/dd HH:mm:ss ZZZZ";
}
diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java
index a327c59b85..fb0fe81f1d 100644
--- a/src/test/java/org/kohsuke/AppTest.java
+++ b/src/test/java/org/kohsuke/AppTest.java
@@ -22,6 +22,10 @@ public void testCredentialValid() throws IOException {
public void testApp() throws IOException {
GitHub gitHub = GitHub.connect();
+
+// tryRenaming(gitHub);
+// tryOrgFork(gitHub);
+
// testOrganization(gitHub);
// testPostCommitHook(gitHub);
@@ -42,6 +46,15 @@ public void testApp() throws IOException {
// System.out.println(hub.getUser("kohsuke").getRepository("hudson").getCollaborators());
}
+ private void tryRenaming(GitHub gitHub) throws IOException {
+ gitHub.getUser("kohsuke").getRepository("test").renameTo("test2");
+ }
+
+ private void tryOrgFork(GitHub gitHub) throws IOException {
+ GHOrganization o = gitHub.getOrganization("HudsonLabs");
+ System.out.println(gitHub.getUser("rtyler").getRepository("memcache-ada").forkTo(o).getUrl());
+ }
+
private void tryTeamCreation(GitHub gitHub) throws IOException {
GHOrganization o = gitHub.getOrganization("HudsonLabs");
GHTeam t = o.createTeam("auto team", Permission.PUSH);