From 62f42300b8ba1b1af6ca0da024172df5fbe31bf2 Mon Sep 17 00:00:00 2001 From: Luke Granger-Brown Date: Sun, 14 Jun 2020 19:38:15 +0100 Subject: [PATCH] feat(gerrit): Add CL titles to title tags if accessing a CL or patchset. Fine, puck, you win. Change-Id: I47fe8ea6662132f5c337e1e73281dbeca19a414c Reviewed-on: https://cl.tvl.fyi/c/depot/+/321 Reviewed-by: tazjin --- third_party/gerrit/add_titles_to_cls.patch | 200 +++++++++++++++++++++ third_party/gerrit/default.nix | 1 + 2 files changed, 201 insertions(+) create mode 100644 third_party/gerrit/add_titles_to_cls.patch diff --git a/third_party/gerrit/add_titles_to_cls.patch b/third_party/gerrit/add_titles_to_cls.patch new file mode 100644 index 000000000..1a17e6dbb --- /dev/null +++ b/third_party/gerrit/add_titles_to_cls.patch @@ -0,0 +1,200 @@ +diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +index 41d2f83975..323567b4a4 100644 +--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java ++++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +@@ -42,6 +42,7 @@ import java.util.Arrays; + import java.util.Collections; + import java.util.HashMap; + import java.util.Map; ++import java.util.Optional; + import java.util.Set; + import java.util.function.Function; + import java.util.regex.Matcher; +@@ -110,7 +111,8 @@ public class IndexHtmlUtil { + String faviconPath, + Map urlParameterMap, + Function urlInScriptTagOrdainer, +- String requestedURL) ++ String requestedURL, ++ TitleComputer titleComputer) + throws URISyntaxException, RestApiException { + ImmutableMap.Builder data = ImmutableMap.builder(); + data.putAll( +@@ -121,7 +123,7 @@ public class IndexHtmlUtil { + urlParameterMap, + urlInScriptTagOrdainer, + requestedURL)) +- .putAll(dynamicTemplateData(gerritApi)); ++ .putAll(dynamicTemplateData(gerritApi, requestedURL, titleComputer)); + + Set enabledExperiments = experimentData(urlParameterMap); + if (!enabledExperiments.isEmpty()) { +@@ -131,7 +133,9 @@ public class IndexHtmlUtil { + } + + /** Returns dynamic parameters of {@code index.html}. */ +- public static ImmutableMap dynamicTemplateData(GerritApi gerritApi) ++ public static ImmutableMap dynamicTemplateData(GerritApi gerritApi, ++ String requestedURL, ++ TitleComputer titleComputer) + throws RestApiException { + ImmutableMap.Builder data = ImmutableMap.builder(); + Map initialData = new HashMap<>(); +@@ -159,6 +163,10 @@ public class IndexHtmlUtil { + } + + data.put("gerritInitialData", initialData); ++ ++ Optional title = titleComputer.computeTitle(requestedURL); ++ title.ifPresent(s -> data.put("title", s)); ++ + return data.build(); + } + +diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java +index 97d22701de..089ef4725f 100644 +--- a/java/com/google/gerrit/httpd/raw/IndexServlet.java ++++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java +@@ -44,12 +44,14 @@ public class IndexServlet extends HttpServlet { + private final GerritApi gerritApi; + private final SoySauce soySauce; + private final Function urlOrdainer; ++ private TitleComputer titleComputer; + + IndexServlet( + @Nullable String canonicalUrl, + @Nullable String cdnPath, + @Nullable String faviconPath, +- GerritApi gerritApi) { ++ GerritApi gerritApi, ++ TitleComputer titleComputer) { + this.canonicalUrl = canonicalUrl; + this.cdnPath = cdnPath; + this.faviconPath = faviconPath; +@@ -63,6 +65,7 @@ public class IndexServlet extends HttpServlet { + (s) -> + UnsafeSanitizedContentOrdainer.ordainAsSafe( + s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI); ++ this.titleComputer = titleComputer; + } + + @Override +@@ -74,7 +77,7 @@ public class IndexServlet extends HttpServlet { + // TODO(hiesel): Remove URL ordainer as parameter once Soy is consistent + ImmutableMap templateData = + IndexHtmlUtil.templateData( +- gerritApi, canonicalUrl, cdnPath, faviconPath, parameterMap, urlOrdainer, requestUrl); ++ gerritApi, canonicalUrl, cdnPath, faviconPath, parameterMap, urlOrdainer, requestUrl, titleComputer); + renderer = soySauce.renderTemplate("com.google.gerrit.httpd.raw.Index").setData(templateData); + } catch (URISyntaxException | RestApiException e) { + throw new IOException(e); +diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java +index 414a120194..e1b6fb082d 100644 +--- a/java/com/google/gerrit/httpd/raw/StaticModule.java ++++ b/java/com/google/gerrit/httpd/raw/StaticModule.java +@@ -220,11 +220,12 @@ public class StaticModule extends ServletModule { + HttpServlet getPolyGerritUiIndexServlet( + @CanonicalWebUrl @Nullable String canonicalUrl, + @GerritServerConfig Config cfg, +- GerritApi gerritApi) { ++ GerritApi gerritApi, ++ TitleComputer titleComputer) { + String cdnPath = + options.useDevCdn() ? options.devCdn() : cfg.getString("gerrit", null, "cdnPath"); + String faviconPath = cfg.getString("gerrit", null, "faviconPath"); +- return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi); ++ return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, titleComputer); + } + + @Provides +diff --git a/java/com/google/gerrit/httpd/raw/TitleComputer.java b/java/com/google/gerrit/httpd/raw/TitleComputer.java +new file mode 100644 +index 0000000000..efee24607c +--- /dev/null ++++ b/java/com/google/gerrit/httpd/raw/TitleComputer.java +@@ -0,0 +1,67 @@ ++package com.google.gerrit.httpd.raw; ++ ++import com.google.common.flogger.FluentLogger; ++import com.google.gerrit.entities.Change; ++import com.google.gerrit.extensions.restapi.ResourceConflictException; ++import com.google.gerrit.extensions.restapi.ResourceNotFoundException; ++import com.google.gerrit.server.change.ChangeResource; ++import com.google.gerrit.server.permissions.PermissionBackendException; ++import com.google.gerrit.server.restapi.change.ChangesCollection; ++import com.google.inject.Inject; ++import com.google.inject.Provider; ++import com.google.inject.Singleton; ++ ++import java.net.MalformedURLException; ++import java.net.URL; ++import java.util.Optional; ++import java.util.regex.Matcher; ++import java.util.regex.Pattern; ++ ++@Singleton ++public class TitleComputer { ++ private static final FluentLogger logger = FluentLogger.forEnclosingClass(); ++ ++ @Inject ++ public TitleComputer(Provider changes) { ++ this.changes = changes; ++ } ++ ++ public Optional computeTitle(String requestedURI) { ++ URL url = null; ++ try { ++ url = new URL(requestedURI); ++ } catch (MalformedURLException e) { ++ logger.atWarning().log("Failed to turn %s into a URL.", requestedURI); ++ return Optional.empty(); ++ } ++ ++ // Try to turn this into a change. ++ Optional changeId = tryExtractChange(url.getPath()); ++ if (changeId.isPresent()) { ++ return titleFromChangeId(changeId.get()); ++ } ++ ++ return Optional.empty(); ++ } ++ ++ private static final Pattern extractChangeIdRegex = Pattern.compile("^/(?:c/.*/\\+/)?(?[0-9]+)(?:/[0-9]+)?$"); ++ private final Provider changes; ++ ++ private Optional tryExtractChange(String path) { ++ Matcher m = extractChangeIdRegex.matcher(path); ++ if (!m.matches()) { ++ return Optional.empty(); ++ } ++ return Change.Id.tryParse(m.group("changeId")); ++ } ++ ++ private Optional titleFromChangeId(Change.Id changeId) { ++ ChangesCollection changesCollection = changes.get(); ++ try { ++ ChangeResource changeResource = changesCollection.parse(changeId); ++ return Optional.of(changeResource.getChange().getSubject()); ++ } catch (ResourceConflictException | ResourceNotFoundException | PermissionBackendException e) { ++ return Optional.empty(); ++ } ++ } ++} +diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy +index d162714399..0ba228ad00 100644 +--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy ++++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy +@@ -33,10 +33,12 @@ + {@param? preloadChangePage: ?} + {@param? preloadDiffPage: ?} + {@param? userIsAuthenticated: ?} ++ {@param? title: ?} + {\n} + {\n} + {\n} +- {\n} ++ {if $title}{$title} · Gerrit Code Review{\n}{/if} ++ {\n} + {\n} + {\n} + diff --git a/third_party/gerrit/default.nix b/third_party/gerrit/default.nix index 98373582b..d5350d3ed 100644 --- a/third_party/gerrit/default.nix +++ b/third_party/gerrit/default.nix @@ -43,6 +43,7 @@ pkgs.buildBazelPackage { ./use_detzip.patch ./syntax_highlight_nix.patch ./syntax_highlight_rules_pl.patch + ./add_titles_to_cls.patch ]; bazelTarget = "release";