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);