Merge "Make the trailing-whitespace CSS rule more specific"
diff --git a/Documentation/config-plugins.txt b/Documentation/config-plugins.txt
index 81c9927..8324a72 100644
--- a/Documentation/config-plugins.txt
+++ b/Documentation/config-plugins.txt
@@ -143,6 +143,18 @@
rights directly to a single user, since in Gerrit access rights can
only be assigned to groups.
+[[webhooks]]
+=== webhooks
+
+This plugin allows to propagate Gerrit events to remote http endpoints.
+
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/webhooks[
+Project] |
+link:https://gerrit.googlesource.com/plugins/webhooks/+doc/master/src/main/resources/Documentation/about.md[
+Documentation] |
+link:https://gerrit.googlesource.com/plugins/webhooks/+doc/master/src/main/resources/Documentation/config.md[
+Configuration]
+
[[other-plugins]]
== Other Plugins
diff --git a/Documentation/pg-plugin-endpoints.txt b/Documentation/pg-plugin-endpoints.txt
index cb80c74..ff62da1 100644
--- a/Documentation/pg-plugin-endpoints.txt
+++ b/Documentation/pg-plugin-endpoints.txt
@@ -35,6 +35,11 @@
The following endpoints are available to plugins.
+=== banner
+The `banner` extension point is located at the top of all pages. The purpose
+is to allow plugins to show outage information and important announcements to
+all users.
+
=== change-view-integration
The `change-view-integration` extension point is located between `Files` and
`Messages` section on the change view page, and it may take full page's
diff --git a/WORKSPACE b/WORKSPACE
index b39bc78..3addf85 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -829,15 +829,15 @@
# elasticsearch-rest-client explicitly depends on this version
maven_jar(
name = "httpasyncclient",
- artifact = "org.apache.httpcomponents:httpasyncclient:4.1.2",
- sha1 = "95aa3e6fb520191a0970a73cf09f62948ee614be",
+ artifact = "org.apache.httpcomponents:httpasyncclient:4.1.4",
+ sha1 = "f3a3240681faae3fa46b573a4c7e50cec9db0d86",
)
# elasticsearch-rest-client explicitly depends on this version
maven_jar(
name = "httpcore-nio",
- artifact = "org.apache.httpcomponents:httpcore-nio:4.4.5",
- sha1 = "f4be009e7505f6ceddf21e7960c759f413f15056",
+ artifact = "org.apache.httpcomponents:httpcore-nio:4.4.11",
+ sha1 = "7d0a97d01d39cff9aa3e6db81f21fddb2435f4e6",
)
# Test-only dependencies below.
@@ -1059,8 +1059,8 @@
# and httpasyncclient as necessary.
maven_jar(
name = "elasticsearch-rest-client",
- artifact = "org.elasticsearch.client:elasticsearch-rest-client:6.7.1",
- sha1 = "a00aa6cc593a464e4a890d1a226ded5c625659ab",
+ artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.0.0",
+ sha1 = "121d12f1c71f318be1a654e8a956e38d5b68e98a",
)
JACKSON_VERSION = "2.9.8"
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 103edd8..b68be77 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -1842,7 +1842,7 @@
if (magicBranch.deprecatedTopicSeen) {
messages.add(
new ValidationMessage(
- "WARNING: deprecated topic syntax. Use %topic=TOPIC instead", false));
+ "WARNING: deprecated topic syntax. Use -o topic=TOPIC instead", false));
logger.atInfo().log("deprecated topic push seen for project %s", project.getName());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index 479788a..8400d02 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -51,7 +51,7 @@
case V6_7:
return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.7.1";
case V7_0:
- return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.0-rc2";
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.0";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
index 0ce66e8..f01138a 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V6_2);
+ container = ElasticContainer.createAndStart(ElasticVersion.V6_7);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/plugins/BUILD b/plugins/BUILD
index c7ad8a4..4837b67 100644
--- a/plugins/BUILD
+++ b/plugins/BUILD
@@ -42,6 +42,7 @@
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/metrics/dropwizard",
"//java/com/google/gerrit/reviewdb:server",
+ "//java/com/google/gerrit/server/api",
"//java/com/google/gerrit/server/audit",
"//java/com/google/gerrit/server/cache/mem",
"//java/com/google/gerrit/server/logging",
@@ -50,6 +51,8 @@
"//java/com/google/gerrit/util/cli",
"//java/com/google/gerrit/util/http",
"//java/com/google/gwtorm",
+ "//lib/antlr:java-runtime",
+ "//lib/auto:auto-value-annotations",
"//lib/commons:compress",
"//lib/commons:dbcp",
"//lib/commons:lang",
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
index 7c6fbc6..a1af8e1 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
@@ -151,7 +151,8 @@
sectionIndex: 0,
};
- content = this._splitCommonGroupsWithComments(content);
+ content = this._splitLargeChunks(content);
+ content = this._splitUnchangedChunksWithComments(content);
let currentBatch = 0;
const nextStep = () => {
@@ -384,60 +385,78 @@
return new GrDiffGroup(GrDiffGroup.Type.BOTH, [line]);
},
+
+ /**
+ * Split chunks into smaller chunks of the same kind.
+ *
+ * This is done to prevent doing too much work on the main thread in one
+ * uninterrupted rendering step, which would make the browser unresponsive.
+ *
+ * Note that in the case of unmodified chunks, we only split chunks if the
+ * context is set to file (because otherwise they are split up further down
+ * the processing into the visible and hidden context), and only split it
+ * into 2 chunks, one max sized one and the rest (for reasons that are
+ * unclear to me).
+ *
+ * @param {!Array<!Object>} chunks Chunks as returned from the server
+ * @return {!Array<!Object>} Finer grained chunks.
+ */
+ _splitLargeChunks(chunks) {
+ const newChunks = [];
+
+ for (const chunk of chunks) {
+ if (!chunk.ab) {
+ for (const group of this._breakdownGroup(chunk)) {
+ newChunks.push(group);
+ }
+ continue;
+ }
+
+ // If the context is set to "whole file", then break down the shared
+ // chunks so they can be rendered incrementally. Note: this is not
+ // enabled for any other context preference because manipulating the
+ // chunks in this way violates assumptions by the context grouper logic.
+ if (this.context === -1 && chunk.ab.length > MAX_GROUP_SIZE * 2) {
+ // Split large shared groups in two, where the first is the maximum
+ // group size.
+ newChunks.push({ab: chunk.ab.slice(0, MAX_GROUP_SIZE)});
+ newChunks.push({ab: chunk.ab.slice(MAX_GROUP_SIZE)});
+ } else {
+ newChunks.push(chunk);
+ }
+ }
+ return newChunks;
+ },
+
/**
* In order to show comments out of the bounds of the selected context,
* treat them as separate chunks within the model so that the content (and
* context surrounding it) renders correctly.
- * @param {?} content The diff content object. (has to be iterable)
- * @return {!Object} A new diff content object with regions split up.
+ * @param {!Array<!Object>} chunks DiffContents as returned from server.
+ * @return {!Array<!Object>} Finer grained DiffContents.
*/
- _splitCommonGroupsWithComments(content) {
+ _splitUnchangedChunksWithComments(chunks) {
const result = [];
let leftLineNum = 0;
let rightLineNum = 0;
- // If the context is set to "whole file", then break down the shared
- // chunks so they can be rendered incrementally. Note: this is not enabled
- // for any other context preference because manipulating the chunks in
- // this way violates assumptions by the context grouper logic.
- if (this.context === -1) {
- const newContent = [];
- for (const group of content) {
- if (group.ab && group.ab.length > MAX_GROUP_SIZE * 2) {
- // Split large shared groups in two, where the first is the maximum
- // group size.
- newContent.push({ab: group.ab.slice(0, MAX_GROUP_SIZE)});
- newContent.push({ab: group.ab.slice(MAX_GROUP_SIZE)});
- } else {
- newContent.push(group);
+ for (const chunk of chunks) {
+ // If it isn't a common chunk, append it as-is and update line numbers.
+ if (!chunk.ab) {
+ if (chunk.a) {
+ leftLineNum += chunk.a.length;
}
- }
- content = newContent;
- }
-
- // For each section in the diff.
- for (let i = 0; i < content.length; i++) {
- // If it isn't a common group, append it as-is and update line numbers.
- if (!content[i].ab) {
- if (content[i].a) {
- leftLineNum += content[i].a.length;
+ if (chunk.b) {
+ rightLineNum += chunk.b.length;
}
- if (content[i].b) {
- rightLineNum += content[i].b.length;
- }
-
- for (const group of this._breakdownGroup(content[i])) {
- result.push(group);
- }
-
+ result.push(chunk);
continue;
}
- const chunk = content[i].ab;
let currentChunk = {ab: []};
// For each line in the common group.
- for (const subChunk of chunk) {
+ for (const line of chunk.ab) {
leftLineNum++;
rightLineNum++;
@@ -453,10 +472,10 @@
}
// Add the non-collapse line as its own chunk.
- result.push({ab: [subChunk]});
+ result.push({ab: [line]});
} else {
// Append the current line to the current chunk.
- currentChunk.ab.push(subChunk);
+ currentChunk.ab.push(line);
}
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
index 7ccd9f8..186a49e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
@@ -280,7 +280,6 @@
left: {1: true},
right: {10: true},
};
- const lineNums = {left: 0, right: 0};
const content = [
{
@@ -304,7 +303,7 @@
},
];
const result =
- element._splitCommonGroupsWithComments(content, lineNums);
+ element._splitUnchangedChunksWithComments(content);
assert.deepEqual(result, [
{
ab: ['Copyright (C) 2015 The Android Open Source Project'],
@@ -337,28 +336,25 @@
]);
});
- test('breaks-down shared chunks w/ whole-file', () => {
+ test('breaks down shared chunks w/ whole-file', () => {
const size = 120 * 2 + 5;
- const lineNums = {left: 0, right: 0};
const content = [{
ab: _.times(size, () => { return `${Math.random()}`; }),
}];
element.context = -1;
- const result =
- element._splitCommonGroupsWithComments(content, lineNums);
+ const result = element._splitLargeChunks(content);
assert.equal(result.length, 2);
assert.deepEqual(result[0].ab, content[0].ab.slice(0, 120));
assert.deepEqual(result[1].ab, content[0].ab.slice(120));
});
test('does not break-down shared chunks w/ context', () => {
- const lineNums = {left: 0, right: 0};
const content = [{
ab: _.times(75, () => { return `${Math.random()}`; }),
}];
element.context = 4;
const result =
- element._splitCommonGroupsWithComments(content, lineNums);
+ element._splitUnchangedChunksWithComments(content);
assert.deepEqual(result, content);
});
diff --git a/polygerrit-ui/app/elements/gr-app.html b/polygerrit-ui/app/elements/gr-app.html
index 1cdf035..e537ac4 100644
--- a/polygerrit-ui/app/elements/gr-app.html
+++ b/polygerrit-ui/app/elements/gr-app.html
@@ -15,16 +15,18 @@
limitations under the License.
-->
<script>
- // This must be set prior to loading Polymer for the first time.
- if (localStorage.getItem('USE_SHADOW_DOM') === 'true') {
- window.Polymer = {
- dom: 'shadow',
- passiveTouchGestures: true,
- };
- } else if (!window.Polymer) {
- window.Polymer = {
- passiveTouchGestures: true,
- };
+ if (!window.POLYMER2) {
+ // This must be set prior to loading Polymer for the first time.
+ if (localStorage.getItem('USE_SHADOW_DOM') === 'true') {
+ window.Polymer = {
+ dom: 'shadow',
+ passiveTouchGestures: true,
+ };
+ } else if (!window.Polymer) {
+ window.Polymer = {
+ passiveTouchGestures: true,
+ };
+ }
}
// Needed for JSCompiler to understand it's global.
// eslint-disable-next-line no-unused-vars, prefer-const
@@ -148,6 +150,7 @@
color: var(--error-text-color);
}
</style>
+ <gr-endpoint-decorator name="banner"></gr-endpoint-decorator>
<gr-fixed-panel id="header">
<gr-main-header
id="mainHeader"
diff --git a/polygerrit-ui/app/elements/gr-app.js b/polygerrit-ui/app/elements/gr-app.js
index 5889054..a2a495b 100644
--- a/polygerrit-ui/app/elements/gr-app.js
+++ b/polygerrit-ui/app/elements/gr-app.js
@@ -20,9 +20,10 @@
// Eagerly render Polymer components when backgrounded. (Skips
// requestAnimationFrame.)
// @see https://github.com/Polymer/polymer/issues/3851
- // TODO: Reassess after Polymer 2.0 upgrade.
// @see Issue 4699
- Polymer.RenderStatus._makeReady();
+ if (!window.POLYMER2) {
+ Polymer.RenderStatus._makeReady();
+ }
Polymer({
is: 'gr-app',
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index e4f699c..85f338c 100644
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -24,6 +24,7 @@
{@param? faviconPath: ?}
{@param? versionInfo: ?}
{@param? deprecateGwtUi: ?}
+ {@param? polymer2: ?}
<!DOCTYPE html>{\n}
<html lang="en">{\n}
<meta charset="utf-8">{\n}
@@ -42,6 +43,7 @@
{if $versionInfo}window.VERSION_INFO = '{$versionInfo}';{/if}
{if $staticResourcePath != ''}window.STATIC_RESOURCE_PATH = '{$staticResourcePath}';{/if}
{if $assetsPath}window.ASSETS_PATH = '{$assetsPath}';{/if}
+ {if $polymer2}window.POLYMER2 = true;{/if}
</script>{\n}
{if $faviconPath}