diff options
Diffstat (limited to 'third_party/gerrit')
-rw-r--r-- | third_party/gerrit/0001-Use-detzip-in-download_bower.py.patch | 25 | ||||
-rw-r--r-- | third_party/gerrit/0002-Syntax-highlight-nix.patch | 24 | ||||
-rw-r--r-- | third_party/gerrit/0003-Syntax-highlight-rules.pl.patch | 46 | ||||
-rw-r--r-- | third_party/gerrit/0004-Add-titles-to-CLs-over-HTTP.patch | 217 | ||||
-rw-r--r-- | third_party/gerrit/0005-When-using-local-fonts-always-assume-Gerrit-is-mount.patch | 26 | ||||
-rw-r--r-- | third_party/gerrit/0006-Always-use-Google-Fonts.patch | 28 | ||||
-rw-r--r-- | third_party/gerrit/default.nix | 150 | ||||
-rw-r--r-- | third_party/gerrit/detzip.go | 97 |
8 files changed, 613 insertions, 0 deletions
diff --git a/third_party/gerrit/0001-Use-detzip-in-download_bower.py.patch b/third_party/gerrit/0001-Use-detzip-in-download_bower.py.patch new file mode 100644 index 000000000000..7d197795b725 --- /dev/null +++ b/third_party/gerrit/0001-Use-detzip-in-download_bower.py.patch @@ -0,0 +1,25 @@ +From 621cadcc1dd71e9397c21cf8cf0f1aae4f6f7057 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Thu, 2 Jul 2020 23:02:09 +0100 +Subject: [PATCH 1/7] Use detzip in download_bower.py + +--- + tools/js/download_bower.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/js/download_bower.py b/tools/js/download_bower.py +index d541b565a9..ffdae60f95 100755 +--- a/tools/js/download_bower.py ++++ b/tools/js/download_bower.py +@@ -110,7 +110,7 @@ def main(): + args.b, '--quiet', 'install', '%s#%s' % (args.p, args.v))) + bc = os.path.join(cwd, 'bower_components') + subprocess.check_call( +- ['zip', '-q', '--exclude', '.bower.json', '-r', cached, args.n], ++ ['detzip', '--exclude', '.bower.json', cached, args.n], + cwd=bc) + + if args.s: +-- +2.32.0 + diff --git a/third_party/gerrit/0002-Syntax-highlight-nix.patch b/third_party/gerrit/0002-Syntax-highlight-nix.patch new file mode 100644 index 000000000000..256da0a3c930 --- /dev/null +++ b/third_party/gerrit/0002-Syntax-highlight-nix.patch @@ -0,0 +1,24 @@ +From 924647c354576ade0dc46fdf30596967f58bb4c6 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Thu, 2 Jul 2020 23:02:32 +0100 +Subject: [PATCH 2/7] Syntax highlight nix + +--- + .../app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts +index 081d28d749..2762ccc625 100644 +--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts ++++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts +@@ -99,6 +99,7 @@ const LANGUAGE_MAP = new Map<string, string>([ + ['text/x-vhdl', 'vhdl'], + ['text/x-yaml', 'yaml'], + ['text/vbscript', 'vbscript'], ++ ['application/x-mix-transfer', 'nix'], + ]); + const ASYNC_DELAY = 10; + +-- +2.32.0 + diff --git a/third_party/gerrit/0003-Syntax-highlight-rules.pl.patch b/third_party/gerrit/0003-Syntax-highlight-rules.pl.patch new file mode 100644 index 000000000000..02bb3397eabb --- /dev/null +++ b/third_party/gerrit/0003-Syntax-highlight-rules.pl.patch @@ -0,0 +1,46 @@ +From be348f64eda257ae0af1f89552548d3e8eca3688 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Thu, 2 Jul 2020 23:02:43 +0100 +Subject: [PATCH 3/7] Syntax highlight rules.pl + +--- + .../diff/gr-syntax-layer/gr-syntax-layer.ts | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts +index 2762ccc625..598e14589f 100644 +--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts ++++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.ts +@@ -103,6 +103,10 @@ const LANGUAGE_MAP = new Map<string, string>([ + ]); + const ASYNC_DELAY = 10; + ++const FILENAME_OVERRIDES = new Map<string, string>([ ++ ['rules.pl', 'prolog'], ++]); ++ + const CLASS_SAFELIST = new Set<string>([ + 'gr-diff gr-syntax gr-syntax-attr', + 'gr-diff gr-syntax gr-syntax-attribute', +@@ -241,10 +245,17 @@ export class GrSyntaxLayer implements DiffLayer { + } + } + ++ _basename(filename: string): string { ++ const pieces = filename.split(/\//); ++ return pieces[pieces.length-1]; ++ } ++ + _getLanguage(metaInfo: DiffFileMetaInfo) { + // The Gerrit API provides only content-type, but for other users of + // gr-diff it may be more convenient to specify the language directly. +- return metaInfo.language ?? LANGUAGE_MAP.get(metaInfo.content_type); ++ return metaInfo.language ?? ++ FILENAME_OVERRIDES.get(this._basename(metaInfo.name)) ?? ++ LANGUAGE_MAP.get(metaInfo.content_type); + } + + /** +-- +2.32.0 + diff --git a/third_party/gerrit/0004-Add-titles-to-CLs-over-HTTP.patch b/third_party/gerrit/0004-Add-titles-to-CLs-over-HTTP.patch new file mode 100644 index 000000000000..8e78e5f535e3 --- /dev/null +++ b/third_party/gerrit/0004-Add-titles-to-CLs-over-HTTP.patch @@ -0,0 +1,217 @@ +From 32bf13d8316f93828d2ff47ccfca38d4e7a634b1 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Thu, 2 Jul 2020 23:03:02 +0100 +Subject: [PATCH 4/7] Add titles to CLs over HTTP + +--- + .../gerrit/httpd/raw/IndexHtmlUtil.java | 13 +++- + .../google/gerrit/httpd/raw/IndexServlet.java | 8 ++- + .../google/gerrit/httpd/raw/StaticModule.java | 6 +- + .../gerrit/httpd/raw/TitleComputer.java | 67 +++++++++++++++++++ + .../gerrit/httpd/raw/PolyGerritIndexHtml.soy | 4 +- + 5 files changed, 90 insertions(+), 8 deletions(-) + create mode 100644 java/com/google/gerrit/httpd/raw/TitleComputer.java + +diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +index 8d52f5ad50..a9cfceb3b6 100644 +--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java ++++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +@@ -39,6 +39,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; + +@@ -60,13 +61,14 @@ public class IndexHtmlUtil { + String faviconPath, + Map<String, String[]> urlParameterMap, + Function<String, SanitizedContent> urlInScriptTagOrdainer, +- String requestedURL) ++ String requestedURL, ++ TitleComputer titleComputer) + throws URISyntaxException, RestApiException { + ImmutableMap.Builder<String, Object> data = ImmutableMap.builder(); + data.putAll( + staticTemplateData( + canonicalURL, cdnPath, faviconPath, urlParameterMap, urlInScriptTagOrdainer)) +- .putAll(dynamicTemplateData(gerritApi, requestedURL)); ++ .putAll(dynamicTemplateData(gerritApi, requestedURL, titleComputer)); + Set<String> enabledExperiments = experimentFeatures.getEnabledExperimentFeatures(); + + if (!enabledExperiments.isEmpty()) { +@@ -77,7 +79,9 @@ public class IndexHtmlUtil { + + /** Returns dynamic parameters of {@code index.html}. */ + public static ImmutableMap<String, Object> dynamicTemplateData( +- GerritApi gerritApi, String requestedURL) throws RestApiException, URISyntaxException { ++ GerritApi gerritApi, ++ String requestedURL, ++ TitleComputer titleComputer) throws RestApiException, URISyntaxException { + ImmutableMap.Builder<String, Object> data = ImmutableMap.builder(); + Map<String, SanitizedContent> initialData = new HashMap<>(); + Server serverApi = gerritApi.config().server(); +@@ -128,6 +132,9 @@ public class IndexHtmlUtil { + // Don't render data + } + ++ Optional<String> title = titleComputer.computeTitle(requestedURL); ++ title.ifPresent(s -> data.put("title", s)); ++ + data.put("gerritInitialData", initialData); + return data.build(); + } +diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java +index 3f2c2028ae..7861c007df 100644 +--- a/java/com/google/gerrit/httpd/raw/IndexServlet.java ++++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java +@@ -46,13 +46,15 @@ public class IndexServlet extends HttpServlet { + private final ExperimentFeatures experimentFeatures; + private final SoySauce soySauce; + private final Function<String, SanitizedContent> urlOrdainer; ++ private TitleComputer titleComputer; + + IndexServlet( + @Nullable String canonicalUrl, + @Nullable String cdnPath, + @Nullable String faviconPath, + GerritApi gerritApi, +- ExperimentFeatures experimentFeatures) { ++ ExperimentFeatures experimentFeatures, ++ TitleComputer titleComputer) { + this.canonicalUrl = canonicalUrl; + this.cdnPath = cdnPath; + this.faviconPath = faviconPath; +@@ -67,6 +69,7 @@ public class IndexServlet extends HttpServlet { + (s) -> + UnsafeSanitizedContentOrdainer.ordainAsSafe( + s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI); ++ this.titleComputer = titleComputer; + } + + @Override +@@ -85,7 +88,8 @@ public class IndexServlet extends HttpServlet { + faviconPath, + parameterMap, + urlOrdainer, +- requestUrl); ++ 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 bb1eb92525..6b20c504d2 100644 +--- a/java/com/google/gerrit/httpd/raw/StaticModule.java ++++ b/java/com/google/gerrit/httpd/raw/StaticModule.java +@@ -224,11 +224,13 @@ public class StaticModule extends ServletModule { + @CanonicalWebUrl @Nullable String canonicalUrl, + @GerritServerConfig Config cfg, + GerritApi gerritApi, +- ExperimentFeatures experimentFeatures) { ++ ExperimentFeatures experimentFeatures, ++ 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, experimentFeatures); ++ return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, ++ experimentFeatures, 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..8fd2053ad0 +--- /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<ChangesCollection> changes) { ++ this.changes = changes; ++ } ++ ++ public Optional<String> 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<Change.Id> changeId = tryExtractChange(url.getPath()); ++ if (changeId.isPresent()) { ++ return titleFromChangeId(changeId.get()); ++ } ++ ++ return Optional.empty(); ++ } ++ ++ private static final Pattern extractChangeIdRegex = Pattern.compile("^/(?:c/.*/\\+/)?(?<changeId>[0-9]+)(?:/[0-9]+)?(?:/.*)?$"); ++ private final Provider<ChangesCollection> changes; ++ ++ private Optional<Change.Id> tryExtractChange(String path) { ++ Matcher m = extractChangeIdRegex.matcher(path); ++ if (!m.matches()) { ++ return Optional.empty(); ++ } ++ return Change.Id.tryParse(m.group("changeId")); ++ } ++ ++ private Optional<String> 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 11717fb8a4..1ae9046360 100644 +--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy ++++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy +@@ -33,10 +33,12 @@ + {@param? defaultDashboardHex: ?} + {@param? dashboardQuery: ?} + {@param? userIsAuthenticated: ?} ++ {@param? title: ?} + <!DOCTYPE html>{\n} + <html lang="en">{\n} + <meta charset="utf-8">{\n} +- <meta name="description" content="Gerrit Code Review">{\n} ++ {if $title}<title>{$title} · Gerrit Code Review</title>{\n}{/if} ++ <meta name="description" content="{if $title}{$title} · {/if}Gerrit Code Review">{\n} + <meta name="referrer" content="never">{\n} + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n} + +-- +2.32.0 + diff --git a/third_party/gerrit/0005-When-using-local-fonts-always-assume-Gerrit-is-mount.patch b/third_party/gerrit/0005-When-using-local-fonts-always-assume-Gerrit-is-mount.patch new file mode 100644 index 000000000000..b664ea0ea6b2 --- /dev/null +++ b/third_party/gerrit/0005-When-using-local-fonts-always-assume-Gerrit-is-mount.patch @@ -0,0 +1,26 @@ +From bd7db44cabb6de64f03adbaf5e24c73e022a8932 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Sat, 11 Jul 2020 00:45:57 +0000 +Subject: [PATCH 5/7] When using local fonts, always assume Gerrit is mounted + at the root. + +--- + polygerrit-ui/app/rollup.config.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/polygerrit-ui/app/rollup.config.js b/polygerrit-ui/app/rollup.config.js +index d93b5eab39..c862c9bbae 100644 +--- a/polygerrit-ui/app/rollup.config.js ++++ b/polygerrit-ui/app/rollup.config.js +@@ -50,7 +50,7 @@ const importLocalFontMetaUrlResolver = function() { + name: 'import-meta-url-resolver', + resolveImportMeta: function (property, data) { + if(property === 'url' && data.moduleId.endsWith('/@polymer/font-roboto-local/roboto.js')) { +- return 'new URL("..", document.baseURI).href'; ++ return 'new URL("/", document.baseURI).href'; + } + return null; + } +-- +2.32.0 + diff --git a/third_party/gerrit/0006-Always-use-Google-Fonts.patch b/third_party/gerrit/0006-Always-use-Google-Fonts.patch new file mode 100644 index 000000000000..5b817d0b55a3 --- /dev/null +++ b/third_party/gerrit/0006-Always-use-Google-Fonts.patch @@ -0,0 +1,28 @@ +From d71f51afe12a280b92831070a583b15c8b6bc2f4 Mon Sep 17 00:00:00 2001 +From: Luke Granger-Brown <git@lukegb.com> +Date: Sat, 11 Jul 2020 00:46:13 +0000 +Subject: [PATCH 6/7] Always use Google Fonts. + +We're not a corporate, and we're not behind the GFW. Always use Google Fonts, +because even though we no longer get the caching benefits (boo, browsers), +it is still a better geographically-distributed CDN. +--- + java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +index a9cfceb3b6..9c287c6e45 100644 +--- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java ++++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java +@@ -184,7 +184,7 @@ public class IndexHtmlUtil { + if (urlParameterMap.containsKey("ce")) { + data.put("polyfillCE", "true"); + } +- if (urlParameterMap.containsKey("gf")) { ++ if (/* urlParameterMap.containsKey("gf") || */ true) { + data.put("useGoogleFonts", "true"); + } + +-- +2.32.0 + diff --git a/third_party/gerrit/default.nix b/third_party/gerrit/default.nix new file mode 100644 index 000000000000..f886a0426d52 --- /dev/null +++ b/third_party/gerrit/default.nix @@ -0,0 +1,150 @@ +{ depot, pkgs, ... }: + +let + detzip = depot.nix.buildGo.program { + name = "detzip"; + srcs = [ ./detzip.go ]; + }; + bazelRunScript = pkgs.writeShellScriptBin "bazel-run" '' + yarn config set cache-folder "$bazelOut/external/yarn_cache" + export HOME="$bazelOut/external/home" + mkdir -p "$bazelOut/external/home" + exec /bin/bazel "$@" + ''; + bazelTop = pkgs.buildFHSUserEnv { + name = "bazel"; + targetPkgs = pkgs: [ + (pkgs.bazel.override { enableNixHacks = true; }) + detzip + pkgs.jdk11_headless + pkgs.zlib + pkgs.python + pkgs.curl + pkgs.nodejs + pkgs.yarn + pkgs.git + bazelRunScript + ]; + runScript = "/bin/bazel-run"; + }; + bazel = bazelTop // { override = x: bazelTop; }; + version = "3.4.0"; +in +pkgs.lib.makeOverridable pkgs.buildBazelPackage { + pname = "gerrit"; + inherit version; + + src = pkgs.fetchgit { + url = "https://gerrit.googlesource.com/gerrit"; + rev = "471c1c15a7bc294d10e246df43812942b5ac8a13"; + branchName = "v${version}"; + sha256 = "sha256:0ayj0bcsxjln8qydkj9j7yiqibmjgd3bcpqvgsdzdx072wzx01c0"; + fetchSubmodules = true; + }; + + patches = [ + ./0001-Use-detzip-in-download_bower.py.patch + ./0002-Syntax-highlight-nix.patch + ./0003-Syntax-highlight-rules.pl.patch + ./0004-Add-titles-to-CLs-over-HTTP.patch + ./0005-When-using-local-fonts-always-assume-Gerrit-is-mount.patch + ./0006-Always-use-Google-Fonts.patch + ]; + + bazelTarget = "release api-skip-javadoc"; + inherit bazel; + + bazelFlags = [ + "--repository_cache=" + "--disk_cache=" + ]; + removeRulesCC = false; + fetchConfigured = true; + + fetchAttrs = { + sha256 = "sha256:16a1lbz40bc7217ldwf7x8yzlzxc714h965ldjnmfbvi3jq3hk6y"; + preBuild = '' + rm .bazelversion + ''; + + installPhase = '' + runHook preInstall + + # Remove all built in external workspaces, Bazel will recreate them when building + rm -rf $bazelOut/external/{bazel_tools,\@bazel_tools.marker} + rm -rf $bazelOut/external/{embedded_jdk,\@embedded_jdk.marker} + rm -rf $bazelOut/external/{local_config_cc,\@local_config_cc.marker} + rm -rf $bazelOut/external/{local_*,\@local_*.marker} + + # Clear markers + find $bazelOut/external -name '@*\.marker' -exec sh -c 'echo > {}' \; + + # Remove all vcs files + rm -rf $(find $bazelOut/external -type d -name .git) + rm -rf $(find $bazelOut/external -type d -name .svn) + rm -rf $(find $bazelOut/external -type d -name .hg) + + # Removing top-level symlinks along with their markers. + # This is needed because they sometimes point to temporary paths (?). + # For example, in Tensorflow-gpu build: + # platforms -> NIX_BUILD_TOP/tmp/install/35282f5123611afa742331368e9ae529/_embedded_binaries/platforms + find $bazelOut/external -maxdepth 1 -type l | while read symlink; do + name="$(basename "$symlink")" + rm -rf "$symlink" "$bazelOut/external/@$name.marker" + done + + # Patching symlinks to remove build directory reference + find $bazelOut/external -type l | while read symlink; do + new_target="$(readlink "$symlink" | sed "s,$NIX_BUILD_TOP,NIX_BUILD_TOP,")" + rm "$symlink" + ln -sf "$new_target" "$symlink" + done + + echo '${bazel.name}' > $bazelOut/external/.nix-bazel-version + + # Gerrit fixups: + # Remove polymer-bridges and ba-linkify, they're in-repo + rm -rf $bazelOut/external/yarn_cache/v6/npm-polymer-bridges-* + rm -rf $bazelOut/external/yarn_cache/v6/npm-ba-linkify-* + # Normalize permissions on .yarn-{tarball,metadata} files + find $bazelOut/external/yarn_cache \( -name .yarn-tarball.tgz -or -name .yarn-metadata.json \) -exec chmod 644 {} + + + (cd $bazelOut/ && tar czf $out --sort=name --mtime='@1' --owner=0 --group=0 --numeric-owner external/) + + runHook postInstall + ''; + }; + + buildAttrs = { + preConfigure = '' + rm .bazelversion + ''; + installPhase = '' + mkdir -p "$out"/webapps/ "$out"/share/api/ + cp bazel-bin/release.war "$out"/webapps/gerrit-${version}.war + unzip bazel-bin/api-skip-javadoc.zip -d "$out"/share/api + ''; + + nativeBuildInputs = with pkgs; [ + unzip + ]; + }; + + passthru = { + # A list of plugins that are part of the gerrit.war file. + # Use `java -jar gerrit.war ls | grep -Po '(?<=plugins/)[^.]+' | sed -e 's,^,",' -e 's,$,",' | sort` to generate that list. + plugins = [ + "codemirror-editor" + "commit-message-length-validator" + "delete-project" + "download-commands" + "gitiles" + "hooks" + "plugin-manager" + "replication" + "reviewnotes" + "singleusergroup" + "webhooks" + ]; + }; +} diff --git a/third_party/gerrit/detzip.go b/third_party/gerrit/detzip.go new file mode 100644 index 000000000000..511c18ecfe17 --- /dev/null +++ b/third_party/gerrit/detzip.go @@ -0,0 +1,97 @@ +package main + +import ( + "archive/zip" + "flag" + "fmt" + "io" + "log" + "os" + "path/filepath" + "sort" + "strings" +) + +var ( + exclude = flag.String("exclude", "", "comma-separated list of filenames to exclude (in any directory)") +) + +func init() { + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s [zip file] [directory]:\n", os.Args[0]) + flag.PrintDefaults() + } +} + +func listToMap(ss []string) map[string]bool { + m := make(map[string]bool) + for _, s := range ss { + m[s] = true + } + return m +} + +func main() { + flag.Parse() + if flag.NArg() != 2 { + flag.Usage() + os.Exit(1) + } + + outPath := flag.Arg(0) + dirPath := flag.Arg(1) + + excludeFiles := listToMap(strings.Split(*exclude, ",")) + + // Aggregate all files first. + var files []string + filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + if excludeFiles[info.Name()] { + return nil + } + files = append(files, path) + return nil + }) + + // Create zip + outW, err := os.Create(outPath) + if err != nil { + log.Fatalf("Create(%q): %v", outPath, err) + } + + zipW := zip.NewWriter(outW) + + // Output files in alphabetical order + sort.Strings(files) + for _, f := range files { + fw, err := zipW.CreateHeader(&zip.FileHeader{ + Name: f, + Method: zip.Store, + }) + if err != nil { + log.Fatalf("creating %q in zip: %v", f, err) + } + + ff, err := os.Open(f) + if err != nil { + log.Fatalf("opening %q: %v", f, err) + } + if _, err := io.Copy(fw, ff); err != nil { + log.Fatalf("copying %q to zip: %v", f, err) + } + ff.Close() + } + + if err := zipW.Close(); err != nil { + log.Fatalf("writing ZIP central directory: %v", err) + } + if err := outW.Close(); err != nil { + log.Fatalf("closing ZIP file: %v", err) + } +} |