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}