Merge "Suppress unchecked cast Java compiler warning" into stable-3.9
diff --git a/Documentation/prolog-cookbook.txt b/Documentation/prolog-cookbook.txt
index 6c77109..af944cf 100644
--- a/Documentation/prolog-cookbook.txt
+++ b/Documentation/prolog-cookbook.txt
@@ -3,7 +3,8 @@
[WARNING]
Prolog rules are no longer supported in Gerrit. Existing usages of prolog rules
-can be modified or deleted, but uploading new "rules.pl" files are rejected.
+can be modified or deleted. Uploading new "rules.pl" files will result in
+a warning being emitted.
Please use link:config-submit-requirements.html[submit requirements] instead.
Note that the link:#SubmitType[Submit Type] being deprecated in this
documentation page currently has no substitution in submit requirements.
diff --git a/java/com/google/gerrit/server/account/HashedPassword.java b/java/com/google/gerrit/server/account/HashedPassword.java
index 09115503..7a7c35b 100644
--- a/java/com/google/gerrit/server/account/HashedPassword.java
+++ b/java/com/google/gerrit/server/account/HashedPassword.java
@@ -136,6 +136,6 @@
public boolean checkPassword(String password) {
// Constant-time comparison, because we're paranoid.
- return Arrays.areEqual(hashPassword(password, salt, cost, nullTerminate), hashed);
+ return Arrays.constantTimeAreEqual(hashPassword(password, salt, cost, nullTerminate), hashed);
}
}
diff --git a/java/com/google/gerrit/server/data/PatchSetAttribute.java b/java/com/google/gerrit/server/data/PatchSetAttribute.java
index dc47057..3f7c8e4 100644
--- a/java/com/google/gerrit/server/data/PatchSetAttribute.java
+++ b/java/com/google/gerrit/server/data/PatchSetAttribute.java
@@ -17,7 +17,7 @@
import com.google.gerrit.extensions.client.ChangeKind;
import java.util.List;
-public class PatchSetAttribute {
+public class PatchSetAttribute implements Cloneable {
public int number;
public String revision;
public List<String> parents;
@@ -32,4 +32,12 @@
public List<PatchAttribute> files;
public int sizeInsertions;
public int sizeDeletions;
+
+ public PatchSetAttribute shallowClone() {
+ try {
+ return (PatchSetAttribute) super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new AssertionError(e);
+ }
+ }
}
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index 46fe994..fad710a 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -77,6 +77,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -359,33 +360,23 @@
public void addPatchSets(
RevWalk revWalk,
+ Config repoConfig,
ChangeAttribute ca,
- Collection<PatchSet> ps,
- Map<PatchSet.Id, Collection<PatchSetApproval>> approvals,
- LabelTypes labelTypes,
- AccountAttributeLoader accountLoader) {
- addPatchSets(revWalk, ca, ps, approvals, false, null, labelTypes, accountLoader);
- }
-
- public void addPatchSets(
- RevWalk revWalk,
- ChangeAttribute ca,
- Collection<PatchSet> ps,
Map<PatchSet.Id, Collection<PatchSetApproval>> approvals,
boolean includeFiles,
- Change change,
- LabelTypes labelTypes,
+ ChangeData changeData,
AccountAttributeLoader accountLoader) {
- if (!ps.isEmpty()) {
- ca.patchSets = new ArrayList<>(ps.size());
- for (PatchSet p : ps) {
- PatchSetAttribute psa = asPatchSetAttribute(revWalk, change, p, accountLoader);
+ if (!changeData.patchSets().isEmpty()) {
+ ca.patchSets = new ArrayList<>(changeData.patchSets().size());
+ for (PatchSet p : changeData.patchSets()) {
+ PatchSetAttribute psa =
+ asPatchSetAttribute(revWalk, repoConfig, changeData, p, accountLoader);
if (approvals != null) {
- addApprovals(psa, p.id(), approvals, labelTypes, accountLoader);
+ addApprovals(psa, p.id(), approvals, changeData.getLabelTypes(), accountLoader);
}
ca.patchSets.add(psa);
if (includeFiles) {
- addPatchSetFileNames(psa, change, p);
+ addPatchSetFileNames(psa, changeData.change(), p);
}
}
}
@@ -442,13 +433,18 @@
}
}
- public PatchSetAttribute asPatchSetAttribute(RevWalk revWalk, Change change, PatchSet patchSet) {
- return asPatchSetAttribute(revWalk, change, patchSet, null);
+ public PatchSetAttribute asPatchSetAttribute(
+ RevWalk revWalk, Config repoConfig, ChangeData changeData, PatchSet patchSet) {
+ return asPatchSetAttribute(revWalk, repoConfig, changeData, patchSet, null);
}
/** Create a PatchSetAttribute for the given patchset suitable for serialization to JSON. */
public PatchSetAttribute asPatchSetAttribute(
- RevWalk revWalk, Change change, PatchSet patchSet, AccountAttributeLoader accountLoader) {
+ RevWalk revWalk,
+ Config repoConfig,
+ ChangeData changeData,
+ PatchSet patchSet,
+ AccountAttributeLoader accountLoader) {
PatchSetAttribute p = new PatchSetAttribute();
p.revision = patchSet.commitId().name();
p.number = patchSet.number();
@@ -475,12 +471,12 @@
Map<String, FileDiffOutput> modifiedFiles =
diffOperations.listModifiedFilesAgainstParent(
- change.getProject(), patchSet.commitId(), /* parentNum= */ 0, DiffOptions.DEFAULTS);
+ changeData.project(), patchSet.commitId(), /* parentNum= */ 0, DiffOptions.DEFAULTS);
for (FileDiffOutput fileDiff : modifiedFiles.values()) {
p.sizeDeletions += fileDiff.deletions();
p.sizeInsertions += fileDiff.insertions();
}
- p.kind = changeKindCache.getChangeKind(change, patchSet);
+ p.kind = changeKindCache.getChangeKind(revWalk, repoConfig, changeData, patchSet);
} catch (IOException | StorageException e) {
logger.atSevere().withCause(e).log("Cannot load patch set data for %s", patchSet.id());
} catch (DiffNotAvailableException e) {
diff --git a/java/com/google/gerrit/server/events/StreamEventsApiListener.java b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
index 4133c90..136be8d 100644
--- a/java/com/google/gerrit/server/events/StreamEventsApiListener.java
+++ b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
@@ -64,6 +64,7 @@
import com.google.gerrit.server.plugincontext.PluginItemContext;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -147,6 +148,7 @@
private final PatchSetUtil psUtil;
private final ChangeNotes.Factory changeNotesFactory;
private final boolean enableDraftCommentEvents;
+ private final ChangeData.Factory changeDataFactory;
@Inject
StreamEventsApiListener(
@@ -156,7 +158,8 @@
GitRepositoryManager repoManager,
PatchSetUtil psUtil,
ChangeNotes.Factory changeNotesFactory,
- @GerritServerConfig Config config) {
+ @GerritServerConfig Config config,
+ ChangeData.Factory changeDataFactory) {
this.dispatcher = dispatcher;
this.eventFactory = eventFactory;
this.projectCache = projectCache;
@@ -165,6 +168,7 @@
this.changeNotesFactory = changeNotesFactory;
this.enableDraftCommentEvents =
config.getBoolean("event", "stream-events", "enableDraftCommentEvents", false);
+ this.changeDataFactory = changeDataFactory;
}
private ChangeNotes getNotes(ChangeInfo info) {
@@ -200,12 +204,13 @@
}
private Supplier<PatchSetAttribute> patchSetAttributeSupplier(
- final Change change, PatchSet patchSet) {
+ final ChangeData changeData, PatchSet patchSet) {
return Suppliers.memoize(
() -> {
- try (Repository repo = repoManager.openRepository(change.getProject());
+ try (Repository repo = repoManager.openRepository(changeData.change().getProject());
RevWalk revWalk = new RevWalk(repo)) {
- return eventFactory.asPatchSetAttribute(revWalk, change, patchSet);
+ return eventFactory.asPatchSetAttribute(
+ revWalk, repo.getConfig(), changeData, patchSet);
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -295,7 +300,7 @@
PatchSetCreatedEvent event = new PatchSetCreatedEvent(change);
event.change = changeAttributeSupplier(change, notes);
- event.patchSet = patchSetAttributeSupplier(change, patchSet);
+ event.patchSet = patchSetAttributeSupplier(changeDataFactory.create(notes), patchSet);
event.uploader = accountAttributeSupplier(ev.getWho());
dispatcher.run(d -> d.postEvent(change, event));
@@ -311,7 +316,8 @@
Change change = notes.getChange();
ReviewerDeletedEvent event = new ReviewerDeletedEvent(change);
event.change = changeAttributeSupplier(change, notes);
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.reviewer = accountAttributeSupplier(ev.getReviewer());
event.remover = accountAttributeSupplier(ev.getWho());
event.comment = ev.getComment();
@@ -332,7 +338,8 @@
ReviewerAddedEvent event = new ReviewerAddedEvent(change);
event.change = changeAttributeSupplier(change, notes);
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.adder = accountAttributeSupplier(ev.getWho());
for (AccountInfo reviewer : ev.getReviewers()) {
event.reviewer = accountAttributeSupplier(reviewer);
@@ -454,7 +461,7 @@
event.change = changeAttributeSupplier(change, notes);
event.author = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, ps);
+ event.patchSet = patchSetAttributeSupplier(changeDataFactory.create(notes), ps);
event.comment = ev.getComment();
event.approvals = approvalsAttributeSupplier(change, ev.getApprovals(), ev.getOldApprovals());
@@ -473,7 +480,8 @@
event.change = changeAttributeSupplier(change, notes);
event.restorer = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.reason = ev.getReason();
dispatcher.run(d -> d.postEvent(change, event));
@@ -491,7 +499,8 @@
event.change = changeAttributeSupplier(change, notes);
event.submitter = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.newRev = ev.getNewRevisionId();
dispatcher.run(d -> d.postEvent(change, event));
@@ -509,7 +518,8 @@
event.change = changeAttributeSupplier(change, notes);
event.abandoner = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.reason = ev.getReason();
dispatcher.run(d -> d.postEvent(change, event));
@@ -528,7 +538,7 @@
event.change = changeAttributeSupplier(change, notes);
event.changer = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, patchSet);
+ event.patchSet = patchSetAttributeSupplier(changeDataFactory.create(notes), patchSet);
dispatcher.run(d -> d.postEvent(change, event));
} catch (StorageException e) {
@@ -546,7 +556,7 @@
event.change = changeAttributeSupplier(change, notes);
event.changer = accountAttributeSupplier(ev.getWho());
- event.patchSet = patchSetAttributeSupplier(change, patchSet);
+ event.patchSet = patchSetAttributeSupplier(changeDataFactory.create(notes), patchSet);
dispatcher.run(d -> d.postEvent(change, event));
} catch (StorageException e) {
@@ -562,7 +572,8 @@
VoteDeletedEvent event = new VoteDeletedEvent(change);
event.change = changeAttributeSupplier(change, notes);
- event.patchSet = patchSetAttributeSupplier(change, psUtil.current(notes));
+ event.patchSet =
+ patchSetAttributeSupplier(changeDataFactory.create(notes), psUtil.current(notes));
event.comment = ev.getMessage();
event.reviewer = accountAttributeSupplier(ev.getReviewer());
event.remover = accountAttributeSupplier(ev.getWho());
diff --git a/java/com/google/gerrit/server/query/change/OutputStreamQuery.java b/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
index d21f5b6..40ebaea 100644
--- a/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
+++ b/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
@@ -21,7 +21,6 @@
import com.google.common.collect.Lists;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Change;
-import com.google.gerrit.entities.LabelTypes;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
@@ -261,7 +260,6 @@
Map<Project.NameKey, RevWalk> revWalks,
AccountAttributeLoader accountLoader)
throws IOException {
- LabelTypes labelTypes = d.getLabelTypes();
ChangeAttribute c = eventFactory.asChangeAttribute(d.change(), accountLoader);
c.hashtags = Lists.newArrayList(d.hashtags());
eventFactory.extend(c, d.change());
@@ -285,67 +283,71 @@
eventFactory.addCommitMessage(c, d.commitMessage());
}
- RevWalk rw = null;
if (includePatchSets || includeCurrentPatchSet || includeDependencies) {
Project.NameKey p = d.change().getProject();
- rw = revWalks.get(p);
+ Repository repo;
+ RevWalk rw = revWalks.get(p);
// Cache and reuse repos and revwalks.
if (rw == null) {
- Repository repo = repoManager.openRepository(p);
+ repo = repoManager.openRepository(p);
checkState(repos.put(p, repo) == null);
rw = new RevWalk(repo);
revWalks.put(p, rw);
+ } else {
+ repo = repos.get(p);
}
- }
- if (includePatchSets) {
- eventFactory.addPatchSets(
- rw,
- c,
- d.patchSets(),
- includeApprovals ? d.conditionallyLoadApprovalsWithCopied().asMap() : null,
- includeFiles,
- d.change(),
- labelTypes,
- accountLoader);
- }
-
- if (includeCurrentPatchSet) {
- PatchSet current = d.currentPatchSet();
- if (current != null) {
- c.currentPatchSet = eventFactory.asPatchSetAttribute(rw, d.change(), current);
- eventFactory.addApprovals(
- c.currentPatchSet, d.currentApprovals(), labelTypes, accountLoader);
-
- if (includeFiles) {
- eventFactory.addPatchSetFileNames(c.currentPatchSet, d.change(), d.currentPatchSet());
- }
+ if (includePatchSets) {
+ eventFactory.addPatchSets(
+ rw,
+ repo.getConfig(),
+ c,
+ includeApprovals ? d.conditionallyLoadApprovalsWithCopied().asMap() : null,
+ includeFiles,
+ d,
+ accountLoader);
if (includeComments) {
- eventFactory.addPatchSetComments(c.currentPatchSet, d.publishedComments(), accountLoader);
+ for (PatchSetAttribute attribute : c.patchSets) {
+ eventFactory.addPatchSetComments(attribute, d.publishedComments(), accountLoader);
+ }
}
}
+
+ if (includeCurrentPatchSet) {
+ PatchSet current = d.currentPatchSet();
+ if (current != null) {
+ if (includePatchSets) {
+ for (PatchSetAttribute attribute : c.patchSets) {
+ if (attribute.number == current.number()) {
+ c.currentPatchSet = attribute.shallowClone();
+ // approvals will be populated later using different logic than --patch-sets uses
+ c.currentPatchSet.approvals = null;
+ break;
+ }
+ }
+ } else {
+ c.currentPatchSet =
+ eventFactory.asPatchSetAttribute(rw, repo.getConfig(), d, current, accountLoader);
+ if (includeFiles) {
+ eventFactory.addPatchSetFileNames(c.currentPatchSet, d.change(), d.currentPatchSet());
+ }
+ if (includeComments) {
+ eventFactory.addPatchSetComments(
+ c.currentPatchSet, d.publishedComments(), accountLoader);
+ }
+ }
+ eventFactory.addApprovals(
+ c.currentPatchSet, d.currentApprovals(), d.getLabelTypes(), accountLoader);
+ }
+ }
+
+ if (includeDependencies) {
+ eventFactory.addDependencies(rw, c, d.change(), d.currentPatchSet());
+ }
}
if (includeComments) {
eventFactory.addComments(c, d.messages(), accountLoader);
- if (includePatchSets) {
- eventFactory.addPatchSets(
- rw,
- c,
- d.patchSets(),
- includeApprovals ? d.approvals().asMap() : null,
- includeFiles,
- d.change(),
- labelTypes,
- accountLoader);
- for (PatchSetAttribute attribute : c.patchSets) {
- eventFactory.addPatchSetComments(attribute, d.publishedComments(), accountLoader);
- }
- }
- }
-
- if (includeDependencies) {
- eventFactory.addDependencies(rw, c, d.change(), d.currentPatchSet());
}
List<PluginDefinedInfo> pluginInfos = pluginInfosByChange.get(d.getId());
diff --git a/package.json b/package.json
index e671e86..7ff0169 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"@typescript-eslint/parser": "^5.62.0"
},
"devDependencies": {
- "@koa/cors": "^3.4.3",
+ "@koa/cors": "^5.0.0",
"@types/page": "^1.11.6",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@web/dev-server": "^0.1.38",
diff --git a/web-dev-server.config.mjs b/web-dev-server.config.mjs
index 2a7dca4..53a240e 100644
--- a/web-dev-server.config.mjs
+++ b/web-dev-server.config.mjs
@@ -1,5 +1,7 @@
import { esbuildPlugin } from "@web/dev-server-esbuild";
import cors from "@koa/cors";
+import path from 'node:path';
+import fs from 'node:fs';
/** @type {import('@web/dev-server').DevServerConfig} */
export default {
@@ -18,6 +20,20 @@
// (ex: gerrit-review.googlesource.com), which happens during local
// development with Gerrit FE Helper extension.
cors({ origin: "*" }),
+ // Map some static assets.
+ // When creating the bundle, the files are moved by polygerrit_bundle() in
+ // polygerrit-ui/app/rules.bzl
+ async (context, next) => {
+
+ if ( context.url.includes("/bower_components/webcomponentsjs/webcomponents-lite.js") ) {
+ context.response.redirect("/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js");
+
+ } else if ( context.url.startsWith( "/fonts/" ) ) {
+ const fontFile = path.join( "lib/fonts", path.basename(context.url) );
+ context.body = fs.createReadStream( fontFile );
+ }
+ await next();
+ },
// The issue solved here is that our production index.html does not load
// 'gr-app.js' as an ESM module due to our build process, but in development
// all our source code is written as ESM modules. When using the Gerrit FE
@@ -40,6 +56,7 @@
await next();
if (!isGrAppMjs && context.url.includes("gr-app.js")) {
+ context.set('Content-Type', 'application/javascript; charset=utf-8');
context.body = "import('./gr-app.mjs')";
}
},
diff --git a/yarn.lock b/yarn.lock
index 5702d39..e6e6566 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -252,10 +252,10 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
-"@koa/cors@^3.4.3":
- version "3.4.3"
- resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.4.3.tgz#d669ee6e8d6e4f0ec4a7a7b0a17e7a3ed3752ebb"
- integrity sha512-WPXQUaAeAMVaLTEFpoq3T2O1C+FstkjJnDQqy95Ck1UdILajsRhu6mhJ8H2f4NFPRBoCNN+qywTJfq/gGki5mw==
+"@koa/cors@^5.0.0":
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-5.0.0.tgz#0029b5f057fa0d0ae0e37dd2c89ece315a0daffd"
+ integrity sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==
dependencies:
vary "^1.1.2"