Merge "Add support for "long" mode in JSON queries for trees."
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
index 4837671..d570dbc 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
@@ -23,6 +23,7 @@
import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
@@ -53,6 +54,7 @@
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.QuotedString;
import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -239,6 +241,11 @@
GitilesView view = ViewFilter.getView(req);
Repository repo = ServletUtils.getRepository(req);
+ String longStr = req.getParameter("long");
+ boolean includeSizes =
+ (longStr != null)
+ && (longStr.isEmpty() || Boolean.TRUE.equals(StringUtils.toBooleanOrNull(longStr)));
+
try (RevWalk rw = new RevWalk(repo);
WalkResult wr = WalkResult.forPath(rw, view)) {
if (wr == null) {
@@ -247,7 +254,11 @@
}
switch (wr.type) {
case TREE:
- renderJson(req, res, TreeJsonData.toJsonData(wr.id, wr.tw), TreeJsonData.Tree.class);
+ renderJson(
+ req,
+ res,
+ TreeJsonData.toJsonData(wr.id, wr.tw, includeSizes),
+ TreeJsonData.Tree.class);
break;
default:
res.setStatus(SC_NOT_FOUND);
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java b/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
index b525453..6fb4a6c 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
@@ -14,11 +14,17 @@
package com.google.gitiles;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.collect.Lists;
+import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.treewalk.TreeWalk;
import java.io.IOException;
@@ -35,9 +41,12 @@
String type;
String id;
String name;
+
+ @Nullable String target;
+ @Nullable Long size;
}
- static Tree toJsonData(ObjectId id, TreeWalk tw) throws IOException {
+ static Tree toJsonData(ObjectId id, TreeWalk tw, boolean includeSizes) throws IOException {
Tree tree = new Tree();
tree.id = id.name();
tree.entries = Lists.newArrayList();
@@ -48,6 +57,15 @@
e.type = Constants.typeString(mode.getObjectType());
e.id = tw.getObjectId(0).name();
e.name = tw.getNameString();
+
+ if (includeSizes) {
+ if ((mode.getBits() & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) {
+ e.size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB);
+ } else if ((mode.getBits() & FileMode.TYPE_MASK) == FileMode.TYPE_SYMLINK) {
+ e.target =
+ new String(tw.getObjectReader().open(tw.getObjectId(0)).getCachedBytes(), UTF_8);
+ }
+ }
tree.entries.add(e);
}
return tree;
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java b/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
index 5842e07..1eac476 100644
--- a/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
+++ b/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
@@ -224,6 +224,50 @@
}
@Test
+ public void treeJsonSizes() throws Exception {
+ RevCommit c = repo.parseBody(repo.branch("master").commit().add("baz", "01234567").create());
+
+ Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
+
+ assertThat(tree.id).isEqualTo(c.getTree().name());
+ assertThat(tree.entries).hasSize(1);
+ assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
+ assertThat(tree.entries.get(0).type).isEqualTo("blob");
+ assertThat(tree.entries.get(0).name).isEqualTo("baz");
+ assertThat(tree.entries.get(0).size).isEqualTo(8);
+ }
+
+ @Test
+ public void treeJsonLinkTarget() throws Exception {
+ final ObjectId targetID = repo.blob("target");
+ RevCommit c =
+ repo.parseBody(
+ repo.branch("master")
+ .commit()
+ .edit(
+ new PathEdit("link") {
+ @Override
+ public void apply(DirCacheEntry ent) {
+ ent.setFileMode(FileMode.SYMLINK);
+ ent.setObjectId(targetID);
+ }
+ })
+ .create());
+
+ Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
+
+ assertThat(tree.id).isEqualTo(c.getTree().name());
+ assertThat(tree.entries).hasSize(1);
+
+ TreeJsonData.Entry e = tree.entries.get(0);
+ assertThat(e.mode).isEqualTo(0120000);
+ assertThat(e.type).isEqualTo("blob");
+ assertThat(e.name).isEqualTo("link");
+ assertThat(e.id).isEqualTo(targetID.name());
+ assertThat(e.target).isEqualTo("target");
+ }
+
+ @Test
public void treeJson() throws Exception {
RevCommit c =
repo.parseBody(