From 959945a93d6b00cb5110d7f65774e532f60879e6 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 19 Apr 2010 09:38:25 -0700 Subject: [PATCH 1/8] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de5ce58c4f..7f5fe38d8f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.kohsuke github-api jar - 1.2 + 1.3-SNAPSHOT GitHub API for Java http://kohsuke.org/github-api/ GitHub API for Java From 7cd0d921cb849da3417159ef295e9745e20569c8 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 22 Nov 2010 21:25:51 -0800 Subject: [PATCH 2/8] adding support for creating repositories into an organization --- pom.xml | 12 ++++++ .../org/kohsuke/github/GHOrganization.java | 43 +++++++++++++++++++ src/main/java/org/kohsuke/github/GitHub.java | 37 ++++++++++++++-- .../org/kohsuke/github/JsonOrganization.java | 8 ++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHOrganization.java create mode 100644 src/main/java/org/kohsuke/github/JsonOrganization.java diff --git a/pom.xml b/pom.xml index 7f5fe38d8f..58bccfcbbd 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,18 @@ + + org.jvnet.hudson + htmlunit + 2.6-hudson-2 + + + + xml-apis + xml-apis + + + junit junit diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java new file mode 100644 index 0000000000..718c1b5f7c --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -0,0 +1,43 @@ +package org.kohsuke.github; + +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.HtmlForm; +import com.gargoylesoftware.htmlunit.html.HtmlPage; + +import java.io.IOException; + +/** + * @author Kohsuke Kawaguchi + */ +public class GHOrganization { + /*package almost final*/ GitHub root; + + private String gravatar_id,login; + private int public_repo_count, public_gist_count, following_count, id; + + /** + * Creates a new repository. + * + * @return + * Newly created repository. + */ + public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException { + // such API doesn't exist, so fall back to HTML scraping + WebClient wc = root.createWebClient(); + HtmlPage pg = (HtmlPage)wc.getPage("https://github.com/organizations/"+login+"/repositories/new"); + HtmlForm f = pg.getForms().get(1); + f.getInputByName("repository[name]").setValueAttribute(name); + f.getInputByName("repository[description]").setValueAttribute(description); + f.getInputByName("repository[homepage]").setValueAttribute(homepage); + f.getSelectByName("team_id").getOptionByText(team).setSelected(true); + f.submit(f.getButtonByCaption("Create Repository")); + + return root.getUser(login).getRepository(name); + +// GHRepository r = new Poster(root).withCredential() +// .with("name", name).with("description", description).with("homepage", homepage) +// .with("public", isPublic ? 1 : 0).to(root.getApiURL("/organizations/"+login+"/repos/create"), JsonRepository.class).repository; +// r.root = root; +// return r; + } +} diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index cd3a1ed8f8..d3a26e9b82 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -23,6 +23,9 @@ */ package org.kohsuke.github; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.HtmlForm; +import com.gargoylesoftware.htmlunit.html.HtmlPage; import org.apache.commons.io.IOUtils; import org.codehaus.jackson.map.DeserializationConfig.Feature; import org.codehaus.jackson.map.ObjectMapper; @@ -32,6 +35,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -48,12 +52,15 @@ public class GitHub { /*package*/ final String login; /*package*/ final String token; + /*package*/ final String password; private final Map users = new HashMap(); + private final Map orgs = new HashMap(); - private GitHub(String login, String apiToken) { + private GitHub(String login, String apiToken, String password) { this.login = login; this.token = apiToken; + this.password = password; } /** @@ -68,11 +75,11 @@ public static GitHub connect() throws IOException { } finally { IOUtils.closeQuietly(in); } - return new GitHub(props.getProperty("login"),props.getProperty("token")); + return new GitHub(props.getProperty("login"),props.getProperty("token"),props.getProperty("password")); } public static GitHub connect(String login, String apiToken) throws IOException { - return new GitHub(login,apiToken); + return new GitHub(login,apiToken,null); } /** @@ -81,7 +88,7 @@ public static GitHub connect(String login, String apiToken) throws IOException { * All operations that requires authentication will fail. */ public static GitHub connectAnonymously() { - return new GitHub(null,null); + return new GitHub(null,null,null); } /*package*/ void requireCredential() { @@ -110,6 +117,16 @@ public GHUser getUser(String login) throws IOException { return u; } + public GHOrganization getOrganization(String name) throws IOException { + GHOrganization o = orgs.get(name); + if (o==null) { + o = MAPPER.readValue(getApiURL("/organizations/"+name), JsonOrganization.class).organization; + o.root = this; + orgs.put(name,o); + } + return o; + } + /** * Gets the {@link GHUser} that represents yourself. */ @@ -132,6 +149,18 @@ public GHRepository createRepository(String name, String description, String hom return r; } + WebClient createWebClient() throws IOException { + WebClient wc = new WebClient(); + wc.setJavaScriptEnabled(false); + wc.setCssEnabled(false); + HtmlPage pg = (HtmlPage)wc.getPage("https://github.com/login"); + HtmlForm f = pg.getForms().get(0); + f.getInputByName("login").setValueAttribute(login); + f.getInputByName("password").setValueAttribute(password); + f.submit(); + return wc; + } + /*package*/ static final ObjectMapper MAPPER = new ObjectMapper(); diff --git a/src/main/java/org/kohsuke/github/JsonOrganization.java b/src/main/java/org/kohsuke/github/JsonOrganization.java new file mode 100644 index 0000000000..e4908f68ea --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonOrganization.java @@ -0,0 +1,8 @@ +package org.kohsuke.github; + +/** + * @author Kohsuke Kawaguchi + */ +public class JsonOrganization { + public GHOrganization organization; +} From 9b1dd273fd6dd1183f788c75e0a5d1a687d0903c Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:29:41 -0800 Subject: [PATCH 3/8] added team support --- .../org/kohsuke/github/GHOrganization.java | 13 +++++++ src/main/java/org/kohsuke/github/GHTeam.java | 37 +++++++++++++++++++ src/main/java/org/kohsuke/github/GitHub.java | 36 ++++++++++++++++++ .../java/org/kohsuke/github/JsonTeams.java | 21 +++++++++++ .../kohsuke/github/JsonUsersWithDetails.java | 20 ++++++++++ src/main/java/org/kohsuke/github/Poster.java | 5 ++- src/test/java/org/kohsuke/AppTest.java | 14 +++++-- 7 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHTeam.java create mode 100644 src/main/java/org/kohsuke/github/JsonTeams.java create mode 100644 src/main/java/org/kohsuke/github/JsonUsersWithDetails.java diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 718c1b5f7c..d327db393a 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -5,6 +5,7 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage; import java.io.IOException; +import java.util.Map; /** * @author Kohsuke Kawaguchi @@ -15,6 +16,10 @@ public class GHOrganization { private String gravatar_id,login; private int public_repo_count, public_gist_count, following_count, id; + public String getLogin() { + return login; + } + /** * Creates a new repository. * @@ -40,4 +45,12 @@ public GHRepository createRepository(String name, String description, String hom // r.root = root; // return r; } + + /** + * Teams by their names. + */ + public Map getTeams() throws IOException { + return root.retrieveWithAuth(root.getApiURL("/organizations/"+login+"/teams"),JsonTeams.class).toMap(this); + } + } diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java new file mode 100644 index 0000000000..bd5b3853ea --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -0,0 +1,37 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; +import java.util.Set; + +/** + * A team in GitHub organization. + * + * @author Kohsuke Kawaguchi + */ +public class GHTeam { + private String name,permission; + private int id; + + protected /*final*/ GHOrganization org; + + public String getName() { + return name; + } + + public String getPermission() { + return permission; + } + + public int getId() { + return id; + } + + public Set getMembers() throws IOException { + return org.root.retrieveWithAuth(getApiURL("/members"),JsonUsersWithDetails.class).toSet(org.root); + } + + private URL getApiURL(String tail) throws IOException { + return org.root.getApiURL("/organizations/"+org.getLogin()+"/teams/"+id+tail); + } +} diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index d3a26e9b82..93292f0994 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -30,11 +30,14 @@ import org.codehaus.jackson.map.DeserializationConfig.Feature; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.introspect.VisibilityChecker.Std; +import sun.misc.BASE64Encoder; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; @@ -104,6 +107,26 @@ public static GitHub connectAnonymously() { return MAPPER.readValue(getApiURL(tail),type); } + /*package*/ T retrieveWithAuth(URL url, Class type) throws IOException { + HttpURLConnection uc = (HttpURLConnection) url.openConnection(); + + BASE64Encoder enc = new sun.misc.BASE64Encoder(); + String userpassword = login + "/token" + ":" + token; + String encodedAuthorization = enc.encode(userpassword.getBytes()); + uc.setRequestProperty("Authorization", "Basic " + encodedAuthorization); + + try { + InputStreamReader r = new InputStreamReader(uc.getInputStream(), "UTF-8"); + if (type==null) { + String data = IOUtils.toString(r); + return null; + } + return MAPPER.readValue(r,type); + } catch (IOException e) { + throw (IOException)new IOException(IOUtils.toString(uc.getErrorStream(),"UTF-8")).initCause(e); + } + } + /** * Obtains the object that represents the named user. */ @@ -117,6 +140,19 @@ public GHUser getUser(String login) throws IOException { return u; } + /** + * Interns the given {@link GHUser}. + */ + protected GHUser getUser(GHUser orig) throws IOException { + GHUser u = users.get(orig.getLogin()); + if (u==null) { + orig.root = this; + users.put(login,orig); + return orig; + } + return u; + } + public GHOrganization getOrganization(String name) throws IOException { GHOrganization o = orgs.get(name); if (o==null) { diff --git a/src/main/java/org/kohsuke/github/JsonTeams.java b/src/main/java/org/kohsuke/github/JsonTeams.java new file mode 100644 index 0000000000..1f1db72ba7 --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonTeams.java @@ -0,0 +1,21 @@ +package org.kohsuke.github; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonTeams { + public List teams; + + Map toMap(GHOrganization org) { + Map r = new TreeMap(); + for (GHTeam t : teams) { + t.org = org; + r.put(t.getName(),t); + } + return r; + } +} diff --git a/src/main/java/org/kohsuke/github/JsonUsersWithDetails.java b/src/main/java/org/kohsuke/github/JsonUsersWithDetails.java new file mode 100644 index 0000000000..424e53c9da --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonUsersWithDetails.java @@ -0,0 +1,20 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonUsersWithDetails { + public List users; + + public Set toSet(GitHub root) throws IOException { + Set r = new HashSet(); + for (GHUser u : users) + r.add(root.getUser(u)); + return r; + } +} diff --git a/src/main/java/org/kohsuke/github/Poster.java b/src/main/java/org/kohsuke/github/Poster.java index a6eafdf823..4ae23de89b 100644 --- a/src/main/java/org/kohsuke/github/Poster.java +++ b/src/main/java/org/kohsuke/github/Poster.java @@ -100,7 +100,10 @@ public T to(URL url, Class type) throws IOException { try { InputStreamReader r = new InputStreamReader(uc.getInputStream(), "UTF-8"); - if (type==null) return null; + if (type==null) { + String data = IOUtils.toString(r); + return null; + } return MAPPER.readValue(r,type); } catch (IOException e) { throw (IOException)new IOException(IOUtils.toString(uc.getErrorStream(),"UTF-8")).initCause(e); diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index ebbce47e3a..084c425230 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -3,6 +3,7 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.kohsuke.github.GHRepository; import org.kohsuke.github.GitHub; import java.io.IOException; @@ -12,10 +13,15 @@ */ public class AppTest extends TestCase { public void testApp() throws IOException { - GitHub hub = GitHub.connectAnonymously(); -// hub.createRepository("test","test repository",null,true); -// hub.getUser("kohsuke").getRepository("test").delete(); + System.out.println(GitHub.connect().getOrganization("HudsonLabs").getTeams().get("Core Developers").getMembers()); - System.out.println(hub.getUser("kohsuke").getRepository("hudson").getCollaborators()); +// GHRepository r = GitHub.connect().getOrganization("HudsonLabs").createRepository("auto-test", "some description", "http://kohsuke.org/", "Plugin Developers", true); + +// r. +// GitHub hub = GitHub.connectAnonymously(); +//// hub.createRepository("test","test repository",null,true); +//// hub.getUser("kohsuke").getRepository("test").delete(); +// +// System.out.println(hub.getUser("kohsuke").getRepository("hudson").getCollaborators()); } } From ea97f8108f7813c8f4a56394a019299cc7529652 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:35:50 -0800 Subject: [PATCH 4/8] member addition and removal --- src/main/java/org/kohsuke/github/GHTeam.java | 11 +++++++++++ src/main/java/org/kohsuke/github/GitHub.java | 6 +++++- src/main/java/org/kohsuke/github/Poster.java | 6 +++++- src/test/java/org/kohsuke/AppTest.java | 8 +++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index bd5b3853ea..e76626cdb8 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -27,10 +27,21 @@ public int getId() { return id; } + /** + * Retrieves the current members. + */ public Set getMembers() throws IOException { return org.root.retrieveWithAuth(getApiURL("/members"),JsonUsersWithDetails.class).toSet(org.root); } + public void add(GHUser u) throws IOException { + org.root.retrieveWithAuth(getApiURL("/members?name="+u.getLogin()),null, "POST"); + } + + public void remove(GHUser u) throws IOException { + org.root.retrieveWithAuth(getApiURL("/members?name="+u.getLogin()),null, "DELETE"); + } + private URL getApiURL(String tail) throws IOException { return org.root.getApiURL("/organizations/"+org.getLogin()+"/teams/"+id+tail); } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 93292f0994..8216ed6ba0 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -108,13 +108,17 @@ public static GitHub connectAnonymously() { } /*package*/ T retrieveWithAuth(URL url, Class type) throws IOException { + return retrieveWithAuth(url,type,"GET"); + } + /*package*/ T retrieveWithAuth(URL url, Class type, String method) throws IOException { HttpURLConnection uc = (HttpURLConnection) url.openConnection(); BASE64Encoder enc = new sun.misc.BASE64Encoder(); String userpassword = login + "/token" + ":" + token; String encodedAuthorization = enc.encode(userpassword.getBytes()); uc.setRequestProperty("Authorization", "Basic " + encodedAuthorization); - + uc.setRequestMethod(method); + try { InputStreamReader r = new InputStreamReader(uc.getInputStream(), "UTF-8"); if (type==null) { diff --git a/src/main/java/org/kohsuke/github/Poster.java b/src/main/java/org/kohsuke/github/Poster.java index 4ae23de89b..0f4a939358 100644 --- a/src/main/java/org/kohsuke/github/Poster.java +++ b/src/main/java/org/kohsuke/github/Poster.java @@ -78,11 +78,15 @@ public void to(URL url) throws IOException { * {@link Reader} that reads the response. */ public T to(URL url, Class type) throws IOException { + return to(url,type,"POST"); + } + + public T to(URL url, Class type, String method) throws IOException { HttpURLConnection uc = (HttpURLConnection) url.openConnection(); uc.setDoOutput(true); uc.setRequestProperty("Content-type","application/x-www-form-urlencoded"); - uc.setRequestMethod("POST"); + uc.setRequestMethod(method); StringBuilder body = new StringBuilder(); diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index 084c425230..07267ce7f5 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -4,6 +4,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GHTeam; import org.kohsuke.github.GitHub; import java.io.IOException; @@ -13,7 +14,12 @@ */ public class AppTest extends TestCase { public void testApp() throws IOException { - System.out.println(GitHub.connect().getOrganization("HudsonLabs").getTeams().get("Core Developers").getMembers()); + GitHub gitHub = GitHub.connect(); + GHTeam t = gitHub.getOrganization("HudsonLabs").getTeams().get("Core Developers"); + t.add(gitHub.getMyself()); + System.out.println(t.getMembers()); + t.remove(gitHub.getMyself()); + System.out.println(t.getMembers()); // GHRepository r = GitHub.connect().getOrganization("HudsonLabs").createRepository("auto-test", "some description", "http://kohsuke.org/", "Plugin Developers", true); From 5159a21de1369e0d760757c3c154844d19dc933d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:36:35 -0800 Subject: [PATCH 5/8] doc improvement --- src/main/java/org/kohsuke/github/GHTeam.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index e76626cdb8..afff039898 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -34,10 +34,16 @@ public Set getMembers() throws IOException { return org.root.retrieveWithAuth(getApiURL("/members"),JsonUsersWithDetails.class).toSet(org.root); } + /** + * Adds a member to the team. + */ public void add(GHUser u) throws IOException { org.root.retrieveWithAuth(getApiURL("/members?name="+u.getLogin()),null, "POST"); } + /** + * Removes a member to the team. + */ public void remove(GHUser u) throws IOException { org.root.retrieveWithAuth(getApiURL("/members?name="+u.getLogin()),null, "DELETE"); } From e665365f115f6bce1ee62fc383b69ce01c21da62 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:51:14 -0800 Subject: [PATCH 6/8] introduced the common base type between GHOrganization and GHUser. --- .../org/kohsuke/github/GHOrganization.java | 12 +--- .../java/org/kohsuke/github/GHPerson.java | 58 +++++++++++++++++++ .../java/org/kohsuke/github/GHRepository.java | 8 ++- src/main/java/org/kohsuke/github/GHTeam.java | 8 +++ src/main/java/org/kohsuke/github/GHUser.java | 46 +-------------- src/main/java/org/kohsuke/github/GitHub.java | 6 +- .../org/kohsuke/github/JsonRepository.java | 5 ++ src/test/java/org/kohsuke/AppTest.java | 15 +++-- 8 files changed, 92 insertions(+), 66 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHPerson.java diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index d327db393a..24405373b6 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -10,16 +10,7 @@ /** * @author Kohsuke Kawaguchi */ -public class GHOrganization { - /*package almost final*/ GitHub root; - - private String gravatar_id,login; - private int public_repo_count, public_gist_count, following_count, id; - - public String getLogin() { - return login; - } - +public class GHOrganization extends GHPerson { /** * Creates a new repository. * @@ -52,5 +43,4 @@ public GHRepository createRepository(String name, String description, String hom public Map getTeams() throws IOException { return root.retrieveWithAuth(root.getApiURL("/organizations/"+login+"/teams"),JsonTeams.class).toMap(this); } - } diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java new file mode 100644 index 0000000000..db87442484 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -0,0 +1,58 @@ +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}. + * + * @author Kohsuke Kawaguchi + */ +public abstract class GHPerson { + /*package almost final*/ GitHub root; + + protected String gravatar_id,login; + + protected int public_gist_count,public_repo_count,following_count,id; + + /** + * Repositories that this user owns. + */ + private transient Map repositories; + + /** + * Gets the repositories this user owns. + */ + public Map getRepositories() throws IOException { + if (repositories==null) { + repositories = new TreeMap(); + URL url = new URL("http://github.com/api/v2/json/repos/show/" + login); + for (GHRepository r : MAPPER.readValue(url, JsonRepositories.class).repositories) { + r.root = root; + repositories.put(r.getName(),r); + } + } + + return Collections.unmodifiableMap(repositories); + } + + public GHRepository getRepository(String name) throws IOException { + return getRepositories().get(name); + } + + /** + * Gravatar ID of this user, like 0cb9832a01c22c083390f3c5dcb64105 + */ + public String getGravatarId() { + return gravatar_id; + } + + public String getLogin() { + return login; + } +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 69f7711a60..116b454b3e 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -64,6 +64,10 @@ public GHUser getOwner() throws IOException { return root.getUser(owner); } + protected String getOwnerName() { + return owner; + } + public boolean hasIssues() { return has_issues; } @@ -142,9 +146,7 @@ public void delete() throws IOException { * Forks this repository. */ public GHRepository fork() throws IOException { - GHRepository r = new Poster(root).withCredential().to(root.getApiURL("/repos/fork/" + owner + "/" + name), JsonRepository.class).repository; - r.root = root; - return r; + return new Poster(root).withCredential().to(root.getApiURL("/repos/fork/" + owner + "/" + name), JsonRepository.class).wrap(root); } private void verifyMine() throws IOException { diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index afff039898..84d5efc789 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -48,6 +48,14 @@ public void remove(GHUser u) throws IOException { org.root.retrieveWithAuth(getApiURL("/members?name="+u.getLogin()),null, "DELETE"); } + public void add(GHRepository r) throws IOException { + org.root.retrieveWithAuth(getApiURL("/repositories?name="+r.getOwnerName()+'/'+r.getName()),null, "POST"); + } + + public void remove(GHRepository r) throws IOException { + org.root.retrieveWithAuth(getApiURL("/repositories?name="+r.getOwnerName()+'/'+r.getName()),null, "DELETE"); + } + private URL getApiURL(String tail) throws IOException { return org.root.getApiURL("/organizations/"+org.getLogin()+"/teams/"+id+tail); } diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java index b439ca4ee8..205b466c0e 100644 --- a/src/main/java/org/kohsuke/github/GHUser.java +++ b/src/main/java/org/kohsuke/github/GHUser.java @@ -24,36 +24,16 @@ package org.kohsuke.github; import java.io.IOException; -import java.net.URL; -import java.util.Collections; -import java.util.Map; import java.util.Set; -import java.util.TreeMap; - -import static org.kohsuke.github.GitHub.MAPPER; /** * Represents an user of GitHub. * * @author Kohsuke Kawaguchi */ -public class GHUser { - /*package almost final*/ GitHub root; - - private String gravatar_id,name,company,location,created_at,blog,login,email; - private int public_gist_count,public_repo_count,following_count,id,followers_count; - - /** - * Repositories that this user owns. - */ - private transient Map repositories; - - /** - * Gravatar ID of this user, like 0cb9832a01c22c083390f3c5dcb64105 - */ - public String getGravatarId() { - return gravatar_id; - } +public class GHUser extends GHPerson { + private String name,company,location,created_at,blog,email; + private int followers_count; /** * Gets the human-readable name of the user, like "Kohsuke Kawaguchi" @@ -124,26 +104,6 @@ public int getFollowersCount() { return followers_count; } - /** - * Gets the repositories this user owns. - */ - public Map getRepositories() throws IOException { - if (repositories==null) { - repositories = new TreeMap(); - URL url = new URL("http://github.com/api/v2/json/repos/show/" + login); - for (GHRepository r : MAPPER.readValue(url, JsonRepositories.class).repositories) { - r.root = root; - repositories.put(r.getName(),r); - } - } - - return Collections.unmodifiableMap(repositories); - } - - public GHRepository getRepository(String name) throws IOException { - return getRepositories().get(name); - } - /** * Follow this user. */ diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 8216ed6ba0..616c123908 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -182,11 +182,9 @@ public GHUser getMyself() throws IOException { * Newly created repository. */ public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException { - GHRepository r = new Poster(this).withCredential() + return new Poster(this).withCredential() .with("name", name).with("description", description).with("homepage", homepage) - .with("public", isPublic ? 1 : 0).to(getApiURL("/repos/create"), JsonRepository.class).repository; - r.root = this; - return r; + .with("public", isPublic ? 1 : 0).to(getApiURL("/repos/create"), JsonRepository.class).wrap(this); } WebClient createWebClient() throws IOException { diff --git a/src/main/java/org/kohsuke/github/JsonRepository.java b/src/main/java/org/kohsuke/github/JsonRepository.java index 1f13a196b3..eb8eadd315 100644 --- a/src/main/java/org/kohsuke/github/JsonRepository.java +++ b/src/main/java/org/kohsuke/github/JsonRepository.java @@ -28,4 +28,9 @@ */ class JsonRepository { public GHRepository repository; + + public GHRepository wrap(GitHub root) { + repository.root = root; + return repository; + } } diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java index 07267ce7f5..84ba0d6d8d 100644 --- a/src/test/java/org/kohsuke/AppTest.java +++ b/src/test/java/org/kohsuke/AppTest.java @@ -3,6 +3,7 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.kohsuke.github.GHOrganization; import org.kohsuke.github.GHRepository; import org.kohsuke.github.GHTeam; import org.kohsuke.github.GitHub; @@ -15,11 +16,15 @@ public class AppTest extends TestCase { public void testApp() throws IOException { GitHub gitHub = GitHub.connect(); - GHTeam t = gitHub.getOrganization("HudsonLabs").getTeams().get("Core Developers"); - t.add(gitHub.getMyself()); - System.out.println(t.getMembers()); - t.remove(gitHub.getMyself()); - System.out.println(t.getMembers()); + GHOrganization labs = gitHub.getOrganization("HudsonLabs"); + GHTeam t = labs.getTeams().get("Core Developers"); + + t.add(labs.getRepository("xyz")); + +// t.add(gitHub.getMyself()); +// System.out.println(t.getMembers()); +// t.remove(gitHub.getMyself()); +// System.out.println(t.getMembers()); // GHRepository r = GitHub.connect().getOrganization("HudsonLabs").createRepository("auto-test", "some description", "http://kohsuke.org/", "Plugin Developers", true); From efdabb819b67c34aeb9e8f0bca2be0ac0055845f Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:51:37 -0800 Subject: [PATCH 7/8] shouldn't be public --- src/main/java/org/kohsuke/github/JsonOrganization.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/JsonOrganization.java b/src/main/java/org/kohsuke/github/JsonOrganization.java index e4908f68ea..02c7479b84 100644 --- a/src/main/java/org/kohsuke/github/JsonOrganization.java +++ b/src/main/java/org/kohsuke/github/JsonOrganization.java @@ -3,6 +3,6 @@ /** * @author Kohsuke Kawaguchi */ -public class JsonOrganization { +class JsonOrganization { public GHOrganization organization; } From 31028a31e67b968411b6de4a0fd52bfd0b82e522 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 23 Nov 2010 21:52:24 -0800 Subject: [PATCH 8/8] [maven-release-plugin] prepare release github-api-1.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 58bccfcbbd..fec4cefb66 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.kohsuke github-api jar - 1.3-SNAPSHOT + 1.3 GitHub API for Java http://kohsuke.org/github-api/ GitHub API for Java