diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 8570a09bb1..1b84d25ed5 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -641,6 +641,35 @@ public GHRef getRef(String refName) throws IOException { return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root); } /** + * Retrive a tree of the given type for the current GitHub repository. + * + * @param sha - sha number or branch name ex: "master" + * @return refs matching the request type + * @throws IOException + * on failure communicating with GitHub, potentially due to an + * invalid tree type being requested + */ + public GHTree getTree(String sha) throws IOException { + String url = String.format("/repos/%s/%s/git/trees/%s", owner.login, name, sha); + return root.retrieve().to(url, GHTree.class).wrap(root); + } + + /** + * Retrieves the tree for the current GitHub repository, recursively as described in here: + * https://developer.github.com/v3/git/trees/#get-a-tree-recursively + * + * @param sha - sha number or branch name ex: "master" + * @param recursive use 1 + * @throws IOException + * on failure communicating with GitHub, potentially due to an + * invalid tree type being requested + */ + public GHTree getTreeRecursive(String sha, int recursive) throws IOException { + String url = String.format("/repos/%s/%s/git/trees/%s?recursive=%d", owner.login, name, sha, recursive); + return root.retrieve().to(url, GHTree.class).wrap(root); + } + + /** * Gets a commit object in this repository. */ public GHCommit getCommit(String sha1) throws IOException { diff --git a/src/main/java/org/kohsuke/github/GHTree.java b/src/main/java/org/kohsuke/github/GHTree.java new file mode 100644 index 0000000000..f520c14cd5 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHTree.java @@ -0,0 +1,114 @@ +package org.kohsuke.github; + +import java.net.URL; + +/** + * Provides information for Git Trees + * https://developer.github.com/v3/git/trees/ + * + * @author Daniel Teixeira - https://github.com/ddtxra + */ +public class GHTree { + /* package almost final */GitHub root; + + private boolean truncated; + private String sha, url; + private GHTreeEntry[] tree; + + /** + * The SHA for this trees + */ + public String getSha() { + return sha; + } + + /** + * Return an array of entries of the trees + * @return + */ + public GHTreeEntry[] getTree() { + return tree; + } + + /** + * Returns true if the number of items in the tree array exceeded the GitHub maximum limit. + * @return true true if the number of items in the tree array exceeded the GitHub maximum limit otherwise false. + */ + public boolean isTruncated() { + return truncated; + } + + /** + * The API URL of this tag, such as + * "url": "https://api.github.com/repos/octocat/Hello-World/trees/fc6274d15fa3ae2ab983129fb037999f264ba9a7", + */ + public URL getUrl() { + return GitHub.parseURL(url); + } + + /* package */GHTree wrap(GitHub root) { + this.root = root; + return this; + } + + public static class GHTreeEntry { + private String path, mode, type, sha, url; + private long size; + + /** + * Get the path such as + * "subdir/file.txt" + * + * @return the path + */ + public String getPath() { + return path; + } + + /** + * Get mode such as + * 100644 + * + * @return the mode + */ + public String getMode() { + return mode; + } + + /** + * Gets the size of the file, such as + * 132 + * @return The size of the path or 0 if it is a directory + */ + public long getSize() { + return size; + } + + /** + * Gets the type such as: + * "blob" + * + * @return The type + */ + public String getType() { + return type; + } + + + /** + * SHA1 of this object. + */ + public String getSha() { + return sha; + } + + /** + * API URL to this Git data, such as + * https://api.github.com/repos/jenkinsci + * /jenkins/git/commits/b72322675eb0114363a9a86e9ad5a170d1d07ac0 + */ + public URL getUrl() { + return GitHub.parseURL(url); + } + } +} diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index a13f5423f5..4666f2920d 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -3,10 +3,12 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; + import org.junit.Assume; import org.junit.Test; import org.kohsuke.github.GHCommit.File; import org.kohsuke.github.GHOrganization.Permission; +import org.kohsuke.github.GHTree.GHTreeEntry; import java.io.IOException; import java.net.URL; @@ -665,6 +667,33 @@ public void testReadme() throws IOException { assertEquals(readme.getName(),"README.md"); assertEquals(readme.getContent(),"This is a markdown readme.\n"); } + + + @Test + public void testTrees() throws IOException { + GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTree("master"); + boolean foundReadme = false; + for(GHTreeEntry e : masterTree.getTree()){ + if("readme".equalsIgnoreCase(e.getPath().replaceAll(".md", ""))){ + foundReadme = true; + break; + } + } + assertTrue(foundReadme); + } + + @Test + public void testTreesRecursive() throws IOException { + GHTree masterTree = gitHub.getRepository("kohsuke/github-api").getTreeRecursive("master", 1); + boolean foundThisFile = false; + for(GHTreeEntry e : masterTree.getTree()){ + if(e.getPath().endsWith(AppTest.class.getSimpleName() + ".java")){ + foundThisFile = true; + break; + } + } + assertTrue(foundThisFile); + } @Test public void testRepoLabel() throws IOException {