Add link to file view for creating a Gerrit change/edit
Bug: issue 40011246
Change-Id: I726260840191f50eda9e1235bd2abd40eed11af8
diff --git a/java/com/google/gitiles/BlobSoyData.java b/java/com/google/gitiles/BlobSoyData.java
index a6879ae..c90b434 100644
--- a/java/com/google/gitiles/BlobSoyData.java
+++ b/java/com/google/gitiles/BlobSoyData.java
@@ -26,6 +26,7 @@
import com.google.template.soy.data.SoyListData;
import com.google.template.soy.data.SoyMapData;
import java.io.IOException;
+import java.net.URI;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
@@ -79,6 +80,11 @@
public Map<String, Object> toSoyData(String path, ObjectId blobId)
throws MissingObjectException, IOException {
+ return toSoyData(path, blobId, null);
+ }
+
+ public Map<String, Object> toSoyData(String path, ObjectId blobId, @Nullable URI editUrl)
+ throws MissingObjectException, IOException {
Map<String, Object> data = Maps.newHashMapWithExpectedSize(4);
data.put("sha", ObjectId.toString(blobId));
@@ -119,6 +125,9 @@
data.put("fileUrl", GitilesView.path().copyFrom(view).toUrl());
data.put("logUrl", GitilesView.log().copyFrom(view).toUrl());
data.put("blameUrl", GitilesView.blame().copyFrom(view).toUrl());
+ if (editUrl != null) {
+ data.put("editUrl", editUrl.toString());
+ }
if (imageBlob != null) {
data.put("imgBlob", imageBlob);
}
diff --git a/java/com/google/gitiles/PathServlet.java b/java/com/google/gitiles/PathServlet.java
index 87d2680..fc0af05 100644
--- a/java/com/google/gitiles/PathServlet.java
+++ b/java/com/google/gitiles/PathServlet.java
@@ -15,6 +15,7 @@
package com.google.gitiles;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.gitiles.GitilesUrls.escapeName;
import static com.google.gitiles.TreeSoyData.resolveTargetUrl;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
@@ -31,6 +32,8 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@@ -49,6 +52,8 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
@@ -61,11 +66,14 @@
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;
/** Serves an HTML page with detailed information about a path within a tree. */
// TODO(dborowitz): Handle non-UTF-8 names.
public class PathServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
+ private static final Logger log = LoggerFactory.getLogger(PathServlet.class);
static final String MODE_HEADER = "X-Gitiles-Path-Mode";
static final String TYPE_HEADER = "X-Gitiles-Object-Type";
@@ -532,10 +540,34 @@
return p.eof() ? p : null;
}
+ private @Nullable URI createEditUrl(HttpServletRequest req, GitilesView view)
+ throws IOException {
+ String baseGerritUrl = this.urls.getBaseGerritUrl(req);
+ if (baseGerritUrl == null) {
+ return null;
+ }
+ String commitish = view.getRevision().getName();
+ if (commitish == null || !commitish.startsWith("refs/heads/")) {
+ return null;
+ }
+ try {
+ URI editUrl = new URI(baseGerritUrl);
+ String path =
+ String.format("/admin/repos/edit/repo/%s/branch/%s/file/%s",
+ view.getRepositoryName(),
+ commitish,
+ view.getPathPart());
+ return editUrl.resolve(escapeName(path));
+ } catch (URISyntaxException use) {
+ log.warn("Malformed Edit URL", use);
+ }
+ return null;
+ }
+
private void showFile(HttpServletRequest req, HttpServletResponse res, WalkResult wr)
throws IOException {
GitilesView view = ViewFilter.getView(req);
- Map<String, ?> data = new BlobSoyData(wr.getObjectReader(), view).toSoyData(wr.path, wr.id);
+ Map<String, ?> data = new BlobSoyData(wr.getObjectReader(), view).toSoyData(wr.path, wr.id, createEditUrl(req, view));
// TODO(sop): Allow caching files by SHA-1 when no S cookie is sent.
renderHtml(
req,
diff --git a/javatests/com/google/gitiles/PathServletTest.java b/javatests/com/google/gitiles/PathServletTest.java
index 5002948..7531242 100644
--- a/javatests/com/google/gitiles/PathServletTest.java
+++ b/javatests/com/google/gitiles/PathServletTest.java
@@ -103,6 +103,18 @@
}
@Test
+ public void editUrl() throws Exception {
+ repo.branch("master").commit().add("editFoo", "Content").create();
+ repo.reset("refs/heads/master");
+
+ Map<String, ?> data = buildData("/repo/+/refs/heads/master/editFoo");
+
+ String editUrl = (String) getBlobData(data).get("editUrl");
+ String testUrl = "http://test-host-review/admin/repos/edit/repo/repo/branch/refs/heads/master/file/editFoo";
+ assertThat(editUrl).isEqualTo(testUrl);
+ }
+
+ @Test
public void fileWithMaxLines() throws Exception {
int MAX_LINE_COUNT = 50000;
StringBuilder contentBuilder = new StringBuilder();
diff --git a/resources/com/google/gitiles/templates/ObjectDetail.soy b/resources/com/google/gitiles/templates/ObjectDetail.soy
index 1dd3a40..f7c0b0c 100644
--- a/resources/com/google/gitiles/templates/ObjectDetail.soy
+++ b/resources/com/google/gitiles/templates/ObjectDetail.soy
@@ -242,12 +242,14 @@
{@param? logUrl: ?} /** optional URL to a log for this file. */
{@param? blameUrl: ?} /** optional URL to a blame for this file. */
{@param? docUrl: ?} /** optional URL to view rendered file. */
+ {@param? editUrl: ?} /** optional URL to create a change in Gerrit. */
<div class="u-sha1 u-monospace BlobSha1">
{msg desc="SHA-1 for the file's blob"}blob: {$sha}{/msg}
{if $fileUrl}{sp}[<a href="{$fileUrl}">{msg desc="detail view of a file"}file{/msg}</a>]{/if}
{if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a file"}log{/msg}</a>]{/if}
{if $blameUrl}{sp}[<a href="{$blameUrl}">{msg desc="blame for a file"}blame{/msg}</a>]{/if}
{if $docUrl}{sp}[<a href="{$docUrl}">{msg desc="view rendered file"}view{/msg}</a>]{/if}
+ {if $editUrl}{sp}[<a href="{$editUrl}">{msg desc="edit file in Gerrit"}edit{/msg}</a>]{/if}
</div>
{/template}