Merge "Add download commands to project pages"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index aca1586..185af15 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -970,10 +970,10 @@
[[capability.administrateServer]]capability.administrateServer::
+
Names of groups of users that are allowed to exercise the
-administrateServer capability, in addition to those listed in
+`administrateServer` capability, in addition to those listed in
All-Projects. Configuring this option can be a useful fail-safe
to recover a server in the event an administrator removed all
-groups from the administrateServer capability, or to ensure that
+groups from the `administrateServer` capability, or to ensure that
specific groups always have administration capabilities.
+
----
@@ -987,7 +987,16 @@
is logged and the server will continue normal startup.
+
If not specified (default), only the groups listed by All-Projects
-may use the administrateServer capability.
+may use the `administrateServer` capability.
+
+[[capability.makeFirstUserAdmin]]capability.makeFirstUserAdmin::
++
+Whether the first user that logs in to the Gerrit server should
+automatically be added to the administrator group and hence get the
+`administrateServer` capability assigned. This is useful to bootstrap
+the authentication database.
++
+Default is true.
[[change]]
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index be6d025..e4a7218 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -344,6 +344,18 @@
doubt, do not hesitate to ask on the developer
link:https://groups.google.com/forum/#!forum/repo-discuss[mailing list].
+=== Upgrading Libraries
+
+Gerrit's library dependencies should only be upgraded if the new version contains
+something we need in Gerrit. This includes new features, API changes as well as bug
+or security fixes.
+An exception to this rule is that right after a new Gerrit release was branched
+off, all libraries should be upgraded to the latest version to prevent Gerrit
+from falling behind. Doing those upgrades should conclude at the latest two
+months after the branch was cut. This should happen on the master branch to ensure
+that they are vetted long enough before they go into a release and we can be sure
+that the update doesn't introduce a regression.
+
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/WORKSPACE b/WORKSPACE
index 8cb061e..4c89dc7 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1107,6 +1107,13 @@
version = "1.0.0",
)
+bower_archive(
+ name = "polymer-resin",
+ package = "polymer/polymer-resin",
+ sha1 = "4a60925f44d004b593e93aca828918b15b29526b",
+ version = "1.2.1-beta",
+)
+
# bower test stuff
bower_archive(
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index cdb8fbb..877a42a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -323,11 +323,7 @@
String topic = "my/topic";
PushOneCommit.Result r = pushTo("refs/for/master/" + topic + "%cc=" + user.email);
r.assertOkStatus();
- r.assertChange(
- Change.Status.NEW,
- topic,
- ImmutableList.of(),
- ImmutableList.of(user));
+ r.assertChange(Change.Status.NEW, topic, ImmutableList.of(), ImmutableList.of(user));
// cc several users
r =
@@ -343,10 +339,7 @@
r.assertOkStatus();
// Check that admin isn't CC'd as they own the change
r.assertChange(
- Change.Status.NEW,
- topic,
- ImmutableList.of(),
- ImmutableList.of(user, accounts.user2()));
+ Change.Status.NEW, topic, ImmutableList.of(), ImmutableList.of(user, accounts.user2()));
// cc non-existing user
String nonExistingEmail = "non.existing@example.com";
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/AbstractMailIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/AbstractMailIT.java
index 4c38d83..d6ad269 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/AbstractMailIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/AbstractMailIT.java
@@ -132,9 +132,9 @@
+ "> \n";
}
- protected static String textFooterForChange(String changeId, String timestamp) {
- return "Gerrit-Change-Id: "
- + changeId
+ protected static String textFooterForChange(int changeNumber, String timestamp) {
+ return "Gerrit-Change-Number: "
+ + changeNumber
+ "\n"
+ "Gerrit-PatchSet: 1\n"
+ "Gerrit-MessageType: comment\n"
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ListMailFilterIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ListMailFilterIT.java
index 1dcdd97..a96c6ec 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ListMailFilterIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/ListMailFilterIT.java
@@ -113,7 +113,7 @@
null,
null,
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
mailProcessor.process(b.build());
return changeInfo;
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailMetadataIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailMetadataIT.java
index ada222a..7cef8e7 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailMetadataIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailMetadataIT.java
@@ -67,7 +67,8 @@
Map<String, Object> expectedHeaders = new HashMap<>();
expectedHeaders.put("Gerrit-PatchSet", "1");
- expectedHeaders.put("Gerrit-Change-Id", newChange.getChangeId());
+ expectedHeaders.put(
+ "Gerrit-Change-Number", String.valueOf(newChange.getChange().getId().get()));
expectedHeaders.put("Gerrit-MessageType", "newchange");
expectedHeaders.put("Gerrit-Commit", newChange.getCommit().getId().name());
expectedHeaders.put("Gerrit-ChangeURL", changeURL);
@@ -102,7 +103,8 @@
String changeURL = "<" + canonicalWebUrl.get() + newChange.getChange().getId().get() + ">";
Map<String, Object> expectedHeaders = new HashMap<>();
expectedHeaders.put("Gerrit-PatchSet", "1");
- expectedHeaders.put("Gerrit-Change-Id", newChange.getChangeId());
+ expectedHeaders.put(
+ "Gerrit-Change-Number", String.valueOf(newChange.getChange().getId().get()));
expectedHeaders.put("Gerrit-MessageType", "comment");
expectedHeaders.put("Gerrit-Commit", newChange.getCommit().getId().name());
expectedHeaders.put("Gerrit-ChangeURL", changeURL);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
index e7a0cda..9de4797 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/mail/MailProcessorIT.java
@@ -51,7 +51,7 @@
null,
null,
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
mailProcessor.process(b.build());
@@ -79,7 +79,7 @@
"Some Inline Comment",
null,
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
mailProcessor.process(b.build());
@@ -115,7 +115,7 @@
null,
"Some Comment on File 1",
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
mailProcessor.process(b.build());
@@ -152,7 +152,7 @@
"Some Inline Comment",
null,
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
mailProcessor.process(b.build());
comments = gApi.changes().id(changeId).current().commentsAsList();
@@ -183,7 +183,7 @@
"Some Inline Comment",
null,
null);
- b.textContent(txt + textFooterForChange(changeId, ts));
+ b.textContent(txt + textFooterForChange(changeInfo._number, ts));
// Set account state to inactive
gApi.accounts().id("user").setActive(false);
@@ -219,7 +219,7 @@
MailMessage.Builder b =
messageBuilderWithDefaultFields()
.from(user.emailAddress)
- .textContent(txt + textFooterForChange(changeId, ts));
+ .textContent(txt + textFooterForChange(changeInfo._number, ts));
sender.clear();
mailProcessor.process(b.build());
diff --git a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index eed6ccc..7fd3d81 100644
--- a/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/gerrit-httpd/src/main/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -19,6 +19,7 @@
/**
* @param canonicalPath
* @param staticResourcePath
+ * @param? versionInfo
*/
{template .Index autoescape="strict" kind="html"}
<!DOCTYPE html>{\n}
@@ -27,8 +28,11 @@
<meta name="description" content="Gerrit Code Review">{\n}
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n}
- {if $canonicalPath != ''}
- <script>window.CANONICAL_PATH = '{$canonicalPath}';</script>{\n}
+ {if $canonicalPath != '' or $versionInfo}
+ <script>
+ {if $canonicalPath != ''}window.CANONICAL_PATH = '{$canonicalPath}';{/if}
+ {if $versionInfo}window.VERSION_INFO = '{$versionInfo}';{/if}
+ </script>{\n}
{/if}
<link rel="icon" type="image/x-icon" href="{$canonicalPath}/favicon.ico">{\n}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
index 9f2b869..3ff35b3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountManager.java
@@ -30,6 +30,7 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.account.InternalAccountQuery;
import com.google.gwtorm.server.OrmException;
@@ -43,6 +44,7 @@
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,6 +71,7 @@
@Inject
AccountManager(
SchemaFactory<ReviewDb> schema,
+ @GerritServerConfig Config cfg,
Accounts accounts,
AccountsUpdate.Server accountsUpdateFactory,
AccountCache byIdCache,
@@ -90,7 +93,8 @@
this.userFactory = userFactory;
this.changeUserNameFactory = changeUserNameFactory;
this.projectCache = projectCache;
- this.awaitsFirstAccountCheck = new AtomicBoolean(true);
+ this.awaitsFirstAccountCheck =
+ new AtomicBoolean(cfg.getBoolean("capability", "makeFirstUserAdmin", true));
this.auditService = auditService;
this.accountQueryProvider = accountQueryProvider;
this.externalIds = externalIds;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsUpdate.java
index 069380f..54e06de 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsUpdate.java
@@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableSet;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -42,7 +43,12 @@
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
-/** Updates accounts. */
+/**
+ * Updates accounts.
+ *
+ * <p>On updating accounts this class takes care to evict them from the account cache and thus
+ * triggers reindex for them.
+ */
@Singleton
public class AccountsUpdate {
/**
@@ -50,9 +56,6 @@
*
* <p>The Gerrit server identity will be used as author and committer for all commits that update
* the accounts.
- *
- * <p>On updating accounts this class takes care to evict them from the account cache and thus
- * triggers reindex for them.
*/
@Singleton
public static class Server {
@@ -80,6 +83,37 @@
}
/**
+ * Factory to create an AccountsUpdate instance for updating accounts by the Gerrit server.
+ *
+ * <p>Using this class will not perform reindexing for the updated accounts and they will also not
+ * be evicted from the account cache.
+ *
+ * <p>The Gerrit server identity will be used as author and committer for all commits that update
+ * the accounts.
+ */
+ @Singleton
+ public static class ServerNoReindex {
+ private final GitRepositoryManager repoManager;
+ private final AllUsersName allUsersName;
+ private final Provider<PersonIdent> serverIdent;
+
+ @Inject
+ public ServerNoReindex(
+ GitRepositoryManager repoManager,
+ AllUsersName allUsersName,
+ @GerritPersonIdent Provider<PersonIdent> serverIdent) {
+ this.repoManager = repoManager;
+ this.allUsersName = allUsersName;
+ this.serverIdent = serverIdent;
+ }
+
+ public AccountsUpdate create() {
+ PersonIdent i = serverIdent.get();
+ return new AccountsUpdate(repoManager, null, allUsersName, i, i);
+ }
+ }
+
+ /**
* Factory to create an AccountsUpdate instance for updating accounts by the current user.
*
* <p>The identity of the current user will be used as author for all commits that update the
@@ -119,19 +153,19 @@
}
private final GitRepositoryManager repoManager;
- private final AccountCache accountCache;
+ @Nullable private final AccountCache accountCache;
private final AllUsersName allUsersName;
private final PersonIdent committerIdent;
private final PersonIdent authorIdent;
private AccountsUpdate(
GitRepositoryManager repoManager,
- AccountCache accountCache,
+ @Nullable AccountCache accountCache,
AllUsersName allUsersName,
PersonIdent committerIdent,
PersonIdent authorIdent) {
this.repoManager = checkNotNull(repoManager, "repoManager");
- this.accountCache = checkNotNull(accountCache, "accountCache");
+ this.accountCache = accountCache;
this.allUsersName = checkNotNull(allUsersName, "allUsersName");
this.committerIdent = checkNotNull(committerIdent, "committerIdent");
this.authorIdent = checkNotNull(authorIdent, "authorIdent");
@@ -146,7 +180,7 @@
public void insert(ReviewDb db, Account account) throws OrmException, IOException {
db.accounts().insert(ImmutableSet.of(account));
createUserBranch(account);
- accountCache.evict(account.getId());
+ evictAccount(account.getId());
}
/**
@@ -157,13 +191,13 @@
public void upsert(ReviewDb db, Account account) throws OrmException, IOException {
db.accounts().upsert(ImmutableSet.of(account));
createUserBranchIfNeeded(account);
- accountCache.evict(account.getId());
+ evictAccount(account.getId());
}
/** Updates the account. */
public void update(ReviewDb db, Account account) throws OrmException, IOException {
db.accounts().update(ImmutableSet.of(account));
- accountCache.evict(account.getId());
+ evictAccount(account.getId());
}
/**
@@ -185,7 +219,7 @@
consumer.accept(a);
return a;
});
- accountCache.evict(accountId);
+ evictAccount(accountId);
return account;
}
@@ -193,14 +227,14 @@
public void delete(ReviewDb db, Account account) throws OrmException, IOException {
db.accounts().delete(ImmutableSet.of(account));
deleteUserBranch(account.getId());
- accountCache.evict(account.getId());
+ evictAccount(account.getId());
}
/** Deletes the account. */
public void deleteByKey(ReviewDb db, Account.Id accountId) throws OrmException, IOException {
db.accounts().deleteKeys(ImmutableSet.of(accountId));
deleteUserBranch(accountId);
- accountCache.evict(accountId);
+ evictAccount(accountId);
}
private void createUserBranch(Account account) throws IOException {
@@ -294,4 +328,10 @@
throw new IOException(String.format("Failed to delete ref %s: %s", refName, result.name()));
}
}
+
+ private void evictAccount(Account.Id accountId) throws IOException {
+ if (accountCache != null) {
+ accountCache.evict(accountId);
+ }
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdsUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdsUpdate.java
index 9beae0e..2985504 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdsUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdsUpdate.java
@@ -136,6 +136,47 @@
}
/**
+ * Factory to create an ExternalIdsUpdate instance for updating external IDs by the Gerrit server.
+ *
+ * <p>Using this class no reindex will be performed for the affected accounts and they will also
+ * not be evicted from the account cache.
+ *
+ * <p>The Gerrit server identity will be used as author and committer for all commits that update
+ * the external IDs.
+ */
+ @Singleton
+ public static class ServerNoReindex {
+ private final GitRepositoryManager repoManager;
+ private final AllUsersName allUsersName;
+ private final MetricMaker metricMaker;
+ private final ExternalIds externalIds;
+ private final ExternalIdCache externalIdCache;
+ private final Provider<PersonIdent> serverIdent;
+
+ @Inject
+ public ServerNoReindex(
+ GitRepositoryManager repoManager,
+ AllUsersName allUsersName,
+ MetricMaker metricMaker,
+ ExternalIds externalIds,
+ ExternalIdCache externalIdCache,
+ @GerritPersonIdent Provider<PersonIdent> serverIdent) {
+ this.repoManager = repoManager;
+ this.allUsersName = allUsersName;
+ this.metricMaker = metricMaker;
+ this.externalIds = externalIds;
+ this.externalIdCache = externalIdCache;
+ this.serverIdent = serverIdent;
+ }
+
+ public ExternalIdsUpdate create() {
+ PersonIdent i = serverIdent.get();
+ return new ExternalIdsUpdate(
+ repoManager, null, allUsersName, metricMaker, externalIds, externalIdCache, i, i);
+ }
+ }
+
+ /**
* Factory to create an ExternalIdsUpdate instance for updating external IDs by the current user.
*
* <p>The identity of the current user will be used as author for all commits that update the
@@ -204,7 +245,7 @@
private static final Retryer<RefsMetaExternalIdsUpdate> RETRYER = retryerBuilder().build();
private final GitRepositoryManager repoManager;
- private final AccountCache accountCache;
+ @Nullable private final AccountCache accountCache;
private final AllUsersName allUsersName;
private final ExternalIds externalIds;
private final ExternalIdCache externalIdCache;
@@ -216,7 +257,7 @@
private ExternalIdsUpdate(
GitRepositoryManager repoManager,
- AccountCache accountCache,
+ @Nullable AccountCache accountCache,
AllUsersName allUsersName,
MetricMaker metricMaker,
ExternalIds externalIds,
@@ -239,7 +280,7 @@
@VisibleForTesting
public ExternalIdsUpdate(
GitRepositoryManager repoManager,
- AccountCache accountCache,
+ @Nullable AccountCache accountCache,
AllUsersName allUsersName,
MetricMaker metricMaker,
ExternalIds externalIds,
@@ -375,7 +416,7 @@
}
});
externalIdCache.onRemoveByKeys(u.oldRev(), u.newRev(), accountId, extIdKeys);
- accountCache.evict(accountId);
+ evictAccount(accountId);
}
/**
@@ -434,7 +475,7 @@
}
});
externalIdCache.onReplaceByKeys(u.oldRev(), u.newRev(), accountId, toDelete, toAdd);
- accountCache.evict(accountId);
+ evictAccount(accountId);
}
/**
@@ -726,7 +767,17 @@
return ins.insert(OBJ_TREE, new byte[] {});
}
+ private void evictAccount(Account.Id accountId) throws IOException {
+ if (accountCache != null) {
+ accountCache.evict(accountId);
+ }
+ }
+
private void evictAccounts(Collection<ExternalId> extIds) throws IOException {
+ if (accountCache == null) {
+ return;
+ }
+
for (Account.Id id : extIds.stream().map(ExternalId::accountId).collect(toSet())) {
accountCache.evict(id);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MetadataName.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MetadataName.java
index 3db55c0..3080e4f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/MetadataName.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/MetadataName.java
@@ -15,7 +15,7 @@
package com.google.gerrit.server.mail;
public final class MetadataName {
- public static final String CHANGE_ID = "Gerrit-Change-Id";
+ public static final String CHANGE_NUMBER = "Gerrit-Change-Number";
public static final String PATCH_SET = "Gerrit-PatchSet";
public static final String MESSAGE_TYPE = "Gerrit-MessageType";
public static final String TIMESTAMP = "Gerrit-Comment-Date";
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailMetadata.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailMetadata.java
index f85291c..04c2add 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailMetadata.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailMetadata.java
@@ -19,14 +19,14 @@
/** MailMetadata represents metadata parsed from inbound email. */
public class MailMetadata {
- public String changeId;
+ public Integer changeNumber;
public Integer patchSet;
public String author; // Author of the email
public Timestamp timestamp;
public String messageType; // we expect comment here
public boolean hasRequiredFields() {
- return changeId != null
+ return changeNumber != null
&& patchSet != null
&& author != null
&& timestamp != null
@@ -36,7 +36,7 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
- .add("Change-Id", changeId)
+ .add("Change-Number", changeNumber)
.add("Patch-Set", patchSet)
.add("Author", author)
.add("Timestamp", timestamp)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
index 0c2cf04..7ad282b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
@@ -169,12 +169,12 @@
try (ManualRequestContext ctx = oneOffRequestContext.openAs(account)) {
List<ChangeData> changeDataList =
- queryProvider.get().byKey(Change.Key.parse(metadata.changeId));
+ queryProvider.get().byLegacyChangeId(new Change.Id(metadata.changeNumber));
if (changeDataList.size() != 1) {
log.error(
String.format(
"Message %s references unique change %s, but there are %d matching changes in the index. Will delete message.",
- message.id(), metadata.changeId, changeDataList.size()));
+ message.id(), metadata.changeNumber, changeDataList.size()));
return;
}
ChangeData cd = changeDataList.get(0);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MetadataParser.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MetadataParser.java
index a18da68..7085051 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MetadataParser.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MetadataParser.java
@@ -38,9 +38,9 @@
// Check email headers for X-Gerrit-<Name>
for (String header : m.additionalHeaders()) {
- if (header.startsWith(toHeaderWithDelimiter(MetadataName.CHANGE_ID))) {
- metadata.changeId =
- header.substring(toHeaderWithDelimiter(MetadataName.CHANGE_ID).length());
+ if (header.startsWith(toHeaderWithDelimiter(MetadataName.CHANGE_NUMBER))) {
+ String num = header.substring(toHeaderWithDelimiter(MetadataName.CHANGE_NUMBER).length());
+ metadata.changeNumber = Ints.tryParse(num);
} else if (header.startsWith(toHeaderWithDelimiter(MetadataName.PATCH_SET))) {
String ps = header.substring(toHeaderWithDelimiter(MetadataName.PATCH_SET).length());
metadata.patchSet = Ints.tryParse(ps);
@@ -84,8 +84,9 @@
private static void extractFooters(String[] lines, MailMetadata metadata, MailMessage m) {
for (String line : lines) {
- if (metadata.changeId == null && line.contains(MetadataName.CHANGE_ID)) {
- metadata.changeId = extractFooter(toFooterWithDelimiter(MetadataName.CHANGE_ID), line);
+ if (metadata.changeNumber == null && line.contains(MetadataName.CHANGE_NUMBER)) {
+ metadata.changeNumber =
+ Ints.tryParse(extractFooter(toFooterWithDelimiter(MetadataName.CHANGE_NUMBER), line));
} else if (metadata.patchSet == null && line.contains(MetadataName.PATCH_SET)) {
metadata.patchSet =
Ints.tryParse(extractFooter(toFooterWithDelimiter(MetadataName.PATCH_SET), line));
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
index 0c4507e..84bae96 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/mail/receive/MetadataParserTest.java
@@ -34,7 +34,7 @@
b.dateReceived(new DateTime());
b.subject("");
- b.addAdditionalHeader(toHeaderWithDelimiter(MetadataName.CHANGE_ID) + "cid");
+ b.addAdditionalHeader(toHeaderWithDelimiter(MetadataName.CHANGE_NUMBER) + "123");
b.addAdditionalHeader(toHeaderWithDelimiter(MetadataName.PATCH_SET) + "1");
b.addAdditionalHeader(toHeaderWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment");
b.addAdditionalHeader(
@@ -45,7 +45,7 @@
MailMetadata meta = MetadataParser.parse(b.build());
assertThat(meta.author).isEqualTo(author.getEmail());
- assertThat(meta.changeId).isEqualTo("cid");
+ assertThat(meta.changeNumber).isEqualTo(123);
assertThat(meta.patchSet).isEqualTo(1);
assertThat(meta.messageType).isEqualTo("comment");
assertThat(meta.timestamp.getTime())
@@ -62,7 +62,7 @@
b.subject("");
StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid\r\n");
+ stringBuilder.append(toFooterWithDelimiter(MetadataName.CHANGE_NUMBER) + "123\r\n");
stringBuilder.append("> " + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1\n");
stringBuilder.append(toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment\n");
stringBuilder.append(
@@ -74,7 +74,7 @@
MailMetadata meta = MetadataParser.parse(b.build());
assertThat(meta.author).isEqualTo(author.getEmail());
- assertThat(meta.changeId).isEqualTo("cid");
+ assertThat(meta.changeNumber).isEqualTo(123);
assertThat(meta.patchSet).isEqualTo(1);
assertThat(meta.messageType).isEqualTo("comment");
assertThat(meta.timestamp.getTime())
@@ -92,7 +92,7 @@
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
- "<div id\"someid\">" + toFooterWithDelimiter(MetadataName.CHANGE_ID) + "cid</div>");
+ "<div id\"someid\">" + toFooterWithDelimiter(MetadataName.CHANGE_NUMBER) + "123</div>");
stringBuilder.append("<div>" + toFooterWithDelimiter(MetadataName.PATCH_SET) + "1</div>");
stringBuilder.append(
"<div>" + toFooterWithDelimiter(MetadataName.MESSAGE_TYPE) + "comment</div>");
@@ -108,7 +108,7 @@
MailMetadata meta = MetadataParser.parse(b.build());
assertThat(meta.author).isEqualTo(author.getEmail());
- assertThat(meta.changeId).isEqualTo("cid");
+ assertThat(meta.changeNumber).isEqualTo(123);
assertThat(meta.patchSet).isEqualTo(1);
assertThat(meta.messageType).isEqualTo("comment");
assertThat(meta.timestamp.getTime())
diff --git a/lib/js/bower_components.bzl b/lib/js/bower_components.bzl
index bb047bd70..9c3c63b 100644
--- a/lib/js/bower_components.bzl
+++ b/lib/js/bower_components.bzl
@@ -168,6 +168,15 @@
seed = True,
)
bower_component(
+ name = "polymer-resin",
+ license = "//lib:LICENSE-polymer",
+ deps = [
+ ":polymer",
+ ":webcomponentsjs",
+ ],
+ seed = True,
+ )
+ bower_component(
name = "polymer",
license = "//lib:LICENSE-polymer",
deps = [ ":webcomponentsjs" ],
diff --git a/polygerrit-ui/BUILD b/polygerrit-ui/BUILD
index 1f11cde..1b58a90 100644
--- a/polygerrit-ui/BUILD
+++ b/polygerrit-ui/BUILD
@@ -21,6 +21,7 @@
"//lib/js:moment",
"//lib/js:page",
"//lib/js:polymer",
+ "//lib/js:polymer-resin",
"//lib/js:promise-polyfill",
],
)
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
index 8b969f7..fad9baf 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
@@ -22,7 +22,7 @@
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-admin-group-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index 81135ae..c0371ee 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -246,7 +246,7 @@
as="file"
initial-count="[[fileListIncrement]]"
target-framerate="1">
- <div class="file-row row" data-path$="[[file.__path]]">
+ <div class="file-row row" data-path$="[[file.__path]]" tabindex="-1">
<div class="reviewed" hidden$="[[!_loggedIn]]" hidden>
<input type="checkbox" checked="[[file.isReviewed]]"
class="reviewed" aria-label="Reviewed checkbox">
@@ -401,6 +401,7 @@
<gr-cursor-manager
id="fileCursor"
scroll-behavior="keep-visible"
+ focus-on-move
cursor-target-class="selected"></gr-cursor-manager>
<gr-reporting id="reporting"></gr-reporting>
</template>
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
index 7621a9d..0bcd9fd 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -135,7 +135,7 @@
'c': '_handleCKey',
'[': '_handleLeftBracketKey',
']': '_handleRightBracketKey',
- 'o enter': '_handleEnterKey',
+ 'o': '_handleOKey',
'n': '_handleNKey',
'p': '_handlePKey',
'shift+a': '_handleCapitalAKey',
@@ -537,14 +537,10 @@
this._openSelectedFile(0);
},
- _handleEnterKey(e) {
+ _handleOKey(e) {
if (this.shouldSuppressKeyboardShortcut(e) ||
this.modifierPressed(e)) { return; }
- // Use native handling if an anchor is selected. @see Issue 5754
- if (e.detail && e.detail.keyboardEvent && e.detail.keyboardEvent.target &&
- e.detail.keyboardEvent.target.tagName === 'A') { return; }
-
e.preventDefault();
if (this._showInlineDiffs) {
this._openCursorFile();
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index f0f5403..4577a05 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -331,9 +331,7 @@
const showStub = sandbox.stub(page, 'show');
assert.equal(element.$.fileCursor.index, 2);
assert.equal(element.selectedIndex, 2);
- MockInteractions.pressAndReleaseKeyOn(element, 13, null, 'enter');
- assert(showStub.lastCall.calledWith('/c/42/2/myfile.txt'),
- 'Should navigate to /c/42/2/myfile.txt');
+
// k with a modifier should not move the cursor.
MockInteractions.pressAndReleaseKeyOn(element, 75, 'shift', 'k');
assert.equal(element.$.fileCursor.index, 2);
@@ -384,7 +382,7 @@
}
});
- suite('_handleEnterKey', () => {
+ suite('_handleOKey', () => {
let interact;
setup(() => {
@@ -402,7 +400,7 @@
const e = new CustomEvent('fake-keyboard-event', opt_payload);
sinon.stub(e, 'preventDefault');
- element._handleEnterKey(e);
+ element._handleOKey(e);
assert.isTrue(e.preventDefault.called);
const result = {};
if (openCursorStub.called) {
@@ -440,14 +438,6 @@
element._userPrefs.expand_inline_diffs = true;
assert.deepEqual(interact(), {expanded: true});
});
-
- test('noop when anchor focused', () => {
- const e = new CustomEvent('fake-keyboard-event',
- {detail: {keyboardEvent: {target: document.createElement('a')}}});
- sinon.stub(e, 'preventDefault');
- element._handleEnterKey(e);
- assert.isFalse(e.preventDefault.called);
- });
});
});
@@ -1242,4 +1232,6 @@
assert.isFalse(element._displayLine);
});
});
+
+ a11ySuite('basic');
</script>
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
index b96f684..4245cf5 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
@@ -21,7 +21,7 @@
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-label-score-row.html">
<script>void(0);</script>
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
index f4e26d3..e76a9e5 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
@@ -22,7 +22,6 @@
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="../../plugins/gr-plugin-host/gr-plugin-host.html">
<link rel="import" href="gr-reply-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
index eadf667..6aea989 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
@@ -96,6 +96,12 @@
min-height: 6em;
position: relative;
}
+ .textareaContainer,
+ #textarea,
+ gr-endpoint-decorator {
+ display: flex;
+ width: 100%;
+ }
.previewContainer gr-formatted-text {
background: #f6f6f6;
max-height: 20vh;
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
index 1396a2b..fef0f87 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
@@ -231,7 +231,7 @@
<td>Select previous file</td>
</tr>
<tr>
- <td><span class="key">Enter</span> or <span class="key">o</span></td>
+ <td><span class="key">o</span></td>
<td>Show selected file</td>
</tr>
<tr>
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 a61b9ca..84d9783 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
@@ -110,6 +110,7 @@
}
.contextLineNum:before,
.lineNum:before {
+ box-sizing: border-box;
display: inline-block;
color: #666;
content: attr(data-value);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
index 1c0f05e..e7b81be 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
@@ -992,4 +992,6 @@
});
});
});
+
+ a11ySuite('basic');
</script>
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
index 10ef4e1..d8e2ee0 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
@@ -21,7 +21,7 @@
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-list-view.html">
<script>void(0);</script>
diff --git a/polygerrit-ui/app/test/common-test-setup.html b/polygerrit-ui/app/test/common-test-setup.html
index 00bd1e7..9e277ab 100644
--- a/polygerrit-ui/app/test/common-test-setup.html
+++ b/polygerrit-ui/app/test/common-test-setup.html
@@ -16,4 +16,10 @@
-->
<link rel="import"
+ href="../bower_components/polymer-resin/standalone/polymer-resin-debug.html"
+ />
+<script>
+security.polymer_resin.install({allowedIdentifierPrefixes: ['']});
+</script>
+<link rel="import"
href="../bower_components/iron-test-helpers/iron-test-helpers.html" />