Merge "PermissionBackend#filter: Use Collections instead of Maps"
diff --git a/WORKSPACE b/WORKSPACE
index e370f69..307e28c 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -235,6 +235,31 @@
sha1 = GUAVA_BIN_SHA1,
)
+CAFFEINE_VERS = "2.8.0"
+
+maven_jar(
+ name = "caffeine",
+ artifact = "com.github.ben-manes.caffeine:caffeine:" + CAFFEINE_VERS,
+ sha1 = "6000774d7f8412ced005a704188ced78beeed2bb",
+)
+
+# TODO(davido): Rename guava.jar to caffeine-guava.jar on fetch to prevent potential
+# naming collision between caffeine guava adapater and guava library itself.
+# Remove this renaming procedure, once this upstream issue is fixed:
+# https://github.com/ben-manes/caffeine/issues/364.
+http_file(
+ name = "caffeine-guava-renamed",
+ downloaded_file_path = "caffeine-guava-" + CAFFEINE_VERS + ".jar",
+ sha256 = "3a66ee3ec70971dee0bae6e56bda7b8742bc4bedd7489161bfbbaaf7137d89e1",
+ urls = [
+ "https://repo1.maven.org/maven2/com/github/ben-manes/caffeine/guava/" +
+ CAFFEINE_VERS +
+ "/guava-" +
+ CAFFEINE_VERS +
+ ".jar",
+ ],
+)
+
maven_jar(
name = "guava-failureaccess",
artifact = "com.google.guava:failureaccess:1.0.1",
diff --git a/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
index 309ee3e5..574a226 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticVersion.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
@@ -30,7 +30,8 @@
V7_1("7.1.*"),
V7_2("7.2.*"),
V7_3("7.3.*"),
- V7_4("7.4.*");
+ V7_4("7.4.*"),
+ V7_5("7.5.*");
private final String version;
private final Pattern pattern;
diff --git a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
index 0f228fe..1435c5e 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
@@ -126,7 +126,7 @@
edits = new ArrayList<>(content.getEdits());
ImmutableSet<Edit> editsDueToRebase = content.getEditsDueToRebase();
- if (isModify(content) && diffPrefs.intralineDifference) {
+ if (isModify(content) && diffPrefs.intralineDifference && isIntralineModeAllowed(b)) {
IntraLineDiff d =
patchListCache.getIntraLineDiff(
IntraLineDiffKey.create(a.id, b.id, diffPrefs.ignoreWhitespace),
@@ -260,6 +260,16 @@
}
}
+ private static boolean isIntralineModeAllowed(Side side) {
+ // The intraline diff cache keys are the same for these cases. It's better to not show
+ // intraline results than showing completely wrong diffs or to run into a server error.
+ return !Patch.isMagic(side.path) && !isSubmoduleCommit(side.mode);
+ }
+
+ private static boolean isSubmoduleCommit(FileMode mode) {
+ return mode.getObjectType() == Constants.OBJ_COMMIT;
+ }
+
private void correctForDifferencesInNewlineAtEnd(Side a, Side b) {
// a.src.size() is the size ignoring a newline at the end whereas a.size() considers it.
int aSize = a.src.size();
@@ -272,6 +282,12 @@
return;
}
+ if (edits.isEmpty() && (aSize != bSize)) {
+ // Only edits due to rebase were present. If we now added the edits for the newlines, the
+ // code which later assembles the file contents would fail.
+ return;
+ }
+
Optional<Edit> lastEdit = getLast(edits);
if (isNewlineAtEndDeleted(a, b)) {
Optional<Edit> lastLineEdit = lastEdit.filter(edit -> edit.getEndA() == aSize);
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RevisionDiffIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RevisionDiffIT.java
index 24ac209..d4a4c45 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RevisionDiffIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RevisionDiffIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
import static com.google.gerrit.entities.Patch.COMMIT_MSG;
+import static com.google.gerrit.entities.Patch.MERGE_LIST;
import static com.google.gerrit.extensions.common.testing.DiffInfoSubject.assertThat;
import static com.google.gerrit.extensions.common.testing.FileInfoSubject.assertThat;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
@@ -41,6 +42,7 @@
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.restapi.BinaryResult;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.testing.ConfigSuite;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
@@ -401,6 +403,24 @@
}
@Test
+ public void diffBetweenPatchSetsOfMergeCommitCanBeRetrievedForCommitMessageAndMergeList()
+ throws Exception {
+ PushOneCommit.Result result = createMergeCommitChange("refs/for/master", "my_file.txt");
+ String changeId = result.getChangeId();
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ addModifiedPatchSet(changeId, "my_file.txt", content -> content.concat("Line I\nLine II\n"));
+
+ // Call both of them in succession to ensure that they don't share the same cache keys.
+ DiffInfo commitMessageDiffInfo =
+ getDiffRequest(changeId, CURRENT, COMMIT_MSG).withBase(previousPatchSetId).get();
+ DiffInfo mergeListDiffInfo =
+ getDiffRequest(changeId, CURRENT, MERGE_LIST).withBase(previousPatchSetId).get();
+
+ assertThat(commitMessageDiffInfo).content().hasSize(3);
+ assertThat(mergeListDiffInfo).content().hasSize(1);
+ }
+
+ @Test
public void diffOfUnmodifiedFileMarksAllLinesAsCommon() throws Exception {
String filePath = "a_new_file.txt";
String fileContent = "Line 1\nLine 2\nLine 3\n";
@@ -578,6 +598,109 @@
}
@Test
+ public void addedNewlineAtEndOfFileIsMarkedInDiffWhenOtherwiseOnlyEditsDueToRebaseExist()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("Line 101"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.replace("Line 70\n", "Line seventy\n");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("\n"));
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_NONE)
+ .withBase(previousPatchSetId)
+ .get();
+ assertThat(diffInfo).content().element(0).commonLines().isNotEmpty();
+ assertThat(diffInfo).content().element(1).isNotNull(); // Line 70 modification
+ assertThat(diffInfo).content().element(2).commonLines().isNotEmpty();
+ assertThat(diffInfo).content().element(3).linesOfA().containsExactly("Line 101");
+ assertThat(diffInfo).content().element(3).linesOfB().containsExactly("Line 101", "");
+
+ assertThat(diffInfo).metaA().totalLineCount().isEqualTo(101);
+ assertThat(diffInfo).metaB().totalLineCount().isEqualTo(102);
+ }
+
+ @Test
+ // TODO: Fix this issue. This test documents the current behavior and ensures that we at least
+ // don't run into an internal server error.
+ public void addedNewlineAtEndOfFileIsNotIdentifiedAsDueToRebaseEvenThoughItShould()
+ throws Exception {
+ String baseFileContent = FILE_CONTENT.concat("Line 101");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, baseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ // Add a comment so that file contents are not 'skipped'. To be able to add a comment, touch
+ // (= modify) the file in the change.
+ addModifiedPatchSet(
+ changeId, FILE_NAME, fileContent -> fileContent.replace("Line 2\n", "Line two\n"));
+ CommentInput comment = createCommentInput(3, 0, 4, 0, "Comment to not skip file content.");
+ addCommentTo(changeId, CURRENT, FILE_NAME, comment);
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = baseFileContent.concat("\n");
+ ObjectId commit3 = addCommit(commit2, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit3);
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_ALL)
+ .withBase(previousPatchSetId)
+ .get();
+ assertThat(diffInfo).content().element(0).commonLines().isNotEmpty();
+ assertThat(diffInfo).content().element(1).linesOfA().isNull();
+ assertThat(diffInfo).content().element(1).linesOfB().containsExactly("");
+ // This should actually be isDueToRebase().
+ assertThat(diffInfo).content().element(1).isNotDueToRebase();
+ }
+
+ @Test
+ public void
+ addedNewlineAtEndOfFileIsMarkedWhenEditDueToRebaseIncreasedLineCountAndWhitespaceConsidered()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("Line 101"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.replace("Line 70\n", "Line 70\nLine 70.5\n");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("\n"));
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_NONE)
+ .withBase(previousPatchSetId)
+ .get();
+ assertThat(diffInfo).content().element(0).commonLines().isNotEmpty();
+ assertThat(diffInfo).content().element(1).isNotNull(); // Line 70.5 insertion
+ assertThat(diffInfo).content().element(2).commonLines().isNotEmpty();
+ assertThat(diffInfo).content().element(3).linesOfA().containsExactly("Line 101");
+ assertThat(diffInfo).content().element(3).linesOfB().containsExactly("Line 101", "");
+
+ assertThat(diffInfo).metaA().totalLineCount().isEqualTo(101);
+ assertThat(diffInfo).metaB().totalLineCount().isEqualTo(103);
+ }
+
+ @Test
+ // TODO: Fix this issue. This test documents the current behavior and ensures that we at least
+ // don't run into an internal server error.
+ public void
+ addedNewlineAtEndOfFileIsNotMarkedWhenEditDueToRebaseIncreasedLineCountAndWhitespaceIgnoredEvenThoughItShould()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("Line 101"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.replace("Line 70\n", "Line 70\nLine 70.5\n");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("\n"));
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_ALL)
+ .withBase(previousPatchSetId)
+ .get();
+ assertThat(diffInfo).content().element(0).numberOfSkippedLines().isGreaterThan(0);
+ }
+
+ @Test
public void addedLastLineWithoutNewlineBeforeAndAfterwardsIsMarkedInDiff() throws Exception {
addModifiedPatchSet(changeId, FILE_NAME, fileContent -> fileContent.concat("Line 101"));
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
@@ -2374,9 +2497,7 @@
addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
- ReviewInput reviewInput = new ReviewInput();
- reviewInput.comments = ImmutableMap.of(FILE_NAME, ImmutableList.of(comment));
- gApi.changes().id(changeId).revision(previousPatchSetId).review(reviewInput);
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
addModifiedPatchSet(
changeId, FILE_NAME2, content -> content.replace("2nd line\n", "Second line\n"));
@@ -2395,6 +2516,112 @@
}
@Test
+ public void
+ diffOfFileWithOnlyRebaseHunksAndWithCommentAndConsideringWhitespaceReturnsFileContents()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.replace("Line 70\n", "Line seventy\n");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withBase(previousPatchSetId)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_NONE)
+ .get();
+ // We don't list the full file contents here as that is not the focus of this test.
+ assertThat(diffInfo)
+ .content()
+ .element(0)
+ .commonLines()
+ .containsAtLeast("Line 1", "Line two", "Line 3", "Line 4", "Line 5")
+ .inOrder();
+ }
+
+ @Test
+ public void diffOfFileWithOnlyRebaseHunksAndWithCommentAndIgnoringWhitespaceReturnsFileContents()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.replace("Line 70\n", "Line seventy\n");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withBase(previousPatchSetId)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_ALL)
+ .get();
+ // We don't list the full file contents here as that is not the focus of this test.
+ assertThat(diffInfo)
+ .content()
+ .element(0)
+ .commonLines()
+ .containsAtLeast("Line 1", "Line two", "Line 3", "Line 4", "Line 5")
+ .inOrder();
+ }
+
+ @Test
+ public void
+ diffOfFileWithMultilineRebaseHunkAddingNewlineAtEndOfFileAndWithCommentReturnsFileContents()
+ throws Exception {
+ String baseFileContent = FILE_CONTENT.concat("Line 101");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, baseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = baseFileContent.concat("\nLine 102\nLine 103\n");
+ ObjectId commit3 = addCommit(commit2, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit3);
+ CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withBase(previousPatchSetId)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_NONE)
+ .get();
+ // We don't list the full file contents here as that is not the focus of this test.
+ assertThat(diffInfo)
+ .content()
+ .element(0)
+ .commonLines()
+ .containsAtLeast("Line 1", "Line two", "Line 3", "Line 4", "Line 5")
+ .inOrder();
+ }
+
+ @Test
+ public void
+ diffOfFileWithMultilineRebaseHunkRemovingNewlineAtEndOfFileAndWithCommentReturnsFileContents()
+ throws Exception {
+ addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
+ String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
+ String newBaseFileContent = FILE_CONTENT.concat("Line 101\nLine 103\nLine 104");
+ ObjectId commit2 = addCommit(commit1, FILE_NAME, newBaseFileContent);
+ rebaseChangeOn(changeId, commit2);
+ CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
+
+ DiffInfo diffInfo =
+ getDiffRequest(changeId, CURRENT, FILE_NAME)
+ .withBase(previousPatchSetId)
+ .withWhitespace(DiffPreferencesInfo.Whitespace.IGNORE_NONE)
+ .get();
+ // We don't list the full file contents here as that is not the focus of this test.
+ assertThat(diffInfo)
+ .content()
+ .element(0)
+ .commonLines()
+ .containsAtLeast("Line 1", "Line two", "Line 3", "Line 4", "Line 5")
+ .inOrder();
+ }
+
+ @Test
public void diffOfNonExistentFileIsAnEmptyDiffResult() throws Exception {
addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
@@ -2432,9 +2659,7 @@
changeId, FILE_NAME, content -> content.replace("Line 20\n", "Line twenty\n"));
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
CommentInput comment = createCommentInput(20, 0, 21, 0, "Should be 'Line 20'.");
- ReviewInput reviewInput = new ReviewInput();
- reviewInput.comments = ImmutableMap.of(FILE_NAME, ImmutableList.of(comment));
- gApi.changes().id(changeId).revision(previousPatchSetId).review(reviewInput);
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
addModifiedPatchSet(
changeId, FILE_NAME2, content -> content.replace("2nd line\n", "Second line\n"));
@@ -2476,9 +2701,7 @@
addModifiedPatchSet(changeId, FILE_NAME, content -> content.replace("Line 2\n", "Line two\n"));
String previousPatchSetId = gApi.changes().id(changeId).get().currentRevision;
CommentInput comment = createCommentInput(2, 0, 3, 0, "Should be 'Line 2'.");
- ReviewInput reviewInput = new ReviewInput();
- reviewInput.comments = ImmutableMap.of(FILE_NAME, ImmutableList.of(comment));
- gApi.changes().id(changeId).revision(previousPatchSetId).review(reviewInput);
+ addCommentTo(changeId, previousPatchSetId, FILE_NAME, comment);
String newFilePath = "a_new_file.txt";
gApi.changes().id(changeId).edit().renameFile(FILE_NAME, newFilePath);
gApi.changes().id(changeId).edit().publish();
@@ -2507,6 +2730,14 @@
return comment;
}
+ private void addCommentTo(
+ String changeId, String previousPatchSetId, String fileName, CommentInput comment)
+ throws RestApiException {
+ ReviewInput reviewInput = new ReviewInput();
+ reviewInput.comments = ImmutableMap.of(fileName, ImmutableList.of(comment));
+ gApi.changes().id(changeId).revision(previousPatchSetId).review(reviewInput);
+ }
+
private void assertDiffForNewFile(
PushOneCommit.Result pushResult, String path, String expectedContentSideB) throws Exception {
DiffInfo diff =
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
index dcdca86..eeeacab 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
@@ -37,7 +37,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_4);
+ return getConfig(ElasticVersion.V7_5);
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
index 1c41b55..1940274 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
@@ -38,7 +38,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_4);
+ return getConfig(ElasticVersion.V7_5);
}
@Override
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index c15f1a7..c692a3b 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -62,6 +62,8 @@
return "blacktop/elasticsearch:7.3.2";
case V7_4:
return "blacktop/elasticsearch:7.4.2";
+ case V7_5:
+ return "blacktop/elasticsearch:7.5.0";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
index da64d53..1601756 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
@@ -14,6 +14,8 @@
package com.google.gerrit.elasticsearch;
+import static java.util.concurrent.TimeUnit.MINUTES;
+
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testing.ConfigSuite;
@@ -22,7 +24,12 @@
import com.google.gerrit.testing.IndexConfig;
import com.google.inject.Guice;
import com.google.inject.Injector;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.eclipse.jgit.lib.Config;
+import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
@@ -35,6 +42,7 @@
private static ElasticNodeInfo nodeInfo;
private static ElasticContainer container;
+ private static CloseableHttpAsyncClient client;
@BeforeClass
public static void startIndexService() {
@@ -45,6 +53,8 @@
container = ElasticContainer.createAndStart(ElasticVersion.V6_8);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ client = HttpAsyncClients.createDefault();
+ client.start();
}
@AfterClass
@@ -56,6 +66,19 @@
@Rule public final GerritTestName testName = new GerritTestName();
+ @After
+ public void closeIndex() throws Exception {
+ client
+ .execute(
+ new HttpPost(
+ String.format(
+ "http://localhost:%d/%s*/_close",
+ nodeInfo.port, testName.getSanitizedMethodName())),
+ HttpClientContext.create(),
+ null)
+ .get(5, MINUTES);
+ }
+
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
index 021a80d..c55417e 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_4);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_5);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
index 6bb2f8fb..b4feb32 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -51,7 +51,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_4);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_5);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
client = HttpAsyncClients.createDefault();
client.start();
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
index 9312f01..c2d6246 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_4);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_5);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
index 4b9ede8..2fc4366 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_4);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_5);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
index f9cfe35..5d2f99c 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
@@ -60,6 +60,9 @@
assertThat(ElasticVersion.forVersion("7.4.0")).isEqualTo(ElasticVersion.V7_4);
assertThat(ElasticVersion.forVersion("7.4.1")).isEqualTo(ElasticVersion.V7_4);
+
+ assertThat(ElasticVersion.forVersion("7.5.0")).isEqualTo(ElasticVersion.V7_5);
+ assertThat(ElasticVersion.forVersion("7.5.1")).isEqualTo(ElasticVersion.V7_5);
}
@Test
@@ -89,6 +92,7 @@
assertThat(ElasticVersion.V7_2.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
assertThat(ElasticVersion.V7_3.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
assertThat(ElasticVersion.V7_4.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V7_5.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
}
@Test
@@ -106,6 +110,7 @@
assertThat(ElasticVersion.V7_2.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V7_3.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V7_4.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V7_5.isV6OrLater()).isTrue();
}
@Test
@@ -123,5 +128,6 @@
assertThat(ElasticVersion.V7_2.isV7OrLater()).isTrue();
assertThat(ElasticVersion.V7_3.isV7OrLater()).isTrue();
assertThat(ElasticVersion.V7_4.isV7OrLater()).isTrue();
+ assertThat(ElasticVersion.V7_5.isV7OrLater()).isTrue();
}
}
diff --git a/lib/BUILD b/lib/BUILD
index 39c622a..199f4fb 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -528,7 +528,7 @@
"//java/com/google/gerrit/acceptance:__pkg__",
"//java/com/google/gerrit/extensions:__pkg__",
"//java/com/google/gerrit/server:__pkg__",
- "//plugins:__pkg__",
+ "//plugins:__subpackages__",
],
exports = ["@javax-annotation//jar"],
)
diff --git a/package.json b/package.json
index 5ed4671..95edf0b 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,8 @@
"scripts": {
"start": "polygerrit-ui/run-server.sh",
"test": "WCT_HEADLESS_MODE=1 WCT_ARGS='--verbose -l chrome' ./polygerrit-ui/app/run_test.sh",
- "eslint": "./node_modules/eslint/bin/eslint.js --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app || exit 0",
- "eslintfix": "./node_modules/eslint/bin/eslint.js --fix --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app || exit 0",
+ "eslint": "./node_modules/eslint/bin/eslint.js --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app",
+ "eslintfix": "npm run eslint -- --fix",
"test-template": "./polygerrit-ui/app/run_template_test.sh",
"polylint": "bazel test polygerrit-ui/app:polylint_test"
},
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
index 2a57162..01e1f1f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
@@ -77,7 +77,6 @@
properties: {
diff: Object,
- diffPath: String,
changeNum: String,
patchNum: String,
viewMode: String,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
index f5dc438..bdb914f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
@@ -301,7 +301,7 @@
const layers = [this.$.syntaxLayer];
// Get layers from plugins (if any).
for (const pluginLayer of this.$.jsAPI.getDiffLayers(
- this.diffPath, this.changeNum, this.patchNum)) {
+ this.path, this.changeNum, this.patchNum)) {
layers.push(pluginLayer);
}
this._layers = layers;
@@ -313,7 +313,9 @@
this._coverageRanges = [];
const {changeNum, path, patchRange: {basePatchNum, patchNum}} = this;
- this.$.jsAPI.getCoverageRanges(changeNum, path, basePatchNum, patchNum).
+ this.$.jsAPI.getCoverageRanges(
+ changeNum, path, basePatchNum, patchNum
+ ).
then(coverageRanges => {
if (changeNum !== this.changeNum ||
path !== this.path ||
@@ -344,6 +346,8 @@
return this._loadDiffAssets(diff);
});
+ // Not waiting for getCoverageRanges intentionally as
+ // plugin loading should not block the content rendering
return Promise.all([diffRequest, assetRequest])
.then(results => {
const diff = results[0];
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
index 1446fd4..3b64f55 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
@@ -373,7 +373,7 @@
coverage-ranges="[[coverageRanges]]"
project-name="[[projectName]]"
diff="[[diff]]"
- diff-path="[[path]]"
+ path="[[path]]"
change-num="[[changeNum]]"
patch-num="[[patchRange.patchNum]]"
view-mode="[[viewMode]]"
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
index 46fa3cf..cb87bd9 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
@@ -247,7 +247,7 @@
<div id="container" class="container">
<div class="header" id="header" on-click="_handleToggleCollapsed">
<div class="headerLeft">
- <span class="authorName">[[comment.author.name]]</span>
+ <span class="authorName">[[_computeAuthorName(comment)]]</span>
<span class="draftLabel">DRAFT</span>
<gr-tooltip-content class="draftTooltip"
has-tooltip
@@ -258,6 +258,13 @@
<div class="headerMiddle">
<span class="collapsedContent">[[comment.message]]</span>
</div>
+ <div hidden$="[[_computeHideRunDetails(comment, collapsed)]]" class="runIdMessage message">
+ <div class="runIdInformation">
+ <a class="robotRunLink" href$="[[comment.url]]">
+ <span class="robotRun link">Run Details</span>
+ </a>
+ </div>
+ </div>
<gr-button
id="deleteBtn"
link
@@ -284,10 +291,9 @@
</div>
</div>
<div class="body">
- <template is="dom-if" if="[[comment.robot_id]]">
+ <template is="dom-if" if="[[isRobotComment]]">
<div class="robotId" hidden$="[[collapsed]]">
- <iron-icon class="robotIcon" icon="gr-icons:robot"></iron-icon>
- [[comment.robot_id]]
+ [[comment.author.name]]
</div>
</template>
<template is="dom-if" if="[[editing]]">
@@ -306,19 +312,6 @@
content="[[comment.message]]"
no-trailing-margin="[[!comment.__draft]]"
config="[[projectConfig.commentlinks]]"></gr-formatted-text>
- <div hidden$="[[!comment.robot_run_id]]" class="message">
- <div class="runIdInformation" hidden$="[[collapsed]]">
- Run ID:
- <template is="dom-if" if="[[comment.url]]">
- <a class="robotRunLink" href$="[[comment.url]]">
- <span class="robotRun link">[[comment.robot_run_id]]</span>
- </a>
- </template>
- <template is="dom-if" if="[[!comment.url]]">
- <span class="robotRun text">[[comment.robot_run_id]]</span>
- </template>
- </div>
- </div>
<div class="actions humanActions" hidden$="[[!_showHumanActions]]">
<div class="action resolve hideOnPublished">
<label>
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
index dd2855c..053eeee 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
@@ -75,7 +75,7 @@
static get properties() {
return {
changeNum: String,
- /** @type {?} */
+ /** @type {!Gerrit.Comment} */
comment: {
type: Object,
notify: true,
@@ -672,6 +672,19 @@
return overlay.open();
}
+ _computeAuthorName(comment) {
+ if (!comment) return '';
+ if (comment.robot_id) {
+ return comment.robot_id;
+ }
+ return comment.author && comment.author.name;
+ }
+
+ _computeHideRunDetails(comment, collapsed) {
+ if (!comment) return true;
+ return !(comment.robot_id && comment.url && !collapsed);
+ }
+
_closeOverlay(overlay) {
Polymer.dom(Gerrit.getRootElement()).removeChild(overlay);
overlay.close();
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
index de75b40..ad8b5e4 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
@@ -456,17 +456,13 @@
element.editing = false;
element.collapsed = false;
flushAsynchronousOperations();
- assert.isNotOk(element.$$('.robotRun.link'));
- assert.notEqual(getComputedStyle(element.$$('.robotRun.text')).display,
- 'none');
+ assert.isTrue(element.$$('.robotRun.link').textContent === 'Run Details');
// A robot comment with run ID and url should display a link.
element.set(['comment', 'url'], '/path/to/run');
flushAsynchronousOperations();
assert.notEqual(getComputedStyle(element.$$('.robotRun.link')).display,
'none');
- assert.equal(getComputedStyle(element.$$('.robotRun.text')).display,
- 'none');
});
test('collapsible drafts', () => {
@@ -527,6 +523,37 @@
'header middle content is not visible');
});
+ test('robot comment layout', () => {
+ const comment = Object.assign({
+ robot_id: 'happy_robot_id',
+ url: '/robot/comment',
+ author: {
+ name: 'Happy Robot',
+ },
+ }, element.comment);
+ element.comment = comment;
+ element.collapsed = false;
+ flushAsynchronousOperations();
+
+ let runIdMessage;
+ runIdMessage = element.$$('.runIdMessage');
+ assert.isFalse(runIdMessage.hidden);
+
+ const runDetailsLink = element.$$('.robotRunLink');
+ assert.isTrue(runDetailsLink.href.indexOf(element.comment.url) !== -1);
+
+ const robotServiceName = element.$$('.authorName');
+ assert.isTrue(robotServiceName.textContent === 'happy_robot_id');
+
+ const authorName = element.$$('.robotId');
+ assert.isTrue(authorName.innerText === 'Happy Robot');
+
+ element.collapsed = true;
+ flushAsynchronousOperations();
+ runIdMessage = element.$$('.runIdMessage');
+ assert.isTrue(runIdMessage.hidden);
+ });
+
test('draft creation/cancellation', done => {
assert.isFalse(element.editing);
MockInteractions.tap(element.$$('.edit'));
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
index 1802a4a..ae08007 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.js
@@ -270,10 +270,26 @@
// Only one coverage provider makes sense. If there are more, then we
// simply ignore them.
if (provider) {
- return provider(changeNum, path, basePatchNum, patchNum);
+ return annotationApi;
}
}
- return [];
+ return null;
+ }).then(annotationApi => {
+ if (!annotationApi) return [];
+ const provider = annotationApi.getCoverageProvider();
+ return provider(changeNum, path, basePatchNum, patchNum)
+ .then(ranges => {
+ ranges = ranges || [];
+ // Notify with the coverage data.
+ ranges.forEach(range => {
+ annotationApi.notify(
+ path,
+ range.code_range.start_line,
+ range.code_range.end_line,
+ range.side);
+ });
+ return ranges;
+ });
});
}
diff --git a/polygerrit-ui/app/styles/gr-change-view-integration-shared-styles.html b/polygerrit-ui/app/styles/gr-change-view-integration-shared-styles.html
index 5c5194c..76e978c 100644
--- a/polygerrit-ui/app/styles/gr-change-view-integration-shared-styles.html
+++ b/polygerrit-ui/app/styles/gr-change-view-integration-shared-styles.html
@@ -29,6 +29,10 @@
/* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
</style>
<style>
+ :host {
+ border-top: 1px solid var(--border-color);
+ display: block;
+ }
.header {
color: var(--primary-text-color);
background-color: var(--table-header-background-color);
diff --git a/polygerrit-ui/app/types/types.js b/polygerrit-ui/app/types/types.js
index 8dd65cb..3b91407 100644
--- a/polygerrit-ui/app/types/types.js
+++ b/polygerrit-ui/app/types/types.js
@@ -273,4 +273,27 @@
* makeSuggestionItem: function(Object): Gerrit.GrSuggestionItem,
* }}
*/
-Gerrit.GrSuggestionsProvider;
\ No newline at end of file
+Gerrit.GrSuggestionsProvider;
+
+/**
+ * @typedef {{
+ * patch_set: ?number,
+ * id: ?string,
+ * path: ?Object,
+ * side: ?string,
+ * parent: ?number,
+ * line: ?Object,
+ * in_reply_to: ?string,
+ * message: ?Object,
+ * updated: ?string,
+ * author: ?Object,
+ * tag: ?Object,
+ * unresolved: ?boolean,
+ * robot_id: ?string,
+ * robot_run_id: ?string,
+ * url: ?string,
+ * properties: ?Object,
+ * fix_suggestions: ?Object,
+ * }}
+ */
+Gerrit.Comment;
diff --git a/tools/nongoogle.bzl b/tools/nongoogle.bzl
index 1dfc2f4..6a29da6 100644
--- a/tools/nongoogle.bzl
+++ b/tools/nongoogle.bzl
@@ -69,8 +69,8 @@
# elasticsearch-rest-client explicitly depends on this version
maven_jar(
name = "httpcore-nio",
- artifact = "org.apache.httpcomponents:httpcore-nio:4.4.11",
- sha1 = "7d0a97d01d39cff9aa3e6db81f21fddb2435f4e6",
+ artifact = "org.apache.httpcomponents:httpcore-nio:4.4.12",
+ sha1 = "84cd29eca842f31db02987cfedea245af020198b",
)
maven_jar(
@@ -102,8 +102,8 @@
# and httpasyncclient as necessary.
maven_jar(
name = "elasticsearch-rest-client",
- artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.4.2",
- sha1 = "f48725523c0b3402f869214433602f8d3f4c737c",
+ artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.5.0",
+ sha1 = "62535b6fc3a4e943e88e7640eac22e29f03a696d",
)
maven_jar(