diff --git a/pom.xml b/pom.xml
index fec4cefb66..6298239952 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.kohsuke
github-api
jar
- 1.3
+ 1.4
GitHub API for Java
http://kohsuke.org/github-api/
GitHub API for Java
diff --git a/src/main/java/org/kohsuke/github/GHException.java b/src/main/java/org/kohsuke/github/GHException.java
new file mode 100644
index 0000000000..c238e53c9e
--- /dev/null
+++ b/src/main/java/org/kohsuke/github/GHException.java
@@ -0,0 +1,14 @@
+package org.kohsuke.github;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+public class GHException extends RuntimeException {
+ public GHException(String message) {
+ super(message);
+ }
+
+ public GHException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java
index 24405373b6..8f08877862 100644
--- a/src/main/java/org/kohsuke/github/GHOrganization.java
+++ b/src/main/java/org/kohsuke/github/GHOrganization.java
@@ -5,6 +5,8 @@
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Map;
/**
@@ -28,7 +30,7 @@ public GHRepository createRepository(String name, String description, String hom
f.getSelectByName("team_id").getOptionByText(team).setSelected(true);
f.submit(f.getButtonByCaption("Create Repository"));
- return root.getUser(login).getRepository(name);
+ return refreshRepository(name);
// GHRepository r = new Poster(root).withCredential()
// .with("name", name).with("description", description).with("homepage", homepage)
@@ -41,6 +43,24 @@ public GHRepository createRepository(String name, String description, String hom
* Teams by their names.
*/
public Map getTeams() throws IOException {
- return root.retrieveWithAuth(root.getApiURL("/organizations/"+login+"/teams"),JsonTeams.class).toMap(this);
+ return root.retrieveWithAuth("/organizations/"+login+"/teams",JsonTeams.class).toMap(this);
}
+
+ public enum Permission { ADMIN, PUSH, PULL }
+
+ /**
+ * Creates a new team and assigns the repositories.
+ */
+ public GHTeam createTeam(String name, Permission p, Collection repositories) throws IOException {
+ Poster post = new Poster(root).withCredential().with("team[name]", name).with("team[permission]", p.name().toLowerCase());
+ for (GHRepository r : repositories) {
+ post.with("team[repo_names][]",r.getOwnerName()+'/'+r.getName());
+ }
+ return post.to("/organizations/"+login+"/teams",JsonTeam.class).wrap(this);
+ }
+
+ public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException {
+ return createTeam(name,p, Arrays.asList(repositories));
+ }
+
}
diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java
index db87442484..719fb978f2 100644
--- a/src/main/java/org/kohsuke/github/GHPerson.java
+++ b/src/main/java/org/kohsuke/github/GHPerson.java
@@ -28,19 +28,25 @@ public abstract class GHPerson {
/**
* Gets the repositories this user owns.
*/
- public Map getRepositories() throws IOException {
+ public synchronized 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);
- }
+ repositories = Collections.synchronizedMap(new TreeMap());
+ repositories.putAll(root.retrieve("/repos/show/" + login, JsonRepositories.class).wrap(root));
}
return Collections.unmodifiableMap(repositories);
}
+ /**
+ * Fetches the repository of the given name from GitHub, and return it.
+ */
+ protected GHRepository refreshRepository(String name) throws IOException {
+ if (repositories==null) getRepositories(); // fetch the base first
+ GHRepository r = root.retrieve("/repos/show/" + login + '/' + name, JsonRepository.class).wrap(root);
+ repositories.put(name,r);
+ return r;
+ }
+
public GHRepository getRepository(String name) throws IOException {
return getRepositories().get(name);
}
diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java
index 116b454b3e..d07ab6029b 100644
--- a/src/main/java/org/kohsuke/github/GHRepository.java
+++ b/src/main/java/org/kohsuke/github/GHRepository.java
@@ -23,14 +23,23 @@
*/
package org.kohsuke.github;
+import com.gargoylesoftware.htmlunit.WebClient;
+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.util.AbstractSet;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
import java.util.Set;
-import static java.util.Arrays.asList;
+import static java.util.Arrays.*;
/**
* A repository on GitHub.
@@ -52,6 +61,9 @@ public String getHomepage() {
return homepage;
}
+ /**
+ * URL of this repository, like 'http://github.com/kohsuke/hudson'
+ */
public String getUrl() {
return url;
}
@@ -126,7 +138,7 @@ public void removeCollaborators(Collection users) throws IOException {
private void modifyCollaborators(Collection users, String op) throws IOException {
verifyMine();
for (GHUser user : users) {
- new Poster(root).withCredential().to(root.getApiURL("/repos/collaborators/"+name+ op +user.getLogin()));
+ new Poster(root).withCredential().to("/repos/collaborators/"+name+ op +user.getLogin());
}
}
@@ -134,9 +146,8 @@ private void modifyCollaborators(Collection users, String op) throws IOE
* Deletes this repository.
*/
public void delete() throws IOException {
- verifyMine();
Poster poster = new Poster(root).withCredential();
- URL url = root.getApiURL("/repos/delete/" + name);
+ String url = "/repos/delete/" + owner +"/"+name;
DeleteToken token = poster.to(url, DeleteToken.class);
poster.with("delete_token",token.delete_token).to(url);
@@ -146,7 +157,7 @@ public void delete() throws IOException {
* Forks this repository.
*/
public GHRepository fork() throws IOException {
- return new Poster(root).withCredential().to(root.getApiURL("/repos/fork/" + owner + "/" + name), JsonRepository.class).wrap(root);
+ return new Poster(root).withCredential().to("/repos/fork/" + owner + "/" + name, JsonRepository.class).wrap(root);
}
private void verifyMine() throws IOException {
@@ -154,6 +165,106 @@ private void verifyMine() throws IOException {
throw new IOException("Operation not applicable to a repository owned by someone else: "+owner);
}
+ /**
+ * Returns a set that represents the post-commit hook URLs.
+ * The returned set is live, and changes made to them are reflected to GitHub.
+ */
+ public Set getPostCommitHooks() {
+ return postCommitHooks;
+ }
+
+ /**
+ * Live set view of the post-commit hook.
+ */
+ private final Set postCommitHooks = new AbstractSet() {
+ private List getPostCommitHooks() {
+ try {
+ verifyMine();
+
+ HtmlForm f = getForm();
+
+ List r = new ArrayList();
+ for (HtmlInput i : f.getInputsByName("urls[]")) {
+ String v = i.getValueAttribute();
+ if (v.length()==0) continue;
+ r.add(new URL(v));
+ }
+ return r;
+ } catch (IOException e) {
+ throw new GHException("Failed to retrieve post-commit hooks",e);
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ return getPostCommitHooks().iterator();
+ }
+
+ @Override
+ public int size() {
+ return getPostCommitHooks().size();
+ }
+
+ @Override
+ public boolean add(URL url) {
+ try {
+ String u = url.toExternalForm();
+
+ verifyMine();
+
+ HtmlForm f = getForm();
+
+ List controls = f.getInputsByName("urls[]");
+ for (HtmlInput i : controls) {
+ String v = i.getValueAttribute();
+ if (v.length()==0) continue;
+ if (v.equals(u))
+ return false; // already there
+ }
+
+ controls.get(controls.size()-1).setValueAttribute(u);
+ f.submit(null);
+ return true;
+ } catch (IOException e) {
+ throw new GHException("Failed to update post-commit hooks",e);
+ }
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ try {
+ String u = ((URL)o).toExternalForm();
+
+ verifyMine();
+
+ HtmlForm f = getForm();
+
+ List controls = f.getInputsByName("urls[]");
+ for (HtmlInput i : controls) {
+ String v = i.getValueAttribute();
+ if (v.length()==0) continue;
+ if (v.equals(u)) {
+ i.setValueAttribute("");
+ f.submit(null);
+ return true;
+ }
+ }
+
+ return false;
+ } catch (IOException e) {
+ throw new GHException("Failed to update post-commit hooks",e);
+ }
+ }
+
+ private HtmlForm getForm() throws IOException {
+ WebClient wc = root.createWebClient();
+ HtmlPage pg = (HtmlPage)wc.getPage(getUrl()+"/admin");
+ HtmlForm f = (HtmlForm) pg.getElementById("new_service");
+ return f;
+ }
+ };
+
+
@Override
public String toString() {
return "Repository:"+owner+":"+name;
diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java
index 84d5efc789..dee87bc4e3 100644
--- a/src/main/java/org/kohsuke/github/GHTeam.java
+++ b/src/main/java/org/kohsuke/github/GHTeam.java
@@ -1,7 +1,7 @@
package org.kohsuke.github;
import java.io.IOException;
-import java.net.URL;
+import java.util.Map;
import java.util.Set;
/**
@@ -31,32 +31,36 @@ public int getId() {
* Retrieves the current members.
*/
public Set getMembers() throws IOException {
- return org.root.retrieveWithAuth(getApiURL("/members"),JsonUsersWithDetails.class).toSet(org.root);
+ return org.root.retrieveWithAuth(api("/members"),JsonUsersWithDetails.class).toSet(org.root);
+ }
+
+ public Map getRepositories() throws IOException {
+ return org.root.retrieveWithAuth(api("/repositories"),JsonRepositories.class).wrap(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");
+ org.root.retrieveWithAuth(api("/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");
+ org.root.retrieveWithAuth(api("/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");
+ org.root.retrieveWithAuth(api("/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");
+ org.root.retrieveWithAuth(api("/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);
+ private String api(String tail) {
+ return "/teams/"+id+tail;
}
}
diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java
index 205b466c0e..178ea0e68b 100644
--- a/src/main/java/org/kohsuke/github/GHUser.java
+++ b/src/main/java/org/kohsuke/github/GHUser.java
@@ -108,14 +108,14 @@ public int getFollowersCount() {
* Follow this user.
*/
public void follow() throws IOException {
- new Poster(root).withCredential().to(root.getApiURL("/user/follow/"+login));
+ new Poster(root).withCredential().to("/user/follow/"+login);
}
/**
* Unfollow this user.
*/
public void unfollow() throws IOException {
- new Poster(root).withCredential().to(root.getApiURL("/user/unfollow/"+login));
+ new Poster(root).withCredential().to("/user/unfollow/"+login);
}
/**
diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java
index 616c123908..db791305a1 100644
--- a/src/main/java/org/kohsuke/github/GitHub.java
+++ b/src/main/java/org/kohsuke/github/GitHub.java
@@ -34,18 +34,16 @@
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.ANY;
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.*;
/**
* Root of the GitHub API.
@@ -54,16 +52,22 @@
*/
public class GitHub {
/*package*/ final String login;
- /*package*/ final String token;
- /*package*/ final String password;
+ /*package*/ final String encodedAuthorization;
+ final String password;
private final Map users = new HashMap();
private final Map orgs = new HashMap();
private GitHub(String login, String apiToken, String password) {
this.login = login;
- this.token = apiToken;
this.password = password;
+
+ BASE64Encoder enc = new sun.misc.BASE64Encoder();
+ if (apiToken!=null || password!=null) {
+ String userpassword = apiToken!=null ? (login + "/token" + ":" + apiToken) : (login + ':'+password);
+ encodedAuthorization = enc.encode(userpassword.getBytes());
+ } else
+ encodedAuthorization = null;
}
/**
@@ -85,6 +89,10 @@ public static GitHub connect(String login, String apiToken) throws IOException {
return new GitHub(login,apiToken,null);
}
+ public static GitHub connect(String login, String apiToken, String password) throws IOException {
+ return new GitHub(login,apiToken,password);
+ }
+
/**
* Connects to GitHub anonymously.
*
@@ -95,40 +103,63 @@ public static GitHub connectAnonymously() {
}
/*package*/ void requireCredential() {
- if (login ==null || token ==null)
+ if (login==null || encodedAuthorization==null)
throw new IllegalStateException("This operation requires a credential but none is given to the GitHub constructor");
}
- /*package*/ URL getApiURL(String tail) throws IOException {
- return new URL("http://github.com/api/v2/json"+tail);
+ /*package*/ URL getApiURL(String tailApiUrl) throws IOException {
+ return new URL("http://github.com/api/v2/json"+tailApiUrl);
}
- /*package*/ T retrieve(String tail, Class type) throws IOException {
- return MAPPER.readValue(getApiURL(tail),type);
+ /*package*/ T retrieve(String tailApiUrl, Class type) throws IOException {
+ return _retrieve(tailApiUrl, type, "GET", false);
}
- /*package*/ T retrieveWithAuth(URL url, Class type) throws IOException {
- return retrieveWithAuth(url,type,"GET");
+ /*package*/ T retrieveWithAuth(String tailApiUrl, Class type) throws IOException {
+ return retrieveWithAuth(tailApiUrl,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) {
- String data = IOUtils.toString(r);
- return null;
+ /*package*/ T retrieveWithAuth(String tailApiUrl, Class type, String method) throws IOException {
+ return _retrieve(tailApiUrl, type, method, true);
+ }
+
+ private T _retrieve(String tailApiUrl, Class type, String method, boolean withAuth) throws IOException {
+ while (true) {// loop while API rate limit is hit
+ HttpURLConnection uc = (HttpURLConnection) getApiURL(tailApiUrl).openConnection();
+
+ if (withAuth)
+ uc.setRequestProperty("Authorization", "Basic " + encodedAuthorization);
+ uc.setRequestMethod(method);
+
+ 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) {
+ handleApiError(e,uc);
+ }
+ }
+ }
+
+ /**
+ * If the error is because of the API limit, wait 10 sec and return normally.
+ * Otherwise throw an exception reporting an error.
+ */
+ /*package*/ void handleApiError(IOException e, HttpURLConnection uc) throws IOException {
+ if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) {
+ // API limit reached. wait 10 secs and return normally
+ try {
+ Thread.sleep(10000);
+ return;
+ } catch (InterruptedException _) {
+ throw (InterruptedIOException)new InterruptedIOException().initCause(e);
}
- return MAPPER.readValue(r,type);
- } catch (IOException e) {
- throw (IOException)new IOException(IOUtils.toString(uc.getErrorStream(),"UTF-8")).initCause(e);
}
+
+ throw (IOException)new IOException(IOUtils.toString(uc.getErrorStream(),"UTF-8")).initCause(e);
}
/**
@@ -137,7 +168,7 @@ public static GitHub connectAnonymously() {
public GHUser getUser(String login) throws IOException {
GHUser u = users.get(login);
if (u==null) {
- u = MAPPER.readValue(getApiURL("/user/show/"+login), JsonUser.class).user;
+ u = retrieve("/user/show/"+login,JsonUser.class).user;
u.root = this;
users.put(login,u);
}
@@ -160,7 +191,7 @@ protected GHUser getUser(GHUser orig) throws IOException {
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 = retrieve("/organizations/"+name,JsonOrganization.class).organization;
o.root = this;
orgs.put(name,o);
}
@@ -184,7 +215,19 @@ public GHUser getMyself() throws IOException {
public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException {
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).wrap(this);
+ .with("public", isPublic ? 1 : 0).to("/repos/create", JsonRepository.class).wrap(this);
+ }
+
+ /**
+ * Ensures that the credential is valid.
+ */
+ public boolean isCredentialValid() throws IOException {
+ try {
+ retrieveWithAuth("/user/show",JsonUser.class);
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
}
WebClient createWebClient() throws IOException {
diff --git a/src/main/java/org/kohsuke/github/JsonRepositories.java b/src/main/java/org/kohsuke/github/JsonRepositories.java
index b3a08853ae..69e0b138c7 100644
--- a/src/main/java/org/kohsuke/github/JsonRepositories.java
+++ b/src/main/java/org/kohsuke/github/JsonRepositories.java
@@ -24,10 +24,21 @@
package org.kohsuke.github;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
/**
* @author Kohsuke Kawaguchi
*/
class JsonRepositories {
public List repositories;
+
+ public Map wrap(GitHub root) {
+ Map map = new TreeMap();
+ for (GHRepository r : repositories) {
+ r.root = root;
+ map.put(r.getName(),r);
+ }
+ return map;
+ }
}
diff --git a/src/main/java/org/kohsuke/github/JsonTeam.java b/src/main/java/org/kohsuke/github/JsonTeam.java
new file mode 100644
index 0000000000..63fde02765
--- /dev/null
+++ b/src/main/java/org/kohsuke/github/JsonTeam.java
@@ -0,0 +1,13 @@
+package org.kohsuke.github;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+public class JsonTeam {
+ public GHTeam team;
+
+ GHTeam wrap(GHOrganization org) {
+ team.org = org;
+ return team;
+ }
+}
diff --git a/src/main/java/org/kohsuke/github/Poster.java b/src/main/java/org/kohsuke/github/Poster.java
index 0f4a939358..700eb5f532 100644
--- a/src/main/java/org/kohsuke/github/Poster.java
+++ b/src/main/java/org/kohsuke/github/Poster.java
@@ -29,14 +29,13 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
+import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
-import java.net.URL;
import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.ArrayList;
+import java.util.List;
-import static org.kohsuke.github.GitHub.MAPPER;
+import static org.kohsuke.github.GitHub.*;
/**
* Handles HTTP POST.
@@ -44,7 +43,8 @@
*/
class Poster {
private final GitHub root;
- private final Map args = new HashMap();
+ private final List args = new ArrayList();
+ private boolean authenticate;
Poster(GitHub root) {
this.root = root;
@@ -52,7 +52,8 @@ class Poster {
public Poster withCredential() {
root.requireCredential();
- return with("login",root.login).with("token",root.token);
+ authenticate = true;
+ return this;
}
public Poster with(String key, int value) {
@@ -60,13 +61,18 @@ public Poster with(String key, int value) {
}
public Poster with(String key, String value) {
- if (value!=null)
- this.args.put(key,value);
+ if (value!=null) {
+ try {
+ args.add(URLEncoder.encode(key,"UTF-8")+'='+URLEncoder.encode(value,"UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new Error(e); // impossible
+ }
+ }
return this;
}
- public void to(URL url) throws IOException {
- to(url,null);
+ public void to(String tailApiUrl) throws IOException {
+ to(tailApiUrl,null);
}
/**
@@ -77,40 +83,41 @@ public void to(URL url) throws IOException {
* @return
* {@link Reader} that reads the response.
*/
- public T to(URL url, Class type) throws IOException {
- return to(url,type,"POST");
+ public T to(String tailApiUrl, Class type) throws IOException {
+ return to(tailApiUrl,type,"POST");
}
- public T to(URL url, Class type, String method) throws IOException {
- HttpURLConnection uc = (HttpURLConnection) url.openConnection();
+ public T to(String tailApiUrl, Class type, String method) throws IOException {
+ while (true) {// loop while API rate limit is hit
+ HttpURLConnection uc = (HttpURLConnection) root.getApiURL(tailApiUrl).openConnection();
- uc.setDoOutput(true);
- uc.setRequestProperty("Content-type","application/x-www-form-urlencoded");
- uc.setRequestMethod(method);
+ uc.setDoOutput(true);
+ uc.setRequestProperty("Content-type","application/x-www-form-urlencoded");
+ if (authenticate)
+ uc.setRequestProperty("Authorization", "Basic " + root.encodedAuthorization);
+ uc.setRequestMethod(method);
- StringBuilder body = new StringBuilder();
- for (Entry e : args.entrySet()) {
- if (body.length()>0) body.append('&');
- body.append(URLEncoder.encode(e.getKey(),"UTF-8"));
- body.append('=');
- body.append(URLEncoder.encode(e.getValue(),"UTF-8"));
- }
-
- OutputStreamWriter o = new OutputStreamWriter(uc.getOutputStream(), "UTF-8");
- o.write(body.toString());
- o.close();
-
+ StringBuilder body = new StringBuilder();
+ for (String e : args) {
+ if (body.length()>0) body.append('&');
+ body.append(e);
+ }
- try {
- InputStreamReader r = new InputStreamReader(uc.getInputStream(), "UTF-8");
- if (type==null) {
- String data = IOUtils.toString(r);
- return null;
+ OutputStreamWriter o = new OutputStreamWriter(uc.getOutputStream(), "UTF-8");
+ o.write(body.toString());
+ o.close();
+
+ 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) {
+ root.handleApiError(e,uc);
}
- 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 84ba0d6d8d..a327c59b85 100644
--- a/src/test/java/org/kohsuke/AppTest.java
+++ b/src/test/java/org/kohsuke/AppTest.java
@@ -1,25 +1,31 @@
package org.kohsuke;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import org.kohsuke.github.GHOrganization;
+import org.kohsuke.github.GHOrganization.Permission;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHTeam;
import org.kohsuke.github.GitHub;
import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
/**
* Unit test for simple App.
*/
public class AppTest extends TestCase {
+ public void testCredentialValid() throws IOException {
+ assertTrue(GitHub.connect().isCredentialValid());
+ assertFalse(GitHub.connect("totally","bogus").isCredentialValid());
+ }
+
public void testApp() throws IOException {
GitHub gitHub = GitHub.connect();
- GHOrganization labs = gitHub.getOrganization("HudsonLabs");
- GHTeam t = labs.getTeams().get("Core Developers");
+// testOrganization(gitHub);
+// testPostCommitHook(gitHub);
- t.add(labs.getRepository("xyz"));
+// tryTeamCreation(gitHub);
// t.add(gitHub.getMyself());
// System.out.println(t.getMembers());
@@ -35,4 +41,26 @@ public void testApp() throws IOException {
//
// System.out.println(hub.getUser("kohsuke").getRepository("hudson").getCollaborators());
}
+
+ private void tryTeamCreation(GitHub gitHub) throws IOException {
+ GHOrganization o = gitHub.getOrganization("HudsonLabs");
+ GHTeam t = o.createTeam("auto team", Permission.PUSH);
+ t.add(o.getRepository("auto-test"));
+ }
+
+ private void testPostCommitHook(GitHub gitHub) throws IOException {
+ GHRepository r = gitHub.getMyself().getRepository("foo");
+ Set hooks = r.getPostCommitHooks();
+ hooks.add(new URL("http://kohsuke.org/test"));
+ System.out.println(hooks);
+ hooks.remove(new URL("http://kohsuke.org/test"));
+ System.out.println(hooks);
+ }
+
+ private void testOrganization(GitHub gitHub) throws IOException {
+ GHOrganization labs = gitHub.getOrganization("HudsonLabs");
+ GHTeam t = labs.getTeams().get("Core Developers");
+
+ t.add(labs.getRepository("xyz"));
+ }
}