Merge "Fix 'press c to comment' on first line of diff"
diff --git a/.gitignore b/.gitignore
index 06a6e66..0e954ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,4 @@
/plugins/cookbook-plugin/
/test_site
/tools/format
+/.vscode
\ No newline at end of file
diff --git a/Documentation/pg-plugin-endpoints.txt b/Documentation/pg-plugin-endpoints.txt
index 45c6e72..8ae25fd 100644
--- a/Documentation/pg-plugin-endpoints.txt
+++ b/Documentation/pg-plugin-endpoints.txt
@@ -1,7 +1,5 @@
= Gerrit Code Review - PolyGerrit Plugin Styling
-== Plugin endpoints
-
Plugin should be html-based and imported following PolyGerrit's
link:pg-plugin-dev.html#loading[dev guide].
@@ -20,6 +18,23 @@
});
```
+== Default parameters
+All endpoints receive the following params, set as attributes to custom components
+that are instantiated at the endpoint:
+
+* `plugin`
++
+the current plugin instance, the one that is used by `Gerrit.install()`.
+
+* `content`
++
+decorated DOM Element, is only set for registrations that decorate existing
+components.
+
+== Plugin endpoints
+
+Following endpoints are available to plugins
+
=== change-view-integration
Extension point is located between `Files` and `Messages` section on the change
view page, and it may take full page's width. Primary purpose is to enable
@@ -30,3 +45,10 @@
`Label Status` and `Links` sections. It's width is equal to the left panel's and
primary purpose is to enable plugins to add sections of metadata to the left
panel.
+
+In addition to default parameters, the following are available:
+
+* `change`
++
+current change displayed, an instance of
+link:rest-api-changes.html#change-info[ChangeInfo]
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index e059671..732c1f7 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -23,7 +23,6 @@
"//java/com/google/gerrit/pgm/util",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
- "//java/com/google/gerrit/server/diff",
"//java/com/google/gerrit/server/git/receive",
"//java/com/google/gerrit/server/project/testing:project-test-util",
"//java/com/google/gerrit/sshd",
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index 636e909..b29922f 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -34,6 +34,7 @@
import com.google.gerrit.server.util.SocketUtil;
import com.google.gerrit.server.util.SystemLog;
import com.google.gerrit.testing.FakeEmailSender;
+import com.google.gerrit.testing.GroupNoteDbMode;
import com.google.gerrit.testing.NoteDbChecker;
import com.google.gerrit.testing.NoteDbMode;
import com.google.gerrit.testing.SshMode;
@@ -391,6 +392,7 @@
cfg.setBoolean("index", null, "reindexAfterRefUpdate", false);
NoteDbMode.newNotesMigrationFromEnv().setConfigValues(cfg);
+ GroupNoteDbMode.get().getGroupsMigration().setConfigValuesIfNotSetYet(cfg);
}
private static Injector createTestInjector(Daemon daemon) throws Exception {
diff --git a/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java b/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
index 3f2cbda..4b1211b 100644
--- a/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
+++ b/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
@@ -28,6 +28,7 @@
import com.google.gerrit.server.config.TrackingFootersProvider;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeBundleReader;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.GwtormChangeBundleReader;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.schema.DataSourceType;
@@ -78,6 +79,7 @@
bind(DataSourceType.class).to(InMemoryH2Type.class);
install(new NotesMigration.Module());
+ install(new GroupsMigration.Module());
TypeLiteral<SchemaFactory<ReviewDb>> schemaFactory =
new TypeLiteral<SchemaFactory<ReviewDb>>() {};
bind(schemaFactory).to(NotesMigrationSchemaFactory.class);
diff --git a/java/com/google/gerrit/httpd/init/WebAppInitializer.java b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
index b7ec467..b5995a8 100644
--- a/java/com/google/gerrit/httpd/init/WebAppInitializer.java
+++ b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
@@ -71,6 +71,7 @@
import com.google.gerrit.server.mail.receive.MailReceiver;
import com.google.gerrit.server.mail.send.SmtpEmailSender;
import com.google.gerrit.server.mime.MimeUtil2Module;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.patch.DiffExecutorModule;
import com.google.gerrit.server.plugins.PluginGuiceEnvironment;
@@ -307,6 +308,7 @@
}
modules.add(new DatabaseModule());
modules.add(new NotesMigration.Module());
+ modules.add(new GroupsMigration.Module());
modules.add(new DropWizardMetricMaker.ApiModule());
return Guice.createInjector(PRODUCTION, modules);
}
diff --git a/java/com/google/gerrit/pgm/init/GroupsOnInit.java b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
index e6f05cf..3385244 100644
--- a/java/com/google/gerrit/pgm/init/GroupsOnInit.java
+++ b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
@@ -42,6 +42,7 @@
import com.google.gerrit.server.group.db.GroupNameNotes;
import com.google.gerrit.server.group.db.Groups;
import com.google.gerrit.server.group.db.InternalGroupUpdate;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -72,20 +73,14 @@
private final InitFlags flags;
private final SitePaths site;
private final String allUsers;
- private final boolean readFromNoteDb;
- private final boolean writeGroupsToNoteDb;
+ private final GroupsMigration groupsMigration;
@Inject
public GroupsOnInit(InitFlags flags, SitePaths site, AllUsersNameOnInitProvider allUsers) {
this.flags = flags;
this.site = site;
this.allUsers = allUsers.get();
- readFromNoteDb = flags.cfg.getBoolean("user", null, "readGroupsFromNoteDb", false);
- // TODO(aliceks): Remove this flag when all other necessary TODOs for writing groups to NoteDb
- // have been addressed.
- // Don't flip this flag in a production setting! We only added it to spread the implementation
- // of groups in NoteDb among several changes which are gradually merged.
- writeGroupsToNoteDb = flags.cfg.getBoolean("user", null, "writeGroupsToNoteDb", false);
+ this.groupsMigration = new GroupsMigration(flags.cfg);
}
/**
@@ -101,7 +96,7 @@
*/
public InternalGroup getExistingGroup(ReviewDb db, GroupReference groupReference)
throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
- if (readFromNoteDb) {
+ if (groupsMigration.readFromNoteDb()) {
return getExistingGroupFromNoteDb(groupReference);
}
@@ -151,7 +146,7 @@
*/
public Stream<GroupReference> getAllGroupReferences(ReviewDb db)
throws OrmException, IOException, ConfigInvalidException {
- if (readFromNoteDb) {
+ if (groupsMigration.readFromNoteDb()) {
File allUsersRepoPath = getPathToAllUsersRepository();
if (allUsersRepoPath != null) {
try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
@@ -181,7 +176,7 @@
public void addGroupMember(ReviewDb db, AccountGroup.UUID groupUuid, Account account)
throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
addGroupMemberInReviewDb(db, groupUuid, account.getId());
- if (!writeGroupsToNoteDb) {
+ if (!groupsMigration.writeToNoteDb()) {
return;
}
addGroupMemberInNoteDb(groupUuid, account);
diff --git a/java/com/google/gerrit/pgm/util/SiteProgram.java b/java/com/google/gerrit/pgm/util/SiteProgram.java
index b59e085..afabcf6 100644
--- a/java/com/google/gerrit/pgm/util/SiteProgram.java
+++ b/java/com/google/gerrit/pgm/util/SiteProgram.java
@@ -28,6 +28,7 @@
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.git.GitRepositoryManagerModule;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.schema.DataSourceModule;
import com.google.gerrit.server.schema.DataSourceProvider;
@@ -183,6 +184,7 @@
modules.add(new SchemaModule());
modules.add(cfgInjector.getInstance(GitRepositoryManagerModule.class));
modules.add(new NotesMigration.Module());
+ modules.add(new GroupsMigration.Module());
try {
return Guice.createInjector(PRODUCTION, modules);
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroup.java b/java/com/google/gerrit/reviewdb/client/AccountGroup.java
index 2dd5b36..c7dc420 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroup.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroup.java
@@ -286,4 +286,25 @@
return Objects.hash(
name, groupId, description, visibleToAll, groupUUID, ownerGroupUUID, createdOn);
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()
+ + "{"
+ + "name="
+ + name
+ + ", groupId="
+ + groupId
+ + ", description="
+ + description
+ + ", visibleToAll="
+ + visibleToAll
+ + ", groupUUID="
+ + groupUUID
+ + ", ownerGroupUUID="
+ + ownerGroupUUID
+ + ", createdOn="
+ + createdOn
+ + "}";
+ }
}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupById.java b/java/com/google/gerrit/reviewdb/client/AccountGroupById.java
index 30ca38f..17a205e 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupById.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupById.java
@@ -88,4 +88,9 @@
public int hashCode() {
return key.hashCode();
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{key=" + key + "}";
+ }
}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java b/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java
index 33955c4..5246d72 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java
@@ -142,4 +142,19 @@
public int hashCode() {
return Objects.hash(key, addedBy, removedBy, removedOn);
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()
+ + "{"
+ + "key="
+ + key
+ + ", addedBy="
+ + addedBy
+ + ", removedBy="
+ + removedBy
+ + ", removedOn="
+ + removedOn
+ + "}";
+ }
}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java b/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java
index ea46366..e1e0754 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java
@@ -84,4 +84,9 @@
public int hashCode() {
return key.hashCode();
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{key=" + key + "}";
+ }
}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java b/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
index 9968b7d..4ea19d2 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
@@ -147,4 +147,19 @@
public int hashCode() {
return Objects.hash(key, addedBy, removedBy, removedOn);
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName()
+ + "{"
+ + "key="
+ + key
+ + ", addedBy="
+ + addedBy
+ + ", removedBy="
+ + removedBy
+ + ", removedOn="
+ + removedOn
+ + "}";
+ }
}
diff --git a/java/com/google/gerrit/reviewdb/server/DisallowReadFromGroupsReviewDbWrapper.java b/java/com/google/gerrit/reviewdb/server/DisallowReadFromGroupsReviewDbWrapper.java
new file mode 100644
index 0000000..640924c
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/server/DisallowReadFromGroupsReviewDbWrapper.java
@@ -0,0 +1,310 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.reviewdb.server;
+
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupById;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupMember;
+import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
+import com.google.gerrit.reviewdb.client.AccountGroupName;
+import com.google.gwtorm.server.OrmException;
+import com.google.gwtorm.server.ResultSet;
+
+public class DisallowReadFromGroupsReviewDbWrapper extends ReviewDbWrapper {
+ private static final String MSG = "This table has been migrated to NoteDb";
+
+ private final Groups groups;
+ private final GroupNames groupNames;
+ private final GroupMembers groupMembers;
+ private final GroupMemberAudits groupMemberAudits;
+ private final ByIds byIds;
+ private final ByIdAudits byIdAudits;
+
+ public DisallowReadFromGroupsReviewDbWrapper(ReviewDb db) {
+ super(db);
+ groups = new Groups(delegate.accountGroups());
+ groupNames = new GroupNames(delegate.accountGroupNames());
+ groupMembers = new GroupMembers(delegate.accountGroupMembers());
+ groupMemberAudits = new GroupMemberAudits(delegate.accountGroupMembersAudit());
+ byIds = new ByIds(delegate.accountGroupById());
+ byIdAudits = new ByIdAudits(delegate.accountGroupByIdAud());
+ }
+
+ public ReviewDb unsafeGetDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public AccountGroupAccess accountGroups() {
+ return groups;
+ }
+
+ @Override
+ public AccountGroupNameAccess accountGroupNames() {
+ return groupNames;
+ }
+
+ @Override
+ public AccountGroupMemberAccess accountGroupMembers() {
+ return groupMembers;
+ }
+
+ @Override
+ public AccountGroupMemberAuditAccess accountGroupMembersAudit() {
+ return groupMemberAudits;
+ }
+
+ @Override
+ public AccountGroupByIdAccess accountGroupById() {
+ return byIds;
+ }
+
+ @Override
+ public AccountGroupByIdAudAccess accountGroupByIdAud() {
+ return byIdAudits;
+ }
+
+ private static class Groups extends AccountGroupAccessWrapper {
+ protected Groups(AccountGroupAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroup, OrmException> getAsync(
+ AccountGroup.Id key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> get(Iterable<AccountGroup.Id> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroup get(AccountGroup.Id id) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> byUUID(AccountGroup.UUID uuid) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> all() {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+
+ private static class GroupNames extends AccountGroupNameAccessWrapper {
+ protected GroupNames(AccountGroupNameAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupName, OrmException> getAsync(
+ AccountGroup.NameKey key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> get(Iterable<AccountGroup.NameKey> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroupName get(AccountGroup.NameKey name) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> all() {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+
+ private static class GroupMembers extends AccountGroupMemberAccessWrapper {
+ protected GroupMembers(AccountGroupMemberAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupMember, OrmException>
+ getAsync(AccountGroupMember.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> get(Iterable<AccountGroupMember.Key> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroupMember get(AccountGroupMember.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> byAccount(Account.Id id) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> byGroup(AccountGroup.Id id) {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+
+ private static class GroupMemberAudits extends AccountGroupMemberAuditAccessWrapper {
+ protected GroupMemberAudits(AccountGroupMemberAuditAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupMemberAudit, OrmException>
+ getAsync(AccountGroupMemberAudit.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> get(Iterable<AccountGroupMemberAudit.Key> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroupMemberAudit get(AccountGroupMemberAudit.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> byGroupAccount(
+ AccountGroup.Id groupId, Account.Id accountId) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> byGroup(AccountGroup.Id groupId) {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+
+ private static class ByIds extends AccountGroupByIdAccessWrapper {
+ protected ByIds(AccountGroupByIdAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupById, OrmException> getAsync(
+ AccountGroupById.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> get(Iterable<AccountGroupById.Key> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroupById get(AccountGroupById.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> byIncludeUUID(AccountGroup.UUID uuid) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> byGroup(AccountGroup.Id id) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> all() {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+
+ private static class ByIdAudits extends AccountGroupByIdAudAccessWrapper {
+ protected ByIdAudits(AccountGroupByIdAudAccess delegate) {
+ super(delegate);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> iterateAllEntities() {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupByIdAud, OrmException>
+ getAsync(AccountGroupByIdAud.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> get(Iterable<AccountGroupByIdAud.Key> keys) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public AccountGroupByIdAud get(AccountGroupByIdAud.Key key) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> byGroupInclude(
+ AccountGroup.Id groupId, AccountGroup.UUID incGroupUUID) {
+ throw new UnsupportedOperationException(MSG);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> byGroup(AccountGroup.Id groupId) {
+ throw new UnsupportedOperationException(MSG);
+ }
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDbUtil.java b/java/com/google/gerrit/reviewdb/server/ReviewDbUtil.java
index bb31b1c..ef057eb 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDbUtil.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDbUtil.java
@@ -14,8 +14,16 @@
package com.google.gerrit.reviewdb.server;
+import static com.google.common.base.Preconditions.checkState;
+
import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.IntKey;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
/** Static utilities for ReviewDb types. */
public class ReviewDbUtil {
@@ -43,10 +51,30 @@
public static ReviewDb unwrapDb(ReviewDb db) {
if (db instanceof DisallowReadFromChangesReviewDbWrapper) {
- return ((DisallowReadFromChangesReviewDbWrapper) db).unsafeGetDelegate();
+ return unwrapDb(((DisallowReadFromChangesReviewDbWrapper) db).unsafeGetDelegate());
+ }
+ if (db instanceof DisallowReadFromGroupsReviewDbWrapper) {
+ return unwrapDb(((DisallowReadFromGroupsReviewDbWrapper) db).unsafeGetDelegate());
}
return db;
}
+ public static void checkColumns(Class<?> clazz, Integer... expected) {
+ Set<Integer> ids = new TreeSet<>();
+ for (Field f : clazz.getDeclaredFields()) {
+ Column col = f.getAnnotation(Column.class);
+ if (col != null) {
+ ids.add(col.id());
+ }
+ }
+ Set<Integer> expectedIds = Sets.newTreeSet(Arrays.asList(expected));
+ checkState(
+ ids.equals(expectedIds),
+ "Unexpected column set for %s: %s != %s",
+ clazz.getSimpleName(),
+ ids,
+ expectedIds);
+ }
+
private ReviewDbUtil() {}
}
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
index 7fd2c73..efc8a01 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
@@ -17,6 +17,12 @@
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupById;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupMember;
+import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
+import com.google.gerrit.reviewdb.client.AccountGroupName;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchLineComment;
@@ -679,4 +685,591 @@
return delegate.all();
}
}
+
+ public static class AccountGroupAccessWrapper implements AccountGroupAccess {
+ protected final AccountGroupAccess delegate;
+
+ protected AccountGroupAccessWrapper(AccountGroupAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroup> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroup.Id primaryKey(AccountGroup entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroup.Id, AccountGroup> toMap(Iterable<AccountGroup> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroup, OrmException> getAsync(
+ AccountGroup.Id key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> get(Iterable<AccountGroup.Id> keys) throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroup> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroup> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroup> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroup.Id> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroup> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroup.Id key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroup atomicUpdate(AccountGroup.Id key, AtomicUpdate<AccountGroup> update)
+ throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroup get(AccountGroup.Id id) throws OrmException {
+ return delegate.get(id);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> byUUID(AccountGroup.UUID uuid) throws OrmException {
+ return delegate.byUUID(uuid);
+ }
+
+ @Override
+ public ResultSet<AccountGroup> all() throws OrmException {
+ return delegate.all();
+ }
+ }
+
+ public static class AccountGroupNameAccessWrapper implements AccountGroupNameAccess {
+ protected final AccountGroupNameAccess delegate;
+
+ protected AccountGroupNameAccessWrapper(AccountGroupNameAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroup.NameKey primaryKey(AccountGroupName entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroup.NameKey, AccountGroupName> toMap(Iterable<AccountGroupName> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupName, OrmException> getAsync(
+ AccountGroup.NameKey key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> get(Iterable<AccountGroup.NameKey> keys)
+ throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroupName> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroupName> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroupName> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroup.NameKey> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroupName> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroup.NameKey key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroupName atomicUpdate(
+ AccountGroup.NameKey key, AtomicUpdate<AccountGroupName> update) throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroupName get(AccountGroup.NameKey name) throws OrmException {
+ return delegate.get(name);
+ }
+
+ @Override
+ public ResultSet<AccountGroupName> all() throws OrmException {
+ return delegate.all();
+ }
+ }
+
+ public static class AccountGroupMemberAccessWrapper implements AccountGroupMemberAccess {
+ protected final AccountGroupMemberAccess delegate;
+
+ protected AccountGroupMemberAccessWrapper(AccountGroupMemberAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroupMember.Key primaryKey(AccountGroupMember entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroupMember.Key, AccountGroupMember> toMap(Iterable<AccountGroupMember> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupMember, OrmException>
+ getAsync(AccountGroupMember.Key key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> get(Iterable<AccountGroupMember.Key> keys)
+ throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroupMember> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroupMember> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroupMember> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroupMember.Key> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroupMember> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroupMember.Key key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroupMember atomicUpdate(
+ AccountGroupMember.Key key, AtomicUpdate<AccountGroupMember> update) throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroupMember get(AccountGroupMember.Key key) throws OrmException {
+ return delegate.get(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> byAccount(Account.Id id) throws OrmException {
+ return delegate.byAccount(id);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMember> byGroup(AccountGroup.Id id) throws OrmException {
+ return delegate.byGroup(id);
+ }
+ }
+
+ public static class AccountGroupMemberAuditAccessWrapper
+ implements AccountGroupMemberAuditAccess {
+ protected final AccountGroupMemberAuditAccess delegate;
+
+ protected AccountGroupMemberAuditAccessWrapper(AccountGroupMemberAuditAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroupMemberAudit.Key primaryKey(AccountGroupMemberAudit entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroupMemberAudit.Key, AccountGroupMemberAudit> toMap(
+ Iterable<AccountGroupMemberAudit> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupMemberAudit, OrmException>
+ getAsync(AccountGroupMemberAudit.Key key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> get(Iterable<AccountGroupMemberAudit.Key> keys)
+ throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroupMemberAudit> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroupMemberAudit> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroupMemberAudit> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroupMemberAudit.Key> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroupMemberAudit> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroupMemberAudit.Key key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroupMemberAudit atomicUpdate(
+ AccountGroupMemberAudit.Key key, AtomicUpdate<AccountGroupMemberAudit> update)
+ throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroupMemberAudit get(AccountGroupMemberAudit.Key key) throws OrmException {
+ return delegate.get(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> byGroupAccount(
+ AccountGroup.Id groupId, Account.Id accountId) throws OrmException {
+ return delegate.byGroupAccount(groupId, accountId);
+ }
+
+ @Override
+ public ResultSet<AccountGroupMemberAudit> byGroup(AccountGroup.Id groupId) throws OrmException {
+ return delegate.byGroup(groupId);
+ }
+ }
+
+ public static class AccountGroupByIdAccessWrapper implements AccountGroupByIdAccess {
+ protected final AccountGroupByIdAccess delegate;
+
+ protected AccountGroupByIdAccessWrapper(AccountGroupByIdAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroupById.Key primaryKey(AccountGroupById entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroupById.Key, AccountGroupById> toMap(Iterable<AccountGroupById> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupById, OrmException> getAsync(
+ AccountGroupById.Key key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> get(Iterable<AccountGroupById.Key> keys)
+ throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroupById> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroupById> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroupById> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroupById.Key> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroupById> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroupById.Key key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroupById atomicUpdate(
+ AccountGroupById.Key key, AtomicUpdate<AccountGroupById> update) throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroupById get(AccountGroupById.Key key) throws OrmException {
+ return delegate.get(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> byIncludeUUID(AccountGroup.UUID uuid) throws OrmException {
+ return delegate.byIncludeUUID(uuid);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> byGroup(AccountGroup.Id id) throws OrmException {
+ return delegate.byGroup(id);
+ }
+
+ @Override
+ public ResultSet<AccountGroupById> all() throws OrmException {
+ return delegate.all();
+ }
+ }
+
+ public static class AccountGroupByIdAudAccessWrapper implements AccountGroupByIdAudAccess {
+ protected final AccountGroupByIdAudAccess delegate;
+
+ protected AccountGroupByIdAudAccessWrapper(AccountGroupByIdAudAccess delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override
+ public String getRelationName() {
+ return delegate.getRelationName();
+ }
+
+ @Override
+ public int getRelationID() {
+ return delegate.getRelationID();
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> iterateAllEntities() throws OrmException {
+ return delegate.iterateAllEntities();
+ }
+
+ @Override
+ public AccountGroupByIdAud.Key primaryKey(AccountGroupByIdAud entity) {
+ return delegate.primaryKey(entity);
+ }
+
+ @Override
+ public Map<AccountGroupByIdAud.Key, AccountGroupByIdAud> toMap(
+ Iterable<AccountGroupByIdAud> c) {
+ return delegate.toMap(c);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public com.google.common.util.concurrent.CheckedFuture<AccountGroupByIdAud, OrmException>
+ getAsync(AccountGroupByIdAud.Key key) {
+ return delegate.getAsync(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> get(Iterable<AccountGroupByIdAud.Key> keys)
+ throws OrmException {
+ return delegate.get(keys);
+ }
+
+ @Override
+ public void insert(Iterable<AccountGroupByIdAud> instances) throws OrmException {
+ delegate.insert(instances);
+ }
+
+ @Override
+ public void update(Iterable<AccountGroupByIdAud> instances) throws OrmException {
+ delegate.update(instances);
+ }
+
+ @Override
+ public void upsert(Iterable<AccountGroupByIdAud> instances) throws OrmException {
+ delegate.upsert(instances);
+ }
+
+ @Override
+ public void deleteKeys(Iterable<AccountGroupByIdAud.Key> keys) throws OrmException {
+ delegate.deleteKeys(keys);
+ }
+
+ @Override
+ public void delete(Iterable<AccountGroupByIdAud> instances) throws OrmException {
+ delegate.delete(instances);
+ }
+
+ @Override
+ public void beginTransaction(AccountGroupByIdAud.Key key) throws OrmException {
+ delegate.beginTransaction(key);
+ }
+
+ @Override
+ public AccountGroupByIdAud atomicUpdate(
+ AccountGroupByIdAud.Key key, AtomicUpdate<AccountGroupByIdAud> update) throws OrmException {
+ return delegate.atomicUpdate(key, update);
+ }
+
+ @Override
+ public AccountGroupByIdAud get(AccountGroupByIdAud.Key key) throws OrmException {
+ return delegate.get(key);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> byGroupInclude(
+ AccountGroup.Id groupId, AccountGroup.UUID incGroupUUID) throws OrmException {
+ return delegate.byGroupInclude(groupId, incGroupUUID);
+ }
+
+ @Override
+ public ResultSet<AccountGroupByIdAud> byGroup(AccountGroup.Id groupId) throws OrmException {
+ return delegate.byGroup(groupId);
+ }
+ }
}
diff --git a/java/com/google/gerrit/server/BUILD b/java/com/google/gerrit/server/BUILD
index 3840e64..6052a63 100644
--- a/java/com/google/gerrit/server/BUILD
+++ b/java/com/google/gerrit/server/BUILD
@@ -38,7 +38,6 @@
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/prettify:server",
"//java/com/google/gerrit/reviewdb:server",
- "//java/com/google/gerrit/server/diff",
"//java/com/google/gerrit/server/ioutil",
"//java/com/google/gerrit/util/cli",
"//java/com/google/gerrit/util/ssl",
diff --git a/java/com/google/gerrit/server/CommentsUtil.java b/java/com/google/gerrit/server/CommentsUtil.java
index 62eab91..1c71c70 100644
--- a/java/com/google/gerrit/server/CommentsUtil.java
+++ b/java/com/google/gerrit/server/CommentsUtil.java
@@ -44,13 +44,13 @@
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerId;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.update.BatchUpdateReviewDb;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/ChangeEdits.java b/java/com/google/gerrit/server/change/ChangeEdits.java
index 7681101..1ca98b7 100644
--- a/java/com/google/gerrit/server/change/ChangeEdits.java
+++ b/java/com/google/gerrit/server/change/ChangeEdits.java
@@ -40,13 +40,13 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.WebLinks;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.edit.ChangeEditJson;
import com.google.gerrit.server.edit.ChangeEditModifier;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.edit.UnchangedCommitMessageException;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.ProjectCache;
diff --git a/java/com/google/gerrit/server/change/ChangeJson.java b/java/com/google/gerrit/server/change/ChangeJson.java
index 74553aa..a03f60a 100644
--- a/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/java/com/google/gerrit/server/change/ChangeJson.java
@@ -109,8 +109,6 @@
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.GpgApiAdapter;
import com.google.gerrit.server.config.TrackingFooters;
-import com.google.gerrit.server.diff.DiffSummary.ChangedLines;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.index.change.ChangeField;
@@ -118,6 +116,7 @@
import com.google.gerrit.server.mail.Address;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.LabelPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
@@ -128,6 +127,7 @@
import com.google.gerrit.server.project.RemoveReviewerControl;
import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.ChangeData.ChangedLines;
import com.google.gerrit.server.query.change.PluginDefinedAttributesFactory;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/CreateDraftComment.java b/java/com/google/gerrit/server/change/CreateDraftComment.java
index b41b323..002c8b7 100644
--- a/java/com/google/gerrit/server/change/CreateDraftComment.java
+++ b/java/com/google/gerrit/server/change/CreateDraftComment.java
@@ -32,7 +32,7 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.diff.PatchListCache;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
diff --git a/java/com/google/gerrit/server/change/DeleteDraftComment.java b/java/com/google/gerrit/server/change/DeleteDraftComment.java
index 6e901ba..6d82139 100644
--- a/java/com/google/gerrit/server/change/DeleteDraftComment.java
+++ b/java/com/google/gerrit/server/change/DeleteDraftComment.java
@@ -27,7 +27,7 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.diff.PatchListCache;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
diff --git a/java/com/google/gerrit/server/change/FileInfoJson.java b/java/com/google/gerrit/server/change/FileInfoJson.java
index 4285319..6ccd460 100644
--- a/java/com/google/gerrit/server/change/FileInfoJson.java
+++ b/java/com/google/gerrit/server/change/FileInfoJson.java
@@ -21,11 +21,11 @@
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.RevId;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Map;
diff --git a/java/com/google/gerrit/server/change/Files.java b/java/com/google/gerrit/server/change/Files.java
index cd92d71..c167e31 100644
--- a/java/com/google/gerrit/server/change/Files.java
+++ b/java/com/google/gerrit/server/change/Files.java
@@ -37,11 +37,11 @@
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.AccountPatchReviewStore.PatchSetWithReviewedFiles;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/GetContent.java b/java/com/google/gerrit/server/change/GetContent.java
index cb921f6..f6b24b8 100644
--- a/java/com/google/gerrit/server/change/GetContent.java
+++ b/java/com/google/gerrit/server/change/GetContent.java
@@ -23,10 +23,10 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.diff.ComparisonType;
-import com.google.gerrit.server.diff.Text;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.patch.ComparisonType;
+import com.google.gerrit.server.patch.Text;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/GetMergeList.java b/java/com/google/gerrit/server/change/GetMergeList.java
index 20c9ea4..88677d6 100644
--- a/java/com/google/gerrit/server/change/GetMergeList.java
+++ b/java/com/google/gerrit/server/change/GetMergeList.java
@@ -21,8 +21,8 @@
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.diff.MergeListBuilder;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.patch.MergeListBuilder;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/java/com/google/gerrit/server/change/PostReview.java b/java/com/google/gerrit/server/change/PostReview.java
index 5467a62..0022656 100644
--- a/java/com/google/gerrit/server/change/PostReview.java
+++ b/java/com/google/gerrit/server/change/PostReview.java
@@ -88,16 +88,16 @@
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.account.AccountsCollection;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.DiffSummary;
-import com.google.gerrit.server.diff.DiffSummaryKey;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.extensions.events.CommentAdded;
import com.google.gerrit.server.mail.Address;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.server.patch.DiffSummary;
+import com.google.gerrit.server.patch.DiffSummaryKey;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.LabelPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/PutDraftComment.java b/java/com/google/gerrit/server/change/PutDraftComment.java
index eadd7b6..c5693c6 100644
--- a/java/com/google/gerrit/server/change/PutDraftComment.java
+++ b/java/com/google/gerrit/server/change/PutDraftComment.java
@@ -30,8 +30,8 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.notedb.ChangeUpdate;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
diff --git a/java/com/google/gerrit/server/diff/BUILD b/java/com/google/gerrit/server/diff/BUILD
deleted file mode 100644
index 606d7bd..0000000
--- a/java/com/google/gerrit/server/diff/BUILD
+++ /dev/null
@@ -1,18 +0,0 @@
-java_library(
- name = "diff",
- srcs = glob(["**/*.java"]),
- visibility = ["//visibility:public"],
- deps = [
- "//java/com/google/gerrit/common:annotations",
- "//java/com/google/gerrit/common:server",
- "//java/com/google/gerrit/extensions:api",
- "//java/com/google/gerrit/reviewdb:server",
- "//java/com/google/gerrit/server/ioutil",
- "//java/org/eclipse/jgit:server",
- "//lib:guava",
- "//lib:juniversalchardet",
- "//lib/auto:auto-value",
- "//lib/jgit/org.eclipse.jgit:jgit",
- "//lib/log:api",
- ],
-)
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index 584a5e9..2614eaf 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -51,11 +51,11 @@
import com.google.gerrit.server.data.SubmitLabelAttribute;
import com.google.gerrit.server.data.SubmitRecordAttribute;
import com.google.gerrit.server.data.TrackingIdAttribute;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
diff --git a/java/com/google/gerrit/server/extensions/events/ChangeAbandoned.java b/java/com/google/gerrit/server/extensions/events/ChangeAbandoned.java
index 92e0fc1..ef69616 100644
--- a/java/com/google/gerrit/server/extensions/events/ChangeAbandoned.java
+++ b/java/com/google/gerrit/server/extensions/events/ChangeAbandoned.java
@@ -24,7 +24,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/ChangeMerged.java b/java/com/google/gerrit/server/extensions/events/ChangeMerged.java
index 943913d..e9ae356 100644
--- a/java/com/google/gerrit/server/extensions/events/ChangeMerged.java
+++ b/java/com/google/gerrit/server/extensions/events/ChangeMerged.java
@@ -24,7 +24,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/ChangeRestored.java b/java/com/google/gerrit/server/extensions/events/ChangeRestored.java
index afbab0d..c25deab 100644
--- a/java/com/google/gerrit/server/extensions/events/ChangeRestored.java
+++ b/java/com/google/gerrit/server/extensions/events/ChangeRestored.java
@@ -24,7 +24,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/CommentAdded.java b/java/com/google/gerrit/server/extensions/events/CommentAdded.java
index af0ee5e..77cd1a8 100644
--- a/java/com/google/gerrit/server/extensions/events/CommentAdded.java
+++ b/java/com/google/gerrit/server/extensions/events/CommentAdded.java
@@ -25,7 +25,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/EventUtil.java b/java/com/google/gerrit/server/extensions/events/EventUtil.java
index 8c217bc..95d7132 100644
--- a/java/com/google/gerrit/server/extensions/events/EventUtil.java
+++ b/java/com/google/gerrit/server/extensions/events/EventUtil.java
@@ -28,7 +28,7 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.change.ChangeJson;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/ReviewerAdded.java b/java/com/google/gerrit/server/extensions/events/ReviewerAdded.java
index 3b5c66c..fc6881d 100644
--- a/java/com/google/gerrit/server/extensions/events/ReviewerAdded.java
+++ b/java/com/google/gerrit/server/extensions/events/ReviewerAdded.java
@@ -25,7 +25,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/ReviewerDeleted.java b/java/com/google/gerrit/server/extensions/events/ReviewerDeleted.java
index e156865..28e07a9 100644
--- a/java/com/google/gerrit/server/extensions/events/ReviewerDeleted.java
+++ b/java/com/google/gerrit/server/extensions/events/ReviewerDeleted.java
@@ -25,7 +25,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/RevisionCreated.java b/java/com/google/gerrit/server/extensions/events/RevisionCreated.java
index 6b384a0..76779ca 100644
--- a/java/com/google/gerrit/server/extensions/events/RevisionCreated.java
+++ b/java/com/google/gerrit/server/extensions/events/RevisionCreated.java
@@ -24,7 +24,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/extensions/events/VoteDeleted.java b/java/com/google/gerrit/server/extensions/events/VoteDeleted.java
index 070d5b8..8944698 100644
--- a/java/com/google/gerrit/server/extensions/events/VoteDeleted.java
+++ b/java/com/google/gerrit/server/extensions/events/VoteDeleted.java
@@ -25,7 +25,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.GpgException;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/git/CommitUtil.java b/java/com/google/gerrit/server/git/CommitUtil.java
index fd512a5..b0f10f2 100644
--- a/java/com/google/gerrit/server/git/CommitUtil.java
+++ b/java/com/google/gerrit/server/git/CommitUtil.java
@@ -14,14 +14,22 @@
package com.google.gerrit.server.git;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.server.CommonConverters;
+import java.io.IOException;
import java.util.ArrayList;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
/** Static utilities for working with {@link RevCommit}s. */
public class CommitUtil {
- public static CommitInfo toCommitInfo(RevCommit commit) {
+ public static CommitInfo toCommitInfo(RevCommit commit) throws IOException {
+ return toCommitInfo(commit, null);
+ }
+
+ public static CommitInfo toCommitInfo(RevCommit commit, @Nullable RevWalk walk)
+ throws IOException {
CommitInfo info = new CommitInfo();
info.commit = commit.getName();
info.author = CommonConverters.toGitPerson(commit.getAuthorIdent());
@@ -30,7 +38,7 @@
info.message = commit.getFullMessage();
info.parents = new ArrayList<>(commit.getParentCount());
for (int i = 0; i < commit.getParentCount(); i++) {
- RevCommit p = commit.getParent(i);
+ RevCommit p = walk == null ? commit.getParent(i) : walk.parseCommit(commit.getParent(i));
CommitInfo parentInfo = new CommitInfo();
parentInfo.commit = p.getName();
parentInfo.subject = p.getShortMessage();
diff --git a/java/com/google/gerrit/server/git/VersionedMetaData.java b/java/com/google/gerrit/server/git/VersionedMetaData.java
index 74a8134..812e693 100644
--- a/java/com/google/gerrit/server/git/VersionedMetaData.java
+++ b/java/com/google/gerrit/server/git/VersionedMetaData.java
@@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.MoreObjects;
+import com.google.gerrit.common.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
@@ -76,7 +77,9 @@
}
}
- protected RevCommit revision;
+ /** The revision at which the data was loaded. Is null for data yet to be created. */
+ @Nullable protected RevCommit revision;
+
protected RevWalk rw;
protected ObjectReader reader;
protected ObjectInserter inserter;
@@ -133,7 +136,8 @@
* @throws IOException
* @throws ConfigInvalidException
*/
- public void load(Repository db, ObjectId id) throws IOException, ConfigInvalidException {
+ public void load(Repository db, @Nullable ObjectId id)
+ throws IOException, ConfigInvalidException {
try (RevWalk walk = new RevWalk(db)) {
load(walk, id);
}
diff --git a/java/com/google/gerrit/server/group/GetAuditLog.java b/java/com/google/gerrit/server/group/GetAuditLog.java
index ebada0b..58a057b 100644
--- a/java/com/google/gerrit/server/group/GetAuditLog.java
+++ b/java/com/google/gerrit/server/group/GetAuditLog.java
@@ -36,10 +36,12 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import org.eclipse.jgit.errors.ConfigInvalidException;
@Singleton
public class GetAuditLog implements RestReadView<GroupResource> {
@@ -68,7 +70,8 @@
@Override
public List<? extends GroupAuditEventInfo> apply(GroupResource rsrc)
- throws AuthException, MethodNotAllowedException, OrmException {
+ throws AuthException, MethodNotAllowedException, OrmException, IOException,
+ ConfigInvalidException {
GroupDescription.Internal group =
rsrc.asInternalGroup().orElseThrow(MethodNotAllowedException::new);
if (!rsrc.getControl().isOwner()) {
@@ -123,8 +126,9 @@
accountLoader.fill();
- // sort by date in reverse order so that the newest audit event comes first
- Collections.sort(auditEvents, comparing((GroupAuditEventInfo a) -> a.date).reversed());
+ // sort by date and then reverse so that the newest audit event comes first
+ Collections.sort(auditEvents, comparing((GroupAuditEventInfo a) -> a.date));
+ Collections.reverse(auditEvents);
return auditEvents;
}
diff --git a/java/com/google/gerrit/server/group/db/AuditLogReader.java b/java/com/google/gerrit/server/group/db/AuditLogReader.java
new file mode 100644
index 0000000..3ab91dd
--- /dev/null
+++ b/java/com/google/gerrit/server/group/db/AuditLogReader.java
@@ -0,0 +1,274 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.group.db;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.MultimapBuilder;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
+import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.config.GerritServerId;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.notedb.NoteDbUtil;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.FooterLine;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.RawParseUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** NoteDb reader for group audit log. */
+@Singleton
+class AuditLogReader {
+ private static final Logger log = LoggerFactory.getLogger(AuditLogReader.class);
+
+ private final String serverId;
+ private final GitRepositoryManager repoManager;
+ private final AllUsersName allUsers;
+
+ @Inject
+ AuditLogReader(
+ @GerritServerId String serverId, GitRepositoryManager repoManager, AllUsersName allUsers) {
+ this.serverId = serverId;
+ this.repoManager = repoManager;
+ this.allUsers = allUsers;
+ }
+
+ // Having separate methods for reading the two types of audit records mirrors the split in
+ // ReviewDb. Once ReviewDb is gone, the audit record interface becomes more flexible and we can
+ // revisit this, e.g. to do only a single walk, or even change the record types.
+
+ ImmutableList<AccountGroupMemberAudit> getMembersAudit(AccountGroup.UUID uuid)
+ throws IOException, ConfigInvalidException {
+ return new MembersAuditLogParser().parseAuditLog(uuid);
+ }
+
+ ImmutableList<AccountGroupByIdAud> getSubgroupsAudit(AccountGroup.UUID uuid)
+ throws IOException, ConfigInvalidException {
+ return new SubgroupsAuditLogParser().parseAuditLog(uuid);
+ }
+
+ private Optional<ParsedCommit> parse(AccountGroup.UUID uuid, RevCommit c) {
+ Optional<Account.Id> authorId = NoteDbUtil.parseIdent(c.getAuthorIdent(), serverId);
+ if (!authorId.isPresent()) {
+ // Only report audit events from identified users, since this is a non-nullable field in
+ // ReviewDb. May be revisited after groups are fully migrated to NoteDb.
+ return Optional.empty();
+ }
+
+ List<Account.Id> addedMembers = new ArrayList<>();
+ List<AccountGroup.UUID> addedSubgroups = new ArrayList<>();
+ List<Account.Id> removedMembers = new ArrayList<>();
+ List<AccountGroup.UUID> removedSubgroups = new ArrayList<>();
+
+ for (FooterLine line : c.getFooterLines()) {
+ if (line.matches(GroupConfig.FOOTER_ADD_MEMBER)) {
+ parseAccount(uuid, c, line).ifPresent(addedMembers::add);
+ } else if (line.matches(GroupConfig.FOOTER_REMOVE_MEMBER)) {
+ parseAccount(uuid, c, line).ifPresent(removedMembers::add);
+ } else if (line.matches(GroupConfig.FOOTER_ADD_GROUP)) {
+ parseGroup(uuid, c, line).ifPresent(addedSubgroups::add);
+ } else if (line.matches(GroupConfig.FOOTER_REMOVE_GROUP)) {
+ parseGroup(uuid, c, line).ifPresent(removedSubgroups::add);
+ }
+ }
+ return Optional.of(
+ new AutoValue_AuditLogReader_ParsedCommit(
+ authorId.get(),
+ new Timestamp(c.getAuthorIdent().getWhen().getTime()),
+ ImmutableList.copyOf(addedMembers),
+ ImmutableList.copyOf(removedMembers),
+ ImmutableList.copyOf(addedSubgroups),
+ ImmutableList.copyOf(removedSubgroups)));
+ }
+
+ private Optional<Account.Id> parseAccount(AccountGroup.UUID uuid, RevCommit c, FooterLine line) {
+ Optional<Account.Id> result =
+ Optional.ofNullable(RawParseUtils.parsePersonIdent(line.getValue()))
+ .flatMap(ident -> NoteDbUtil.parseIdent(ident, serverId));
+ if (!result.isPresent()) {
+ logInvalid(uuid, c, line);
+ }
+ return result;
+ }
+
+ private static Optional<AccountGroup.UUID> parseGroup(
+ AccountGroup.UUID uuid, RevCommit c, FooterLine line) {
+ PersonIdent ident = RawParseUtils.parsePersonIdent(line.getValue());
+ if (ident == null) {
+ logInvalid(uuid, c, line);
+ return Optional.empty();
+ }
+ return Optional.of(new AccountGroup.UUID(ident.getEmailAddress()));
+ }
+
+ private static void logInvalid(AccountGroup.UUID uuid, RevCommit c, FooterLine line) {
+ log.debug(
+ "Invalid footer line in commit {} while parsing audit log for group {}: {}",
+ c.name(),
+ uuid,
+ line);
+ }
+
+ private abstract class AuditLogParser<T> {
+ final ImmutableList<T> parseAuditLog(AccountGroup.UUID uuid)
+ throws IOException, ConfigInvalidException {
+ try (Repository repo = repoManager.openRepository(allUsers);
+ RevWalk rw = new RevWalk(repo)) {
+ Ref ref = repo.exactRef(RefNames.refsGroups(uuid));
+ if (ref == null) {
+ return ImmutableList.of();
+ }
+
+ // TODO(dborowitz): This re-walks all commits just to find createdOn, which we don't need.
+ AccountGroup.Id groupId =
+ GroupConfig.loadForGroup(repo, uuid).getLoadedGroup().get().getId();
+
+ rw.reset();
+ rw.markStart(rw.parseCommit(ref.getObjectId()));
+ rw.setRetainBody(true);
+ rw.sort(RevSort.COMMIT_TIME_DESC, true);
+ rw.sort(RevSort.REVERSE, true);
+
+ ImmutableList.Builder<T> result = ImmutableList.builder();
+ RevCommit c;
+ while ((c = rw.next()) != null) {
+ parse(uuid, c).ifPresent(pc -> visit(groupId, pc, result));
+ }
+ return result.build();
+ }
+ }
+
+ protected abstract void visit(
+ AccountGroup.Id groupId, ParsedCommit pc, ImmutableList.Builder<T> result);
+ }
+
+ private class MembersAuditLogParser extends AuditLogParser<AccountGroupMemberAudit> {
+ private ListMultimap<MemberKey, AccountGroupMemberAudit> audits =
+ MultimapBuilder.hashKeys().linkedListValues().build();
+
+ @Override
+ protected void visit(
+ AccountGroup.Id groupId,
+ ParsedCommit pc,
+ ImmutableList.Builder<AccountGroupMemberAudit> result) {
+ for (Account.Id id : pc.addedMembers()) {
+ MemberKey key = MemberKey.create(groupId, id);
+ AccountGroupMemberAudit audit =
+ new AccountGroupMemberAudit(
+ new AccountGroupMemberAudit.Key(id, groupId, pc.when()), pc.authorId());
+ audits.put(key, audit);
+ result.add(audit);
+ }
+ for (Account.Id id : pc.removedMembers()) {
+ List<AccountGroupMemberAudit> adds = audits.get(MemberKey.create(groupId, id));
+ if (!adds.isEmpty()) {
+ AccountGroupMemberAudit audit = adds.remove(0);
+ audit.removed(pc.authorId(), pc.when());
+ } else {
+ // Match old behavior of DbGroupMemberAuditListener and add a "legacy" add/remove pair.
+ AccountGroupMemberAudit audit =
+ new AccountGroupMemberAudit(
+ new AccountGroupMemberAudit.Key(id, groupId, pc.when()), pc.authorId());
+ audit.removedLegacy();
+ result.add(audit);
+ }
+ }
+ }
+ }
+
+ private class SubgroupsAuditLogParser extends AuditLogParser<AccountGroupByIdAud> {
+ private ListMultimap<SubgroupKey, AccountGroupByIdAud> audits =
+ MultimapBuilder.hashKeys().linkedListValues().build();
+
+ @Override
+ protected void visit(
+ AccountGroup.Id groupId,
+ ParsedCommit pc,
+ ImmutableList.Builder<AccountGroupByIdAud> result) {
+ for (AccountGroup.UUID uuid : pc.addedSubgroups()) {
+ SubgroupKey key = SubgroupKey.create(groupId, uuid);
+ AccountGroupByIdAud audit =
+ new AccountGroupByIdAud(
+ new AccountGroupByIdAud.Key(groupId, uuid, pc.when()), pc.authorId());
+ audits.put(key, audit);
+ result.add(audit);
+ }
+ for (AccountGroup.UUID uuid : pc.removedSubgroups()) {
+ List<AccountGroupByIdAud> adds = audits.get(SubgroupKey.create(groupId, uuid));
+ if (!adds.isEmpty()) {
+ AccountGroupByIdAud audit = adds.remove(0);
+ audit.removed(pc.authorId(), pc.when());
+ } else {
+ // Unlike members, DbGroupMemberAuditListener didn't insert an add/remove pair here.
+ }
+ }
+ }
+ }
+
+ @AutoValue
+ abstract static class MemberKey {
+ static MemberKey create(AccountGroup.Id groupId, Account.Id memberId) {
+ return new AutoValue_AuditLogReader_MemberKey(groupId, memberId);
+ }
+
+ abstract AccountGroup.Id groupId();
+
+ abstract Account.Id memberId();
+ }
+
+ @AutoValue
+ abstract static class SubgroupKey {
+ static SubgroupKey create(AccountGroup.Id groupId, AccountGroup.UUID subgroupUuid) {
+ return new AutoValue_AuditLogReader_SubgroupKey(groupId, subgroupUuid);
+ }
+
+ abstract AccountGroup.Id groupId();
+
+ abstract AccountGroup.UUID subgroupUuid();
+ }
+
+ @AutoValue
+ abstract static class ParsedCommit {
+ abstract Account.Id authorId();
+
+ abstract Timestamp when();
+
+ abstract ImmutableList<Account.Id> addedMembers();
+
+ abstract ImmutableList<Account.Id> removedMembers();
+
+ abstract ImmutableList<AccountGroup.UUID> addedSubgroups();
+
+ abstract ImmutableList<AccountGroup.UUID> removedSubgroups();
+ }
+}
diff --git a/java/com/google/gerrit/server/group/db/GroupBundle.java b/java/com/google/gerrit/server/group/db/GroupBundle.java
index f83f094..2f3b118 100644
--- a/java/com/google/gerrit/server/group/db/GroupBundle.java
+++ b/java/com/google/gerrit/server/group/db/GroupBundle.java
@@ -14,11 +14,11 @@
package com.google.gerrit.server.group.db;
-import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.gerrit.reviewdb.server.ReviewDbUtil.checkColumns;
import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupById;
@@ -28,6 +28,11 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Repository;
/**
* A bundle of all entities rooted at a single {@link AccountGroup} entity.
@@ -37,17 +42,84 @@
*/
@AutoValue
public abstract class GroupBundle {
- public static GroupBundle fromReviewDb(ReviewDb db, AccountGroup.Id id) throws OrmException {
- AccountGroup group = db.accountGroups().get(id);
- if (group == null) {
- throw new OrmException("Group " + id + " not found");
+ static {
+ // Initialization-time checks that the column set hasn't changed since the
+ // last time this file was updated.
+ checkColumns(AccountGroup.NameKey.class, 1);
+ checkColumns(AccountGroup.UUID.class, 1);
+ checkColumns(AccountGroup.Id.class, 1);
+ checkColumns(AccountGroup.class, 1, 2, 4, 7, 9, 10, 11);
+
+ checkColumns(AccountGroupById.Key.class, 1, 2);
+ checkColumns(AccountGroupById.class, 1);
+
+ checkColumns(AccountGroupByIdAud.Key.class, 1, 2, 3);
+ checkColumns(AccountGroupByIdAud.class, 1, 2, 3, 4);
+
+ checkColumns(AccountGroupMember.Key.class, 1, 2);
+ checkColumns(AccountGroupMember.class, 1);
+
+ checkColumns(AccountGroupMemberAudit.Key.class, 1, 2, 3);
+ checkColumns(AccountGroupMemberAudit.class, 1, 2, 3, 4);
+ }
+
+ @Singleton
+ public static class Factory {
+ private final AuditLogReader auditLogReader;
+
+ @Inject
+ Factory(AuditLogReader auditLogReader) {
+ this.auditLogReader = auditLogReader;
}
- return create(
- group,
- db.accountGroupMembers().byGroup(id),
- db.accountGroupMembersAudit().byGroup(id),
- db.accountGroupById().byGroup(id),
- db.accountGroupByIdAud().byGroup(id));
+
+ public GroupBundle fromReviewDb(ReviewDb db, AccountGroup.Id id) throws OrmException {
+ AccountGroup group = db.accountGroups().get(id);
+ if (group == null) {
+ throw new OrmException("Group " + id + " not found");
+ }
+ return create(
+ group,
+ db.accountGroupMembers().byGroup(id),
+ db.accountGroupMembersAudit().byGroup(id),
+ db.accountGroupById().byGroup(id),
+ db.accountGroupByIdAud().byGroup(id));
+ }
+
+ public GroupBundle fromNoteDb(Repository repo, AccountGroup.UUID uuid)
+ throws ConfigInvalidException, IOException {
+ GroupConfig groupConfig = GroupConfig.loadForGroup(repo, uuid);
+ InternalGroup internalGroup = groupConfig.getLoadedGroup().get();
+ AccountGroup.Id groupId = internalGroup.getId();
+
+ AccountGroup accountGroup =
+ new AccountGroup(
+ internalGroup.getNameKey(),
+ internalGroup.getId(),
+ internalGroup.getGroupUUID(),
+ internalGroup.getCreatedOn());
+ accountGroup.setDescription(internalGroup.getDescription());
+ accountGroup.setOwnerGroupUUID(internalGroup.getOwnerGroupUUID());
+ accountGroup.setVisibleToAll(internalGroup.isVisibleToAll());
+
+ return create(
+ accountGroup,
+ internalGroup
+ .getMembers()
+ .stream()
+ .map(
+ accountId ->
+ new AccountGroupMember(new AccountGroupMember.Key(accountId, groupId)))
+ .collect(toImmutableSet()),
+ auditLogReader.getMembersAudit(uuid),
+ internalGroup
+ .getSubgroups()
+ .stream()
+ .map(
+ subgroupUuid ->
+ new AccountGroupById(new AccountGroupById.Key(groupId, subgroupUuid)))
+ .collect(toImmutableSet()),
+ auditLogReader.getSubgroupsAudit(uuid));
+ }
}
public static GroupBundle create(
@@ -79,13 +151,13 @@
public abstract AccountGroup group();
- public abstract ImmutableList<AccountGroupMember> members();
+ public abstract ImmutableSet<AccountGroupMember> members();
- public abstract ImmutableList<AccountGroupMemberAudit> memberAudit();
+ public abstract ImmutableSet<AccountGroupMemberAudit> memberAudit();
- public abstract ImmutableList<AccountGroupById> byId();
+ public abstract ImmutableSet<AccountGroupById> byId();
- public abstract ImmutableList<AccountGroupByIdAud> byIdAudit();
+ public abstract ImmutableSet<AccountGroupByIdAud> byIdAudit();
public abstract Builder toBuilder();
@@ -97,8 +169,8 @@
return toBuilder()
.group(newGroup)
.memberAudit(
- memberAudit().stream().map(GroupBundle::roundToSecond).collect(toImmutableList()))
- .byIdAudit(byIdAudit().stream().map(GroupBundle::roundToSecond).collect(toImmutableList()))
+ memberAudit().stream().map(GroupBundle::roundToSecond).collect(toImmutableSet()))
+ .byIdAudit(byIdAudit().stream().map(GroupBundle::roundToSecond).collect(toImmutableSet()))
.build();
}
diff --git a/java/com/google/gerrit/server/group/db/GroupConfig.java b/java/com/google/gerrit/server/group/db/GroupConfig.java
index 17ab344..c23dc09 100644
--- a/java/com/google/gerrit/server/group/db/GroupConfig.java
+++ b/java/com/google/gerrit/server/group/db/GroupConfig.java
@@ -44,12 +44,19 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
// TODO(aliceks): Add Javadoc descriptions to this file.
public class GroupConfig extends VersionedMetaData {
public static final String GROUP_CONFIG_FILE = "group.config";
+
+ static final FooterKey FOOTER_ADD_MEMBER = new FooterKey("Add");
+ static final FooterKey FOOTER_REMOVE_MEMBER = new FooterKey("Remove");
+ static final FooterKey FOOTER_ADD_GROUP = new FooterKey("Add-group");
+ static final FooterKey FOOTER_REMOVE_GROUP = new FooterKey("Remove-group");
+
private static final String MEMBERS_FILE = "members";
private static final String SUBGROUPS_FILE = "subgroups";
private static final Pattern LINE_SEPARATOR_PATTERN = Pattern.compile("\\R");
@@ -332,12 +339,12 @@
Sets.difference(oldMembers, newMembers)
.stream()
.map(accountNameEmailRetriever)
- .map("Remove: "::concat);
+ .map((FOOTER_REMOVE_MEMBER.getName() + ": ")::concat);
Stream<String> addedMembers =
Sets.difference(newMembers, oldMembers)
.stream()
.map(accountNameEmailRetriever)
- .map("Add: "::concat);
+ .map((FOOTER_ADD_MEMBER.getName() + ": ")::concat);
return Stream.concat(removedMembers, addedMembers);
}
@@ -347,12 +354,12 @@
Sets.difference(oldSubgroups, newSubgroups)
.stream()
.map(groupNameRetriever)
- .map("Remove-group: "::concat);
+ .map((FOOTER_REMOVE_GROUP.getName() + ": ")::concat);
Stream<String> addedMembers =
Sets.difference(newSubgroups, oldSubgroups)
.stream()
.map(groupNameRetriever)
- .map("Add-group: "::concat);
+ .map((FOOTER_ADD_GROUP.getName() + ": ")::concat);
return Stream.concat(removedMembers, addedMembers);
}
}
diff --git a/java/com/google/gerrit/server/group/db/Groups.java b/java/com/google/gerrit/server/group/db/Groups.java
index 0260f41..7f63021 100644
--- a/java/com/google/gerrit/server/group/db/Groups.java
+++ b/java/com/google/gerrit/server/group/db/Groups.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.group.db;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static java.util.Comparator.comparing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -30,20 +31,20 @@
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
+import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
/**
@@ -61,18 +62,21 @@
*/
@Singleton
public class Groups {
- private final boolean readFromNoteDb;
+ private final GroupsMigration groupsMigration;
private final GitRepositoryManager repoManager;
private final AllUsersName allUsersName;
+ private final AuditLogReader auditLogReader;
@Inject
public Groups(
- @GerritServerConfig Config config,
+ GroupsMigration groupsMigration,
GitRepositoryManager repoManager,
- AllUsersName allUsersName) {
- readFromNoteDb = config.getBoolean("user", null, "readGroupsFromNoteDb", false);
+ AllUsersName allUsersName,
+ AuditLogReader auditLogReader) {
+ this.groupsMigration = groupsMigration;
this.repoManager = repoManager;
this.allUsersName = allUsersName;
+ this.auditLogReader = auditLogReader;
}
/**
@@ -105,7 +109,7 @@
*/
public Optional<InternalGroup> getGroup(ReviewDb db, AccountGroup.UUID groupUuid)
throws OrmException, IOException, ConfigInvalidException {
- if (readFromNoteDb) {
+ if (groupsMigration.readFromNoteDb()) {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
return getGroupFromNoteDb(allUsersRepo, groupUuid);
}
@@ -182,7 +186,7 @@
*/
public Stream<GroupReference> getAllGroupReferences(ReviewDb db)
throws OrmException, IOException, ConfigInvalidException {
- if (readFromNoteDb) {
+ if (groupsMigration.readFromNoteDb()) {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
return GroupNameNotes.loadAllGroupReferences(allUsersRepo).stream();
}
@@ -278,7 +282,7 @@
*/
public Stream<AccountGroup.UUID> getExternalGroups(ReviewDb db)
throws OrmException, IOException, ConfigInvalidException {
- if (readFromNoteDb) {
+ if (groupsMigration.readFromNoteDb()) {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
return getExternalGroupsFromNoteDb(allUsersRepo);
}
@@ -312,18 +316,23 @@
* @param groupUuid the UUID of the group
* @return the audit records, in arbitrary order; empty if the group does not exist
* @throws OrmException if an error occurs while reading from ReviewDb
+ * @throws IOException if an error occurs while reading from NoteDb
+ * @throws ConfigInvalidException if the group couldn't be retrieved from NoteDb
*/
public List<AccountGroupMemberAudit> getMembersAudit(ReviewDb db, AccountGroup.UUID groupUuid)
- throws OrmException {
- if (readFromNoteDb) {
- // TODO(dborowitz): Implement.
- throw new OrmException("Audit logs not yet implemented in NoteDb");
+ throws OrmException, IOException, ConfigInvalidException {
+ if (groupsMigration.readFromNoteDb()) {
+ return auditLogReader.getMembersAudit(groupUuid);
}
Optional<AccountGroup> group = getGroupFromReviewDb(db, groupUuid);
if (!group.isPresent()) {
return ImmutableList.of();
}
- return db.accountGroupMembersAudit().byGroup(group.get().getId()).toList();
+
+ List<AccountGroupMemberAudit> audits =
+ db.accountGroupMembersAudit().byGroup(group.get().getId()).toList();
+ Collections.sort(audits, comparing((AccountGroupMemberAudit a) -> a.getAddedOn()));
+ return audits;
}
/**
@@ -333,17 +342,22 @@
* @param groupUuid the UUID of the group
* @return the audit records, in arbitrary order; empty if the group does not exist
* @throws OrmException if an error occurs while reading from ReviewDb
+ * @throws IOException if an error occurs while reading from NoteDb
+ * @throws ConfigInvalidException if the group couldn't be retrieved from NoteDb
*/
public List<AccountGroupByIdAud> getSubgroupsAudit(ReviewDb db, AccountGroup.UUID groupUuid)
- throws OrmException {
- if (readFromNoteDb) {
- // TODO(dborowitz): Implement.
- throw new OrmException("Audit logs not yet implemented in NoteDb");
+ throws OrmException, IOException, ConfigInvalidException {
+ if (groupsMigration.readFromNoteDb()) {
+ return auditLogReader.getSubgroupsAudit(groupUuid);
}
Optional<AccountGroup> group = getGroupFromReviewDb(db, groupUuid);
if (!group.isPresent()) {
return ImmutableList.of();
}
- return db.accountGroupByIdAud().byGroup(group.get().getId()).toList();
+
+ List<AccountGroupByIdAud> audits =
+ db.accountGroupByIdAud().byGroup(group.get().getId()).toList();
+ Collections.sort(audits, comparing((AccountGroupByIdAud a) -> a.getAddedOn()));
+ return audits;
}
}
diff --git a/java/com/google/gerrit/server/group/db/GroupsUpdate.java b/java/com/google/gerrit/server/group/db/GroupsUpdate.java
index 3765847..80b282c 100644
--- a/java/com/google/gerrit/server/group/db/GroupsUpdate.java
+++ b/java/com/google/gerrit/server/group/db/GroupsUpdate.java
@@ -32,6 +32,7 @@
import com.google.gerrit.reviewdb.client.AccountGroupName;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
@@ -48,6 +49,7 @@
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.RenameGroupOp;
import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.update.RefUpdateUtil;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
@@ -104,8 +106,8 @@
@Nullable private final IdentifiedUser currentUser;
private final PersonIdent authorIdent;
private final MetaDataUpdateFactory metaDataUpdateFactory;
+ private final GroupsMigration groupsMigration;
private final GitReferenceUpdated gitRefUpdated;
- private final boolean writeGroupsToNoteDb;
private final boolean reviewDbUpdatesAreBlocked;
@Inject
@@ -121,6 +123,7 @@
@GerritServerId String serverId,
@GerritPersonIdent PersonIdent serverIdent,
MetaDataUpdate.InternalFactory metaDataUpdateInternalFactory,
+ GroupsMigration groupsMigration,
@GerritServerConfig Config config,
GitReferenceUpdated gitRefUpdated,
@Assisted @Nullable IdentifiedUser currentUser) {
@@ -133,17 +136,13 @@
this.anonymousCowardName = anonymousCowardName;
this.renameGroupOpFactory = renameGroupOpFactory;
this.serverId = serverId;
+ this.groupsMigration = groupsMigration;
this.gitRefUpdated = gitRefUpdated;
this.currentUser = currentUser;
metaDataUpdateFactory =
getMetaDataUpdateFactory(
metaDataUpdateInternalFactory, currentUser, serverIdent, serverId, anonymousCowardName);
authorIdent = getAuthorIdent(serverIdent, currentUser);
- // TODO(aliceks): Remove this flag when all other necessary TODOs for writing groups to NoteDb
- // have been addressed.
- // Don't flip this flag in a production setting! We only added it to spread the implementation
- // of groups in NoteDb among several changes which are gradually merged.
- writeGroupsToNoteDb = config.getBoolean("user", null, "writeGroupsToNoteDb", false);
reviewDbUpdatesAreBlocked = config.getBoolean("user", null, "blockReviewDbGroupUpdates", false);
}
@@ -206,9 +205,11 @@
public InternalGroup createGroup(
ReviewDb db, InternalGroupCreation groupCreation, InternalGroupUpdate groupUpdate)
throws OrmException, IOException, ConfigInvalidException {
- InternalGroup createdGroupInReviewDb = createGroupInReviewDb(db, groupCreation, groupUpdate);
+ // TODO(ekempin): Don't read groups from ReviewDb if reading groups from NoteDb is configured
+ InternalGroup createdGroupInReviewDb =
+ createGroupInReviewDb(ReviewDbUtil.unwrapDb(db), groupCreation, groupUpdate);
- if (!writeGroupsToNoteDb) {
+ if (!groupsMigration.writeToNoteDb()) {
updateCachesOnGroupCreation(createdGroupInReviewDb);
return createdGroupInReviewDb;
}
@@ -242,10 +243,12 @@
public UpdateResult updateGroupInDb(
ReviewDb db, AccountGroup.UUID groupUuid, InternalGroupUpdate groupUpdate)
throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
- AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid);
- UpdateResult reviewDbUpdateResult = updateGroupInReviewDb(db, group, groupUpdate);
+ // TODO(ekempin): Don't read groups from ReviewDb if reading groups from NoteDb is configured
+ AccountGroup group = getExistingGroupFromReviewDb(ReviewDbUtil.unwrapDb(db), groupUuid);
+ UpdateResult reviewDbUpdateResult =
+ updateGroupInReviewDb(ReviewDbUtil.unwrapDb(db), group, groupUpdate);
- if (!writeGroupsToNoteDb) {
+ if (!groupsMigration.writeToNoteDb()) {
return reviewDbUpdateResult;
}
diff --git a/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java b/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
index 7378b15..a71f417 100644
--- a/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
+++ b/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
@@ -24,6 +24,7 @@
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.CommitUtil;
+import java.io.IOException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.Note;
@@ -55,7 +56,17 @@
if (ref != null) {
rw.sort(RevSort.REVERSE);
rw.markStart(rw.parseCommit(ref.getObjectId()));
- return Streams.stream(rw).map(CommitUtil::toCommitInfo).collect(toImmutableList());
+ return Streams.stream(rw)
+ .map(
+ c -> {
+ try {
+ return CommitUtil.toCommitInfo(c);
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "unexpected state when converting commit " + c.getName(), e);
+ }
+ })
+ .collect(toImmutableList());
}
}
return ImmutableList.of();
diff --git a/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java b/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
index 2d742c6..b0527e1 100644
--- a/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
+++ b/java/com/google/gerrit/server/index/account/AccountIndexerImpl.java
@@ -102,7 +102,7 @@
}
private static boolean autoReindexIfStale(Config cfg) {
- return cfg.getBoolean("index", null, "autoReindexIfStale", true);
+ return cfg.getBoolean("index", null, "autoReindexIfStale", false);
}
private void autoReindexIfStale(Account.Id id) {
diff --git a/java/com/google/gerrit/server/index/group/StalenessChecker.java b/java/com/google/gerrit/server/index/group/StalenessChecker.java
index 5c641ef..418bb35 100644
--- a/java/com/google/gerrit/server/index/group/StalenessChecker.java
+++ b/java/com/google/gerrit/server/index/group/StalenessChecker.java
@@ -20,13 +20,12 @@
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
-import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
@@ -48,7 +47,7 @@
private final GitRepositoryManager repoManager;
private final IndexConfig indexConfig;
private final AllUsersName allUsers;
- private final Config config;
+ private final GroupsMigration groupsMigration;
@Inject
StalenessChecker(
@@ -56,16 +55,16 @@
GitRepositoryManager repoManager,
IndexConfig indexConfig,
AllUsersName allUsers,
- @GerritServerConfig Config config) {
+ GroupsMigration groupsMigration) {
this.indexes = indexes;
this.repoManager = repoManager;
this.indexConfig = indexConfig;
this.allUsers = allUsers;
- this.config = config;
+ this.groupsMigration = groupsMigration;
}
public boolean isStale(AccountGroup.UUID uuid) throws IOException {
- if (!config.getBoolean("user", "readGroupsFromNoteDb", false)) {
+ if (!groupsMigration.readFromNoteDb()) {
return false; // This class only treats staleness for groups in NoteDb.
}
diff --git a/java/com/google/gerrit/server/mail/receive/MailProcessor.java b/java/com/google/gerrit/server/mail/receive/MailProcessor.java
index 8a687fd..3e8734a 100644
--- a/java/com/google/gerrit/server/mail/receive/MailProcessor.java
+++ b/java/com/google/gerrit/server/mail/receive/MailProcessor.java
@@ -40,10 +40,10 @@
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.change.EmailReviewComments;
import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.extensions.events.CommentAdded;
import com.google.gerrit.server.mail.MailFilter;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.update.BatchUpdate;
diff --git a/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
index 8a7c985..3e1dc92 100644
--- a/java/com/google/gerrit/server/mail/send/ChangeEmail.java
+++ b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
@@ -31,11 +31,11 @@
import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.WatchConfig.NotifyType;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.mail.send.ProjectWatch.Watchers;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.permissions.ChangePermission;
diff --git a/java/com/google/gerrit/server/mail/send/CommentSender.java b/java/com/google/gerrit/server/mail/send/CommentSender.java
index 4cef569..8055273 100644
--- a/java/com/google/gerrit/server/mail/send/CommentSender.java
+++ b/java/com/google/gerrit/server/mail/send/CommentSender.java
@@ -30,11 +30,11 @@
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.account.WatchConfig.NotifyType;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.PatchFile;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.mail.MailUtil;
import com.google.gerrit.server.mail.receive.Protocol;
+import com.google.gerrit.server.patch.PatchFile;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchListObjectTooLargeException;
import com.google.gerrit.server.util.LabelVote;
import com.google.gwtorm.client.KeyUtil;
diff --git a/java/com/google/gerrit/server/mail/send/EmailArguments.java b/java/com/google/gerrit/server/mail/send/EmailArguments.java
index e6116c7..83a1c25 100644
--- a/java/com/google/gerrit/server/mail/send/EmailArguments.java
+++ b/java/com/google/gerrit/server/mail/send/EmailArguments.java
@@ -28,10 +28,10 @@
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mail.EmailSettings;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
diff --git a/java/com/google/gerrit/server/notedb/ChangeBundle.java b/java/com/google/gerrit/server/notedb/ChangeBundle.java
index a9663c7..221252c 100644
--- a/java/com/google/gerrit/server/notedb/ChangeBundle.java
+++ b/java/com/google/gerrit/server/notedb/ChangeBundle.java
@@ -17,8 +17,8 @@
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.common.TimeUtil.roundToSecond;
+import static com.google.gerrit.reviewdb.server.ReviewDbUtil.checkColumns;
import static com.google.gerrit.reviewdb.server.ReviewDbUtil.intKeyOrdering;
import static com.google.gerrit.server.notedb.ChangeBundle.Source.NOTE_DB;
import static com.google.gerrit.server.notedb.ChangeBundle.Source.REVIEW_DB;
@@ -71,7 +71,6 @@
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
-import java.util.TreeSet;
/**
* A bundle of all entities rooted at a single {@link Change} entity.
@@ -212,23 +211,6 @@
.compare(a.get(), b.get());
}
- private static void checkColumns(Class<?> clazz, Integer... expected) {
- Set<Integer> ids = new TreeSet<>();
- for (Field f : clazz.getDeclaredFields()) {
- Column col = f.getAnnotation(Column.class);
- if (col != null) {
- ids.add(col.id());
- }
- }
- Set<Integer> expectedIds = Sets.newTreeSet(Arrays.asList(expected));
- checkState(
- ids.equals(expectedIds),
- "Unexpected column set for %s: %s != %s",
- clazz.getSimpleName(),
- ids,
- expectedIds);
- }
-
static {
// Initialization-time checks that the column set hasn't changed since the
// last time this file was updated.
diff --git a/java/com/google/gerrit/server/notedb/GroupsMigration.java b/java/com/google/gerrit/server/notedb/GroupsMigration.java
new file mode 100644
index 0000000..1ca67a4
--- /dev/null
+++ b/java/com/google/gerrit/server/notedb/GroupsMigration.java
@@ -0,0 +1,72 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.notedb;
+
+import static com.google.gerrit.server.notedb.NoteDbTable.GROUPS;
+import static com.google.gerrit.server.notedb.NotesMigration.READ;
+import static com.google.gerrit.server.notedb.NotesMigration.SECTION_NOTE_DB;
+import static com.google.gerrit.server.notedb.NotesMigration.WRITE;
+
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.util.Set;
+import org.eclipse.jgit.lib.Config;
+
+@Singleton
+public class GroupsMigration {
+ public static class Module extends AbstractModule {
+ @Override
+ public void configure() {
+ bind(GroupsMigration.class);
+ }
+ }
+
+ private final boolean writeToNoteDb;
+ private final boolean readFromNoteDb;
+
+ @Inject
+ public GroupsMigration(@GerritServerConfig Config cfg) {
+ // TODO(aliceks): Remove these flags when all other necessary TODOs for writing groups to
+ // NoteDb have been addressed.
+ // Don't flip these flags in a production setting! We only added them to spread the
+ // implementation of groups in NoteDb among several changes which are gradually merged.
+ this(
+ cfg.getBoolean(SECTION_NOTE_DB, GROUPS.key(), WRITE, false),
+ cfg.getBoolean(SECTION_NOTE_DB, GROUPS.key(), READ, false));
+ }
+
+ public GroupsMigration(boolean writeToNoteDb, boolean readFromNoteDb) {
+ this.writeToNoteDb = writeToNoteDb;
+ this.readFromNoteDb = readFromNoteDb;
+ }
+
+ public boolean writeToNoteDb() {
+ return writeToNoteDb;
+ }
+
+ public boolean readFromNoteDb() {
+ return readFromNoteDb;
+ }
+
+ public void setConfigValuesIfNotSetYet(Config cfg) {
+ Set<String> subsections = cfg.getSubsections(SECTION_NOTE_DB);
+ if (!subsections.contains(GROUPS.key())) {
+ cfg.setBoolean(SECTION_NOTE_DB, GROUPS.key(), WRITE, writeToNoteDb());
+ cfg.setBoolean(SECTION_NOTE_DB, GROUPS.key(), READ, readFromNoteDb());
+ }
+ }
+}
diff --git a/java/com/google/gerrit/server/notedb/NoteDbTable.java b/java/com/google/gerrit/server/notedb/NoteDbTable.java
index be24e28..e299fdf 100644
--- a/java/com/google/gerrit/server/notedb/NoteDbTable.java
+++ b/java/com/google/gerrit/server/notedb/NoteDbTable.java
@@ -16,6 +16,7 @@
public enum NoteDbTable {
ACCOUNTS,
+ GROUPS,
CHANGES;
public String key() {
diff --git a/java/com/google/gerrit/server/notedb/NotesMigration.java b/java/com/google/gerrit/server/notedb/NotesMigration.java
index e560ec8..bab756e 100644
--- a/java/com/google/gerrit/server/notedb/NotesMigration.java
+++ b/java/com/google/gerrit/server/notedb/NotesMigration.java
@@ -54,12 +54,12 @@
*/
public abstract class NotesMigration {
public static final String SECTION_NOTE_DB = "noteDb";
+ public static final String READ = "read";
+ public static final String WRITE = "write";
private static final String DISABLE_REVIEW_DB = "disableReviewDb";
private static final String PRIMARY_STORAGE = "primaryStorage";
- private static final String READ = "read";
private static final String SEQUENCE = "sequence";
- private static final String WRITE = "write";
public static class Module extends AbstractModule {
@Override
diff --git a/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java b/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
index eab4544..f96e96c 100644
--- a/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
+++ b/java/com/google/gerrit/server/notedb/rebuild/ChangeRebuilderImpl.java
@@ -52,7 +52,6 @@
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.GerritServerId;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.notedb.ChangeBundle;
import com.google.gerrit.server.notedb.ChangeBundleReader;
import com.google.gerrit.server.notedb.ChangeDraftUpdate;
@@ -66,6 +65,7 @@
import com.google.gerrit.server.notedb.NoteDbUpdateManager.Result;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.update.ChainedReceiveCommands;
diff --git a/java/com/google/gerrit/server/notedb/rebuild/CommentEvent.java b/java/com/google/gerrit/server/notedb/rebuild/CommentEvent.java
index 97a94d1..c8a649e 100644
--- a/java/com/google/gerrit/server/notedb/rebuild/CommentEvent.java
+++ b/java/com/google/gerrit/server/notedb/rebuild/CommentEvent.java
@@ -22,8 +22,8 @@
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.CommentsUtil;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.notedb.ChangeUpdate;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gwtorm.server.OrmException;
class CommentEvent extends Event {
diff --git a/java/com/google/gerrit/server/notedb/rebuild/DraftCommentEvent.java b/java/com/google/gerrit/server/notedb/rebuild/DraftCommentEvent.java
index 468d5b1..914930c 100644
--- a/java/com/google/gerrit/server/notedb/rebuild/DraftCommentEvent.java
+++ b/java/com/google/gerrit/server/notedb/rebuild/DraftCommentEvent.java
@@ -21,9 +21,9 @@
import com.google.gerrit.reviewdb.client.Comment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.CommentsUtil;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.notedb.ChangeDraftUpdate;
import com.google.gerrit.server.notedb.ChangeUpdate;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gwtorm.server.OrmException;
class DraftCommentEvent extends Event {
diff --git a/java/com/google/gerrit/server/diff/CharText.java b/java/com/google/gerrit/server/patch/CharText.java
similarity index 80%
rename from java/com/google/gerrit/server/diff/CharText.java
rename to java/com/google/gerrit/server/patch/CharText.java
index 110dc44..2a0cd2f 100644
--- a/java/com/google/gerrit/server/diff/CharText.java
+++ b/java/com/google/gerrit/server/patch/CharText.java
@@ -12,26 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import org.eclipse.jgit.diff.Sequence;
-public class CharText extends Sequence {
+class CharText extends Sequence {
private final String content;
- public CharText(Text text, int s, int e) {
+ CharText(Text text, int s, int e) {
content = text.getString(s, e, false /* keep LF */);
}
- public char charAt(int idx) {
+ char charAt(int idx) {
return content.charAt(idx);
}
- public boolean isLineStart(int b) {
+ boolean isLineStart(int b) {
return b == 0 || charAt(b - 1) == '\n';
}
- public boolean contains(int b, int e, char c) {
+ boolean contains(int b, int e, char c) {
for (; b < e; b++) {
if (charAt(b) == c) {
return true;
diff --git a/java/com/google/gerrit/server/diff/CharTextComparator.java b/java/com/google/gerrit/server/patch/CharTextComparator.java
similarity index 88%
rename from java/com/google/gerrit/server/diff/CharTextComparator.java
rename to java/com/google/gerrit/server/patch/CharTextComparator.java
index e8c9588..8119313 100644
--- a/java/com/google/gerrit/server/diff/CharTextComparator.java
+++ b/java/com/google/gerrit/server/patch/CharTextComparator.java
@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import org.eclipse.jgit.diff.SequenceComparator;
-public class CharTextComparator extends SequenceComparator<CharText> {
+class CharTextComparator extends SequenceComparator<CharText> {
@Override
public boolean equals(CharText a, int ai, CharText b, int bi) {
return a.charAt(ai) == b.charAt(bi);
diff --git a/java/com/google/gerrit/server/diff/ComparisonType.java b/java/com/google/gerrit/server/patch/ComparisonType.java
similarity index 97%
rename from java/com/google/gerrit/server/diff/ComparisonType.java
rename to java/com/google/gerrit/server/patch/ComparisonType.java
index f7bd276..abbb680 100644
--- a/java/com/google/gerrit/server/diff/ComparisonType.java
+++ b/java/com/google/gerrit/server/patch/ComparisonType.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
diff --git a/java/com/google/gerrit/server/diff/DiffSummary.java b/java/com/google/gerrit/server/patch/DiffSummary.java
similarity index 89%
rename from java/com/google/gerrit/server/diff/DiffSummary.java
rename to java/com/google/gerrit/server/patch/DiffSummary.java
index 1e1807e4..877dba0 100644
--- a/java/com/google/gerrit/server/diff/DiffSummary.java
+++ b/java/com/google/gerrit/server/patch/DiffSummary.java
@@ -12,13 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.gerrit.server.ioutil.BasicSerialization.readString;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeString;
import static com.google.gerrit.server.ioutil.BasicSerialization.writeVarInt32;
+import com.google.gerrit.server.query.change.ChangeData.ChangedLines;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -71,14 +72,4 @@
}
}
}
-
- public static class ChangedLines {
- public final int insertions;
- public final int deletions;
-
- public ChangedLines(int insertions, int deletions) {
- this.insertions = insertions;
- this.deletions = deletions;
- }
- }
}
diff --git a/java/com/google/gerrit/server/diff/DiffSummaryKey.java b/java/com/google/gerrit/server/patch/DiffSummaryKey.java
similarity index 97%
rename from java/com/google/gerrit/server/diff/DiffSummaryKey.java
rename to java/com/google/gerrit/server/patch/DiffSummaryKey.java
index 3e98fe2..0a02e36 100644
--- a/java/com/google/gerrit/server/diff/DiffSummaryKey.java
+++ b/java/com/google/gerrit/server/patch/DiffSummaryKey.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static org.eclipse.jgit.lib.ObjectIdSerialization.readCanBeNull;
import static org.eclipse.jgit.lib.ObjectIdSerialization.readNotNull;
@@ -53,7 +53,7 @@
this.whitespace = whitespace;
}
- public PatchListKey toPatchListKey() {
+ PatchListKey toPatchListKey() {
return new PatchListKey(
oldId, parentNum, newId, whitespace, PatchListKey.Algorithm.OPTIMIZED_DIFF);
}
diff --git a/java/com/google/gerrit/server/patch/DiffSummaryLoader.java b/java/com/google/gerrit/server/patch/DiffSummaryLoader.java
index 4df1f38..188513f 100644
--- a/java/com/google/gerrit/server/patch/DiffSummaryLoader.java
+++ b/java/com/google/gerrit/server/patch/DiffSummaryLoader.java
@@ -16,11 +16,6 @@
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.diff.DiffSummary;
-import com.google.gerrit.server.diff.DiffSummaryKey;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.ArrayList;
diff --git a/java/com/google/gerrit/server/patch/DiffSummaryWeigher.java b/java/com/google/gerrit/server/patch/DiffSummaryWeigher.java
index 863cda8..98e17a5 100644
--- a/java/com/google/gerrit/server/patch/DiffSummaryWeigher.java
+++ b/java/com/google/gerrit/server/patch/DiffSummaryWeigher.java
@@ -15,8 +15,6 @@
package com.google.gerrit.server.patch;
import com.google.common.cache.Weigher;
-import com.google.gerrit.server.diff.DiffSummary;
-import com.google.gerrit.server.diff.DiffSummaryKey;
/** Computes memory usage for {@link DiffSummary} in bytes of memory used. */
public class DiffSummaryWeigher implements Weigher<DiffSummaryKey, DiffSummary> {
diff --git a/java/com/google/gerrit/server/patch/EditTransformer.java b/java/com/google/gerrit/server/patch/EditTransformer.java
index 5e35bfa..271c7c3 100644
--- a/java/com/google/gerrit/server/patch/EditTransformer.java
+++ b/java/com/google/gerrit/server/patch/EditTransformer.java
@@ -25,7 +25,6 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
-import com.google.gerrit.server.diff.PatchListEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -183,7 +182,7 @@
}
@AutoValue
- public abstract static class ContextAwareEdit {
+ abstract static class ContextAwareEdit {
static ContextAwareEdit create(PatchListEntry patchListEntry, Edit edit) {
return create(
patchListEntry.getOldName(),
diff --git a/java/com/google/gerrit/server/diff/IntraLineDiff.java b/java/com/google/gerrit/server/patch/IntraLineDiff.java
similarity index 97%
rename from java/com/google/gerrit/server/diff/IntraLineDiff.java
rename to java/com/google/gerrit/server/patch/IntraLineDiff.java
index 15edbb3..ee8b88b 100644
--- a/java/com/google/gerrit/server/diff/IntraLineDiff.java
+++ b/java/com/google/gerrit/server/patch/IntraLineDiff.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.gerrit.server.ioutil.BasicSerialization.readEnum;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
@@ -58,12 +58,12 @@
private transient Status status;
private transient ImmutableList<Edit> edits;
- public IntraLineDiff(Status status) {
+ IntraLineDiff(Status status) {
this.status = status;
this.edits = ImmutableList.of();
}
- public IntraLineDiff(List<Edit> edits) {
+ IntraLineDiff(List<Edit> edits) {
this.status = Status.EDIT_LIST;
this.edits = ImmutableList.copyOf(edits);
}
diff --git a/java/com/google/gerrit/server/diff/IntraLineDiffArgs.java b/java/com/google/gerrit/server/patch/IntraLineDiffArgs.java
similarity index 97%
rename from java/com/google/gerrit/server/diff/IntraLineDiffArgs.java
rename to java/com/google/gerrit/server/patch/IntraLineDiffArgs.java
index 26bbe6c..882360c 100644
--- a/java/com/google/gerrit/server/diff/IntraLineDiffArgs.java
+++ b/java/com/google/gerrit/server/patch/IntraLineDiffArgs.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
diff --git a/java/com/google/gerrit/server/diff/IntraLineDiffKey.java b/java/com/google/gerrit/server/patch/IntraLineDiffKey.java
similarity index 96%
rename from java/com/google/gerrit/server/diff/IntraLineDiffKey.java
rename to java/com/google/gerrit/server/patch/IntraLineDiffKey.java
index 0e8c4ac..fbda00a 100644
--- a/java/com/google/gerrit/server/diff/IntraLineDiffKey.java
+++ b/java/com/google/gerrit/server/patch/IntraLineDiffKey.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import com.google.auto.value.AutoValue;
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
diff --git a/java/com/google/gerrit/server/patch/IntraLineLoader.java b/java/com/google/gerrit/server/patch/IntraLineLoader.java
index 002d819..e5e1bad 100644
--- a/java/com/google/gerrit/server/patch/IntraLineLoader.java
+++ b/java/com/google/gerrit/server/patch/IntraLineLoader.java
@@ -19,12 +19,6 @@
import com.google.common.collect.ImmutableList;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.CharText;
-import com.google.gerrit.server.diff.CharTextComparator;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.IntraLineDiffArgs;
-import com.google.gerrit.server.diff.IntraLineDiffKey;
-import com.google.gerrit.server.diff.Text;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.ArrayList;
diff --git a/java/com/google/gerrit/server/patch/IntraLineWeigher.java b/java/com/google/gerrit/server/patch/IntraLineWeigher.java
index 62e5f35..7bd37af 100644
--- a/java/com/google/gerrit/server/patch/IntraLineWeigher.java
+++ b/java/com/google/gerrit/server/patch/IntraLineWeigher.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Android Open Source Project
+// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,8 +15,6 @@
package com.google.gerrit.server.patch;
import com.google.common.cache.Weigher;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.IntraLineDiffKey;
/** Approximates memory usage for IntralineDiff in bytes of memory used. */
public class IntraLineWeigher implements Weigher<IntraLineDiffKey, IntraLineDiff> {
diff --git a/java/com/google/gerrit/server/diff/MergeListBuilder.java b/java/com/google/gerrit/server/patch/MergeListBuilder.java
similarity index 97%
rename from java/com/google/gerrit/server/diff/MergeListBuilder.java
rename to java/com/google/gerrit/server/patch/MergeListBuilder.java
index fdfe4b8..433fcad 100644
--- a/java/com/google/gerrit/server/diff/MergeListBuilder.java
+++ b/java/com/google/gerrit/server/patch/MergeListBuilder.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
diff --git a/java/com/google/gerrit/server/diff/PatchFile.java b/java/com/google/gerrit/server/patch/PatchFile.java
similarity index 98%
rename from java/com/google/gerrit/server/diff/PatchFile.java
rename to java/com/google/gerrit/server/patch/PatchFile.java
index 0b50ddd..aff519a 100644
--- a/java/com/google/gerrit/server/diff/PatchFile.java
+++ b/java/com/google/gerrit/server/patch/PatchFile.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static java.nio.charset.StandardCharsets.UTF_8;
diff --git a/java/com/google/gerrit/server/diff/PatchList.java b/java/com/google/gerrit/server/patch/PatchList.java
similarity index 99%
rename from java/com/google/gerrit/server/diff/PatchList.java
rename to java/com/google/gerrit/server/patch/PatchList.java
index b1b1715..16ede58 100644
--- a/java/com/google/gerrit/server/diff/PatchList.java
+++ b/java/com/google/gerrit/server/patch/PatchList.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.gerrit.server.ioutil.BasicSerialization.readBytes;
import static com.google.gerrit.server.ioutil.BasicSerialization.readVarInt32;
diff --git a/java/com/google/gerrit/server/diff/PatchListCache.java b/java/com/google/gerrit/server/patch/PatchListCache.java
similarity index 96%
rename from java/com/google/gerrit/server/diff/PatchListCache.java
rename to java/com/google/gerrit/server/patch/PatchListCache.java
index 6cff23c..728d227 100644
--- a/java/com/google/gerrit/server/diff/PatchListCache.java
+++ b/java/com/google/gerrit/server/patch/PatchListCache.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
diff --git a/java/com/google/gerrit/server/patch/PatchListCacheImpl.java b/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
index e61b08e..8900a15 100644
--- a/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
+++ b/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
@@ -26,18 +26,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.ComparisonType;
-import com.google.gerrit.server.diff.DiffSummary;
-import com.google.gerrit.server.diff.DiffSummaryKey;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.IntraLineDiffArgs;
-import com.google.gerrit.server.diff.IntraLineDiffKey;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
-import com.google.gerrit.server.diff.PatchListWeigher;
import com.google.inject.Inject;
import com.google.inject.Module;
import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/diff/PatchListEntry.java b/java/com/google/gerrit/server/patch/PatchListEntry.java
similarity index 96%
rename from java/com/google/gerrit/server/diff/PatchListEntry.java
rename to java/com/google/gerrit/server/patch/PatchListEntry.java
index fb94c70..96f66f6 100644
--- a/java/com/google/gerrit/server/diff/PatchListEntry.java
+++ b/java/com/google/gerrit/server/patch/PatchListEntry.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.gerrit.server.ioutil.BasicSerialization.readBytes;
import static com.google.gerrit.server.ioutil.BasicSerialization.readEnum;
@@ -48,7 +48,7 @@
public class PatchListEntry {
private static final byte[] EMPTY_HEADER = {};
- public static PatchListEntry empty(String fileName) {
+ static PatchListEntry empty(String fileName) {
return new PatchListEntry(
ChangeType.MODIFIED,
PatchType.UNIFIED,
@@ -77,7 +77,7 @@
// Note: When adding new fields, the serialVersionUID in PatchListKey must be
// incremented so that entries from the cache are automatically invalidated.
- public PatchListEntry(
+ PatchListEntry(
FileHeader hdr, List<Edit> editList, Set<Edit> editsDueToRebase, long size, long sizeDelta) {
changeType = toChangeType(hdr);
patchType = toPatchType(hdr);
@@ -153,7 +153,7 @@
this.sizeDelta = sizeDelta;
}
- public int weigh() {
+ int weigh() {
int size = 16 + 6 * 8 + 2 * 4 + 20 + 16 + 8 + 4 + 20;
size += stringSize(oldName);
size += stringSize(newName);
@@ -324,15 +324,15 @@
private static ChangeType toChangeType(FileHeader hdr) {
switch (hdr.getChangeType()) {
case ADD:
- return ChangeType.ADDED;
+ return Patch.ChangeType.ADDED;
case MODIFY:
- return ChangeType.MODIFIED;
+ return Patch.ChangeType.MODIFIED;
case DELETE:
- return ChangeType.DELETED;
+ return Patch.ChangeType.DELETED;
case RENAME:
- return ChangeType.RENAMED;
+ return Patch.ChangeType.RENAMED;
case COPY:
- return ChangeType.COPIED;
+ return Patch.ChangeType.COPIED;
default:
throw new IllegalArgumentException("Unsupported type " + hdr.getChangeType());
}
@@ -343,11 +343,11 @@
switch (hdr.getPatchType()) {
case UNIFIED:
- pt = PatchType.UNIFIED;
+ pt = Patch.PatchType.UNIFIED;
break;
case GIT_BINARY:
case BINARY:
- pt = PatchType.BINARY;
+ pt = Patch.PatchType.BINARY;
break;
default:
throw new IllegalArgumentException("Unsupported type " + hdr.getPatchType());
diff --git a/java/com/google/gerrit/server/diff/PatchListKey.java b/java/com/google/gerrit/server/patch/PatchListKey.java
similarity index 99%
rename from java/com/google/gerrit/server/diff/PatchListKey.java
rename to java/com/google/gerrit/server/patch/PatchListKey.java
index 357e1af..73e82a1 100644
--- a/java/com/google/gerrit/server/diff/PatchListKey.java
+++ b/java/com/google/gerrit/server/patch/PatchListKey.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.common.base.Preconditions.checkState;
import static org.eclipse.jgit.lib.ObjectIdSerialization.readCanBeNull;
diff --git a/java/com/google/gerrit/server/patch/PatchListLoader.java b/java/com/google/gerrit/server/patch/PatchListLoader.java
index 199503d..bf6e345 100644
--- a/java/com/google/gerrit/server/patch/PatchListLoader.java
+++ b/java/com/google/gerrit/server/patch/PatchListLoader.java
@@ -32,13 +32,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.ComparisonType;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
-import com.google.gerrit.server.diff.Text;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.InMemoryInserter;
import com.google.gerrit.server.git.MergeUtil;
@@ -517,7 +510,7 @@
byte[] aContent = aText.getContent();
byte[] bContent = bText.getContent();
long size = bContent.length;
- long sizeDelta = bContent.length - aContent.length;
+ long sizeDelta = size - aContent.length;
RawText aRawText = new RawText(aContent);
RawText bRawText = new RawText(bContent);
EditList edits = new HistogramDiff().diff(cmp, aRawText, bRawText);
diff --git a/java/com/google/gerrit/server/diff/PatchListNotAvailableException.java b/java/com/google/gerrit/server/patch/PatchListNotAvailableException.java
similarity index 95%
rename from java/com/google/gerrit/server/diff/PatchListNotAvailableException.java
rename to java/com/google/gerrit/server/patch/PatchListNotAvailableException.java
index 0f5981e..fab66cb 100644
--- a/java/com/google/gerrit/server/diff/PatchListNotAvailableException.java
+++ b/java/com/google/gerrit/server/patch/PatchListNotAvailableException.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
public class PatchListNotAvailableException extends Exception {
private static final long serialVersionUID = 1L;
diff --git a/java/com/google/gerrit/server/patch/PatchListObjectTooLargeException.java b/java/com/google/gerrit/server/patch/PatchListObjectTooLargeException.java
index bcb1c34..54e0e6c 100644
--- a/java/com/google/gerrit/server/patch/PatchListObjectTooLargeException.java
+++ b/java/com/google/gerrit/server/patch/PatchListObjectTooLargeException.java
@@ -14,8 +14,6 @@
package com.google.gerrit.server.patch;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
-
/**
* Exception thrown when the PatchList could not be computed because previous attempts failed with
* {@code LargeObjectException}. This is not thrown on the first computation.
diff --git a/java/com/google/gerrit/server/diff/PatchListWeigher.java b/java/com/google/gerrit/server/patch/PatchListWeigher.java
similarity index 96%
rename from java/com/google/gerrit/server/diff/PatchListWeigher.java
rename to java/com/google/gerrit/server/patch/PatchListWeigher.java
index 74b9c9b..942d0e0 100644
--- a/java/com/google/gerrit/server/diff/PatchListWeigher.java
+++ b/java/com/google/gerrit/server/patch/PatchListWeigher.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import com.google.common.cache.Weigher;
diff --git a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
index 5af2f6d..8b86be2 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
@@ -27,13 +27,6 @@
import com.google.gerrit.reviewdb.client.Comment;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.diff.ComparisonType;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.IntraLineDiffArgs;
-import com.google.gerrit.server.diff.IntraLineDiffKey;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.Text;
import com.google.gerrit.server.mime.FileTypeRegistry;
import com.google.inject.Inject;
import eu.medsea.mimeutil.MimeType;
diff --git a/java/com/google/gerrit/server/patch/PatchScriptFactory.java b/java/com/google/gerrit/server/patch/PatchScriptFactory.java
index 02aff82..fe158f8 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptFactory.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptFactory.java
@@ -32,11 +32,6 @@
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.git.GitRepositoryManager;
diff --git a/java/com/google/gerrit/server/diff/Text.java b/java/com/google/gerrit/server/patch/Text.java
similarity index 99%
rename from java/com/google/gerrit/server/diff/Text.java
rename to java/com/google/gerrit/server/patch/Text.java
index 40b8db8..90141715 100644
--- a/java/com/google/gerrit/server/diff/Text.java
+++ b/java/com/google/gerrit/server/patch/Text.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;
diff --git a/java/com/google/gerrit/server/project/GetCommit.java b/java/com/google/gerrit/server/project/GetCommit.java
index 2afeb07..d8fc5b6 100644
--- a/java/com/google/gerrit/server/project/GetCommit.java
+++ b/java/com/google/gerrit/server/project/GetCommit.java
@@ -18,12 +18,13 @@
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.git.CommitUtil;
import com.google.inject.Singleton;
+import java.io.IOException;
@Singleton
public class GetCommit implements RestReadView<CommitResource> {
@Override
- public CommitInfo apply(CommitResource rsrc) {
+ public CommitInfo apply(CommitResource rsrc) throws IOException {
return CommitUtil.toCommitInfo(rsrc.getCommit());
}
}
diff --git a/java/com/google/gerrit/server/query/change/ChangeData.java b/java/com/google/gerrit/server/query/change/ChangeData.java
index a405678..dfcc999 100644
--- a/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -63,16 +63,15 @@
import com.google.gerrit.server.change.MergeabilityCache;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.TrackingFooters;
-import com.google.gerrit.server.diff.DiffSummary;
-import com.google.gerrit.server.diff.DiffSummary.ChangedLines;
-import com.google.gerrit.server.diff.DiffSummaryKey;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.server.patch.DiffSummary;
+import com.google.gerrit.server.patch.DiffSummaryKey;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
@@ -1195,6 +1194,16 @@
return h.toString();
}
+ public static class ChangedLines {
+ public final int insertions;
+ public final int deletions;
+
+ public ChangedLines(int insertions, int deletions) {
+ this.insertions = insertions;
+ this.deletions = deletions;
+ }
+ }
+
public ImmutableList<byte[]> getRefStates() {
return refStates;
}
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 80c672e..b00345f 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -57,7 +57,6 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.strategy.SubmitDryRun;
import com.google.gerrit.server.group.ListMembers;
@@ -69,6 +68,7 @@
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ListChildProjects;
import com.google.gerrit.server.project.ProjectCache;
diff --git a/java/com/google/gerrit/server/rules/PrologEnvironment.java b/java/com/google/gerrit/server/rules/PrologEnvironment.java
index 1f93281..170ff23 100644
--- a/java/com/google/gerrit/server/rules/PrologEnvironment.java
+++ b/java/com/google/gerrit/server/rules/PrologEnvironment.java
@@ -17,8 +17,8 @@
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.diff.PatchListCache;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
diff --git a/java/com/google/gerrit/server/rules/StoredValues.java b/java/com/google/gerrit/server/rules/StoredValues.java
index 3cb322c..287845d 100644
--- a/java/com/google/gerrit/server/rules/StoredValues.java
+++ b/java/com/google/gerrit/server/rules/StoredValues.java
@@ -29,11 +29,11 @@
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.Accounts;
import com.google.gerrit.server.account.Emails;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.PatchListNotAvailableException;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/schema/NotesMigrationSchemaFactory.java b/java/com/google/gerrit/server/schema/NotesMigrationSchemaFactory.java
index d73a5f4..c80e06b 100644
--- a/java/com/google/gerrit/server/schema/NotesMigrationSchemaFactory.java
+++ b/java/com/google/gerrit/server/schema/NotesMigrationSchemaFactory.java
@@ -15,7 +15,9 @@
package com.google.gerrit.server.schema;
import com.google.gerrit.reviewdb.server.DisallowReadFromChangesReviewDbWrapper;
+import com.google.gerrit.reviewdb.server.DisallowReadFromGroupsReviewDbWrapper;
import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
@@ -26,48 +28,58 @@
public class NotesMigrationSchemaFactory implements SchemaFactory<ReviewDb> {
private final SchemaFactory<ReviewDb> delegate;
private final NotesMigration migration;
+ private final GroupsMigration groupsMigration;
@Inject
NotesMigrationSchemaFactory(
- @ReviewDbFactory SchemaFactory<ReviewDb> delegate, NotesMigration migration) {
+ @ReviewDbFactory SchemaFactory<ReviewDb> delegate,
+ NotesMigration migration,
+ GroupsMigration groupsMigration) {
this.delegate = delegate;
this.migration = migration;
+ this.groupsMigration = groupsMigration;
}
@Override
public ReviewDb open() throws OrmException {
ReviewDb db = delegate.open();
- if (!migration.readChanges()) {
- return db;
+ if (migration.readChanges()) {
+ // There are two levels at which this class disables access to Changes and related tables,
+ // corresponding to two phases of the NoteDb migration:
+ //
+ // 1. When changes are read from NoteDb but some changes might still have their primary
+ // storage in ReviewDb, it is generally programmer error to read changes from ReviewDb.
+ // However, since ReviewDb is still the primary storage for most or all changes, we still
+ // need to support writing to ReviewDb. This behavior is accomplished by wrapping in a
+ // DisallowReadFromChangesReviewDbWrapper.
+ //
+ // Some codepaths might need to be able to read from ReviewDb if they really need to,
+ // because they need to operate on the underlying source of truth, for example when
+ // reading a change to determine its primary storage. To support this,
+ // ReviewDbUtil#unwrapDb can detect and unwrap databases of this type.
+ //
+ // 2. After all changes have their primary storage in NoteDb, we can completely shut off
+ // access to the change tables. At this point in the migration, we are by definition not
+ // using the ReviewDb tables at all; we could even delete the tables at this point, and
+ // Gerrit would continue to function.
+ //
+ // This is accomplished by setting the delegate ReviewDb *underneath*
+ // DisallowReadFromChanges to be a complete no-op, with NoChangesReviewDbWrapper. With
+ // this wrapper, all read operations return no results, and write operations silently do
+ // nothing. This wrapper is not a public class and nobody should ever attempt to unwrap
+ // it.
+
+ if (migration.disableChangeReviewDb()) {
+ db = new NoChangesReviewDbWrapper(db);
+ }
+ db = new DisallowReadFromChangesReviewDbWrapper(db);
}
- // There are two levels at which this class disables access to Changes and related tables,
- // corresponding to two phases of the NoteDb migration:
- //
- // 1. When changes are read from NoteDb but some changes might still have their primary storage
- // in ReviewDb, it is generally programmer error to read changes from ReviewDb. However,
- // since ReviewDb is still the primary storage for most or all changes, we still need to
- // support writing to ReviewDb. This behavior is accomplished by wrapping in a
- // DisallowReadFromChangesReviewDbWrapper.
- //
- // Some codepaths might need to be able to read from ReviewDb if they really need to, because
- // they need to operate on the underlying source of truth, for example when reading a change
- // to determine its primary storage. To support this, ReviewDbUtil#unwrapDb can detect and
- // unwrap databases of this type.
- //
- // 2. After all changes have their primary storage in NoteDb, we can completely shut off access
- // to the change tables. At this point in the migration, we are by definition not using the
- // ReviewDb tables at all; we could even delete the tables at this point, and Gerrit would
- // continue to function.
- //
- // This is accomplished by setting the delegate ReviewDb *underneath* DisallowReadFromChanges
- // to be a complete no-op, with NoChangesReviewDbWrapper. With this wrapper, all read
- // operations return no results, and write operations silently do nothing. This wrapper is
- // not a public class and nobody should ever attempt to unwrap it.
-
- if (migration.disableChangeReviewDb()) {
- db = new NoChangesReviewDbWrapper(db);
+ if (groupsMigration.readFromNoteDb()) {
+ // If reading groups from NoteDb is configured, groups should not be read from ReviewDb.
+ // Make sure that any attempt to read a group from ReviewDb anyway fails with an exception.
+ db = new DisallowReadFromGroupsReviewDbWrapper(db);
}
- return new DisallowReadFromChangesReviewDbWrapper(db);
+ return db;
}
}
diff --git a/java/com/google/gerrit/server/schema/SchemaCreator.java b/java/com/google/gerrit/server/schema/SchemaCreator.java
index d62bde7..112fd55 100644
--- a/java/com/google/gerrit/server/schema/SchemaCreator.java
+++ b/java/com/google/gerrit/server/schema/SchemaCreator.java
@@ -45,6 +45,7 @@
import com.google.gerrit.server.group.db.InternalGroupUpdate;
import com.google.gerrit.server.index.group.GroupIndex;
import com.google.gerrit.server.index.group.GroupIndexCollection;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.update.RefUpdateUtil;
import com.google.gwtorm.jdbc.JdbcExecutor;
@@ -72,7 +73,7 @@
private final PersonIdent serverUser;
private final DataSourceType dataSourceType;
private final GroupIndexCollection indexCollection;
- private final boolean writeGroupsToNoteDb;
+ private final GroupsMigration groupsMigration;
private final Config config;
private final MetricMaker metricMaker;
@@ -89,6 +90,7 @@
@GerritPersonIdent PersonIdent au,
DataSourceType dst,
GroupIndexCollection ic,
+ GroupsMigration gm,
@GerritServerConfig Config config,
MetricMaker metricMaker,
NotesMigration migration,
@@ -102,6 +104,7 @@
au,
dst,
ic,
+ gm,
config,
metricMaker,
migration,
@@ -117,6 +120,7 @@
@GerritPersonIdent PersonIdent au,
DataSourceType dst,
GroupIndexCollection ic,
+ GroupsMigration gm,
Config config,
MetricMaker metricMaker,
NotesMigration migration,
@@ -129,11 +133,7 @@
serverUser = au;
dataSourceType = dst;
indexCollection = ic;
- // TODO(aliceks): Remove this flag when all other necessary TODOs for writing groups to NoteDb
- // have been addressed.
- // Don't flip this flag in a production setting! We only added it to spread the implementation
- // of groups in NoteDb among several changes which are gradually merged.
- writeGroupsToNoteDb = config.getBoolean("user", null, "writeGroupsToNoteDb", false);
+ groupsMigration = gm;
this.config = config;
this.allProjectsName = apName;
@@ -213,7 +213,7 @@
throws OrmException, ConfigInvalidException, IOException {
InternalGroup groupInReviewDb = createGroupInReviewDb(db, groupCreation, groupUpdate);
- if (!writeGroupsToNoteDb) {
+ if (!groupsMigration.writeToNoteDb()) {
index(groupInReviewDb);
return;
}
diff --git a/java/com/google/gerrit/server/schema/Schema_115.java b/java/com/google/gerrit/server/schema/Schema_115.java
index 7be595d..3c6a50e 100644
--- a/java/com/google/gerrit/server/schema/Schema_115.java
+++ b/java/com/google/gerrit/server/schema/Schema_115.java
@@ -26,11 +26,11 @@
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.account.VersionedAccountPreferences;
import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.diff.PatchListKey;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.UserConfigSections;
+import com.google.gerrit.server.patch.PatchListKey;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/testing/GroupNoteDbMode.java b/java/com/google/gerrit/testing/GroupNoteDbMode.java
new file mode 100644
index 0000000..9d8e557
--- /dev/null
+++ b/java/com/google/gerrit/testing/GroupNoteDbMode.java
@@ -0,0 +1,71 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.testing;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Enums;
+import com.google.common.base.Strings;
+import com.google.gerrit.server.notedb.GroupsMigration;
+
+public enum GroupNoteDbMode {
+ /** NoteDb is disabled, groups are only in ReviewDb */
+ OFF(new GroupsMigration(false, false)),
+
+ /** Writing new groups to NoteDb is enabled. */
+ WRITE(new GroupsMigration(true, false)),
+
+ /**
+ * Reading/writing groups from/to NoteDb is enabled. Trying to read groups from ReviewDb throws an
+ * exception.
+ */
+ READ_WRITE(new GroupsMigration(true, true));
+
+ private static final String ENV_VAR = "GERRIT_NOTEDB_GROUPS";
+ private static final String SYS_PROP = "gerrit.notedb.groups";
+
+ public static GroupNoteDbMode get() {
+ String value = System.getenv(ENV_VAR);
+ if (Strings.isNullOrEmpty(value)) {
+ value = System.getProperty(SYS_PROP);
+ }
+ if (Strings.isNullOrEmpty(value)) {
+ return OFF;
+ }
+ value = value.toUpperCase().replace("-", "_");
+ GroupNoteDbMode mode = Enums.getIfPresent(GroupNoteDbMode.class, value).orNull();
+ if (!Strings.isNullOrEmpty(System.getenv(ENV_VAR))) {
+ checkArgument(
+ mode != null, "Invalid value for env variable %s: %s", ENV_VAR, System.getenv(ENV_VAR));
+ } else {
+ checkArgument(
+ mode != null,
+ "Invalid value for system property %s: %s",
+ SYS_PROP,
+ System.getProperty(SYS_PROP));
+ }
+ return mode;
+ }
+
+ private final GroupsMigration groupsMigration;
+
+ private GroupNoteDbMode(GroupsMigration groupsMigration) {
+ this.groupsMigration = groupsMigration;
+ }
+
+ public GroupsMigration getGroupsMigration() {
+ return groupsMigration;
+ }
+}
diff --git a/java/gerrit/BUILD b/java/gerrit/BUILD
index ccb159b..980ad23 100644
--- a/java/gerrit/BUILD
+++ b/java/gerrit/BUILD
@@ -7,7 +7,6 @@
"//java/com/google/gerrit/extensions:api",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
- "//java/com/google/gerrit/server/diff",
"//lib:gwtorm",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/log:api",
diff --git a/java/gerrit/PRED_commit_delta_4.java b/java/gerrit/PRED_commit_delta_4.java
index 73602fd..7c26632 100644
--- a/java/gerrit/PRED_commit_delta_4.java
+++ b/java/gerrit/PRED_commit_delta_4.java
@@ -15,8 +15,8 @@
package gerrit;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListEntry;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gerrit.server.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
diff --git a/java/gerrit/PRED_commit_edits_2.java b/java/gerrit/PRED_commit_edits_2.java
index 3b5c177..c196026 100644
--- a/java/gerrit/PRED_commit_edits_2.java
+++ b/java/gerrit/PRED_commit_edits_2.java
@@ -14,9 +14,9 @@
package gerrit;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.Text;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.Text;
import com.google.gerrit.server.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.JavaException;
diff --git a/java/gerrit/PRED_commit_stats_3.java b/java/gerrit/PRED_commit_stats_3.java
index b290ba4..c1666d8 100644
--- a/java/gerrit/PRED_commit_stats_3.java
+++ b/java/gerrit/PRED_commit_stats_3.java
@@ -15,8 +15,8 @@
package gerrit;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListEntry;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gerrit.server.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupRebuilderIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupRebuilderIT.java
index bea41c3..9f98895 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupRebuilderIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupRebuilderIT.java
@@ -15,26 +15,24 @@
package com.google.gerrit.acceptance.api.group;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat;
+import static com.google.gerrit.server.notedb.NoteDbTable.GROUPS;
+import static com.google.gerrit.server.notedb.NotesMigration.READ;
+import static com.google.gerrit.server.notedb.NotesMigration.SECTION_NOTE_DB;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.TestAccount;
-import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.GerritServerId;
import com.google.gerrit.server.git.CommitUtil;
-import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.ServerInitiated;
import com.google.gerrit.server.group.db.GroupBundle;
-import com.google.gerrit.server.group.db.GroupConfig;
import com.google.gerrit.server.group.db.GroupRebuilder;
-import com.google.gerrit.server.group.db.Groups;
import com.google.gerrit.server.group.db.GroupsUpdate;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.TestTimeUtil;
@@ -44,7 +42,6 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
@@ -64,15 +61,15 @@
public static Config defaultConfig() {
Config config = new Config();
// This test is explicitly testing the migration from ReviewDb to NoteDb, and handles reading
- // from NoteDb manually. It should work regardless of the value of writeGroupsToNoteDb, however.
- config.setBoolean("user", null, "readGroupsFromNoteDb", false);
+ // from NoteDb manually. It should work regardless of the value of noteDb.groups.write, however.
+ config.setBoolean(SECTION_NOTE_DB, GROUPS.key(), READ, false);
return config;
}
@Inject @GerritServerId private String serverId;
@Inject @ServerInitiated private Provider<GroupsUpdate> groupsUpdate;
+ @Inject private GroupBundle.Factory bundleFactory;
@Inject private GroupRebuilder rebuilder;
- @Inject private Groups groups;
@Before
public void setTimeForTesting() {
@@ -88,10 +85,11 @@
public void basicGroupProperties() throws Exception {
GroupInfo createdGroup = gApi.groups().create(name("group")).get();
try (BlockReviewDbUpdatesForGroups ctx = new BlockReviewDbUpdatesForGroups()) {
- InternalGroup reviewDbGroup =
- groups.getGroup(db, new AccountGroup.UUID(createdGroup.id)).get();
- deleteGroupRefs(reviewDbGroup);
- assertThat(removeRefState(rebuild(reviewDbGroup))).isEqualTo(roundToSecond(reviewDbGroup));
+ GroupBundle reviewDbBundle =
+ bundleFactory.fromReviewDb(db, new AccountGroup.Id(createdGroup.groupId));
+ deleteGroupRefs(reviewDbBundle);
+
+ assertThat(rebuild(reviewDbBundle)).isEqualTo(reviewDbBundle.roundToSecond());
}
}
@@ -108,11 +106,12 @@
gApi.groups().id(group1.id).addGroups(group2.id);
try (BlockReviewDbUpdatesForGroups ctx = new BlockReviewDbUpdatesForGroups()) {
- InternalGroup reviewDbGroup = groups.getGroup(db, new AccountGroup.UUID(group1.id)).get();
- deleteGroupRefs(reviewDbGroup);
+ GroupBundle reviewDbBundle =
+ bundleFactory.fromReviewDb(db, new AccountGroup.Id(group1.groupId));
+ deleteGroupRefs(reviewDbBundle);
- InternalGroup noteDbGroup = rebuild(reviewDbGroup);
- assertThat(removeRefState(noteDbGroup)).isEqualTo(roundToSecond(reviewDbGroup));
+ GroupBundle noteDbBundle = rebuild(reviewDbBundle);
+ assertThat(noteDbBundle).isEqualTo(reviewDbBundle.roundToSecond());
ImmutableList<CommitInfo> log = log(group1);
assertThat(log).hasSize(4);
@@ -120,7 +119,7 @@
assertThat(log.get(0)).message().isEqualTo("Create group");
assertThat(log.get(0)).author().name().isEqualTo(serverIdent.get().getName());
assertThat(log.get(0)).author().email().isEqualTo(serverIdent.get().getEmailAddress());
- assertThat(log.get(0)).author().date().isEqualTo(noteDbGroup.getCreatedOn());
+ assertThat(log.get(0)).author().date().isEqualTo(noteDbBundle.group().getCreatedOn());
assertThat(log.get(0)).author().tz().isEqualTo(serverIdent.get().getTimeZoneOffset());
assertThat(log.get(0)).committer().isEqualTo(log.get(0).author);
@@ -151,13 +150,9 @@
}
}
- private static InternalGroup removeRefState(InternalGroup group) throws Exception {
- return group.toBuilder().setRefState(null).build();
- }
-
- private void deleteGroupRefs(InternalGroup group) throws Exception {
+ private void deleteGroupRefs(GroupBundle bundle) throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
- String refName = RefNames.refsGroups(group.getGroupUUID());
+ String refName = RefNames.refsGroups(bundle.uuid());
RefUpdate ru = repo.updateRef(refName);
ru.setForceUpdate(true);
Ref oldRef = repo.exactRef(refName);
@@ -170,30 +165,13 @@
}
}
- private InternalGroup rebuild(InternalGroup group) throws Exception {
+ private GroupBundle rebuild(GroupBundle reviewDbBundle) throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
- rebuilder.rebuild(repo, GroupBundle.fromReviewDb(db, group.getId()), null);
- GroupConfig groupConfig = GroupConfig.loadForGroup(repo, group.getGroupUUID());
- Optional<InternalGroup> result = groupConfig.getLoadedGroup();
- assertThat(result).isPresent();
- return result.get();
+ rebuilder.rebuild(repo, reviewDbBundle, null);
+ return bundleFactory.fromNoteDb(repo, reviewDbBundle.uuid());
}
}
- private InternalGroup roundToSecond(InternalGroup g) {
- return InternalGroup.builder()
- .setId(g.getId())
- .setNameKey(g.getNameKey())
- .setDescription(g.getDescription())
- .setOwnerGroupUUID(g.getOwnerGroupUUID())
- .setVisibleToAll(g.isVisibleToAll())
- .setGroupUUID(g.getGroupUUID())
- .setCreatedOn(TimeUtil.roundToSecond(g.getCreatedOn()))
- .setMembers(g.getMembers())
- .setSubgroups(g.getSubgroups())
- .build();
- }
-
private ImmutableList<CommitInfo> log(GroupInfo g) throws Exception {
ImmutableList.Builder<CommitInfo> result = ImmutableList.builder();
List<Date> commitDates = new ArrayList<>();
@@ -225,7 +203,7 @@
}
private void blockReviewDbUpdates(boolean block) {
- cfg.setBoolean("user", null, "readGroupsFromNoteDb", block);
+ cfg.setBoolean("user", null, "blockReviewDbGroupUpdates", block);
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
index b2c4056..ba92835 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
@@ -22,6 +22,10 @@
import static com.google.gerrit.acceptance.rest.account.AccountAssert.assertAccountInfos;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.server.notedb.NoteDbTable.GROUPS;
+import static com.google.gerrit.server.notedb.NotesMigration.READ;
+import static com.google.gerrit.server.notedb.NotesMigration.SECTION_NOTE_DB;
+import static com.google.gerrit.server.notedb.NotesMigration.WRITE;
import static java.util.stream.Collectors.toList;
import com.google.common.base.Throwables;
@@ -110,8 +114,8 @@
@ConfigSuite.Config
public static Config noteDbConfig() {
Config config = new Config();
- config.setBoolean("user", null, "writeGroupsToNoteDb", true);
- config.setBoolean("user", null, "readGroupsFromNoteDb", true);
+ config.setBoolean(SECTION_NOTE_DB, GROUPS.key(), WRITE, true);
+ config.setBoolean(SECTION_NOTE_DB, GROUPS.key(), READ, true);
return config;
}
@@ -774,7 +778,6 @@
@Test
public void getAuditLog() throws Exception {
- assume().that(cfg.getBoolean("user", null, "readGroupsFromNoteDb", false)).isFalse();
GroupApi g = gApi.groups().create(name("group"));
List<? extends GroupAuditEventInfo> auditEvents = g.auditLog();
assertThat(auditEvents).hasSize(1);
@@ -802,10 +805,30 @@
assertThat(auditEvents).hasSize(5);
assertAuditEvent(auditEvents.get(0), Type.REMOVE_GROUP, admin.id, otherGroup);
+ /**
+ * Make sure the new commit is created in a different second. This is added for NoteDb since the
+ * resolution of Timestamp is 1s there. Adding here is enough because the sort used in {@code
+ * GetAuditLog} is stable and we process {@code AccountGroupMemberAudit} before {@code
+ * AccountGroupByIdAud}.
+ */
+ Thread.sleep(1000);
+
+ // Add a removed member back again.
+ g.addMembers(user.username);
+ auditEvents = g.auditLog();
+ assertThat(auditEvents).hasSize(6);
+ assertAuditEvent(auditEvents.get(0), Type.ADD_USER, admin.id, user.id);
+
+ // Add a removed group back again.
+ g.addGroups(otherGroup);
+ auditEvents = g.auditLog();
+ assertThat(auditEvents).hasSize(7);
+ assertAuditEvent(auditEvents.get(0), Type.ADD_GROUP, admin.id, otherGroup);
+
Timestamp lastDate = null;
for (GroupAuditEventInfo auditEvent : auditEvents) {
if (lastDate != null) {
- assertThat(lastDate).isGreaterThan(auditEvent.date);
+ assertThat(lastDate).isAtLeast(auditEvent.date);
}
lastDate = auditEvent.date;
}
@@ -1236,7 +1259,7 @@
}
private boolean groupsInNoteDb() {
- return cfg.getBoolean("user", "writeGroupsToNoteDb", false)
- && cfg.getBoolean("user", "readGroupsFromNoteDb", false);
+ return cfg.getBoolean(SECTION_NOTE_DB, GROUPS.key(), WRITE, false)
+ && cfg.getBoolean(SECTION_NOTE_DB, GROUPS.key(), READ, false);
}
}
diff --git a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index 11c98c7..0adfafd 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -508,7 +508,7 @@
@Test
@Sandboxed
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void advertisedReferencesDontShowGroupBranchToOwnerWithoutRead() throws Exception {
createSelfOwnedGroup("Foos", user);
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
@@ -519,7 +519,7 @@
@Test
@Sandboxed
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void advertisedReferencesOmitGroupBranchesOfNonOwnedGroups() throws Exception {
allow(allUsersName, RefNames.REFS_GROUPS + "*", Permission.READ, REGISTERED_USERS);
AccountGroup.UUID users = createGroup("Users", admins, user);
@@ -534,7 +534,7 @@
@Test
@Sandboxed
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void advertisedReferencesIncludeAllGroupBranchesWithAccessDatabase() throws Exception {
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
AccountGroup.UUID users = createGroup("Users", admins);
@@ -549,7 +549,7 @@
}
@Test
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void advertisedReferencesIncludeAllGroupBranchesForAdmins() throws Exception {
allow(allUsersName, RefNames.REFS_GROUPS + "*", Permission.READ, REGISTERED_USERS);
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ADMINISTRATE_SERVER);
@@ -569,7 +569,7 @@
}
@Test
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void advertisedReferencesOmitNoteDbNotesBranches() throws Exception {
allow(allUsersName, RefNames.REFS + "*", Permission.READ, REGISTERED_USERS);
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
@@ -649,7 +649,7 @@
}
@Test
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void hideMetadata() throws Exception {
allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
try {
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
index b150df3..ba845e5 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
@@ -103,7 +103,7 @@
}
@Test
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void createGroupBranch_Conflict() throws Exception {
allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE, REGISTERED_USERS);
allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH, REGISTERED_USERS);
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
index 3abc581..c8d92c7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
@@ -140,7 +140,7 @@
}
@Test
- @GerritConfig(name = "user.writeGroupsToNoteDb", value = "true")
+ @GerritConfig(name = "noteDb.groups.write", value = "true")
public void deleteGroupBranch_Conflict() throws Exception {
allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE, REGISTERED_USERS);
allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH, REGISTERED_USERS);
diff --git a/javatests/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java b/javatests/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
index 112d0b2..4f61a56 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/PatchListCacheIT.java
@@ -27,15 +27,15 @@
import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.IntraLineDiffArgs;
-import com.google.gerrit.server.diff.IntraLineDiffKey;
-import com.google.gerrit.server.diff.PatchList;
-import com.google.gerrit.server.diff.PatchListCache;
-import com.google.gerrit.server.diff.PatchListEntry;
-import com.google.gerrit.server.diff.PatchListKey;
-import com.google.gerrit.server.diff.Text;
+import com.google.gerrit.server.patch.IntraLineDiff;
+import com.google.gerrit.server.patch.IntraLineDiffArgs;
+import com.google.gerrit.server.patch.IntraLineDiffKey;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListCacheImpl;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.PatchListKey;
+import com.google.gerrit.server.patch.Text;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import java.util.ArrayList;
diff --git a/javatests/com/google/gerrit/acceptance/tests.bzl b/javatests/com/google/gerrit/acceptance/tests.bzl
index 1b646d2..4b3b802d 100644
--- a/javatests/com/google/gerrit/acceptance/tests.bzl
+++ b/javatests/com/google/gerrit/acceptance/tests.bzl
@@ -9,10 +9,7 @@
junit_tests(
name = group,
deps = deps + [
- # j/c/g/gerrit/acceptance:lib exports all dependencies that
- # acceptance tests need. Additional dependencies should go
- # there.
- '//java/com/google/gerrit/acceptance:lib',
+ '//java/com/google/gerrit/acceptance:lib',
],
tags = labels + [
'acceptance',
diff --git a/javatests/com/google/gerrit/server/BUILD b/javatests/com/google/gerrit/server/BUILD
index 83186ff..2eaf4f5 100644
--- a/javatests/com/google/gerrit/server/BUILD
+++ b/javatests/com/google/gerrit/server/BUILD
@@ -41,7 +41,6 @@
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
- "//java/com/google/gerrit/server/diff",
"//java/com/google/gerrit/server/project/testing:project-test-util",
"//java/com/google/gerrit/testing:gerrit-test-util",
"//java/org/eclipse/jgit:server",
diff --git a/javatests/com/google/gerrit/server/diff/BUILD b/javatests/com/google/gerrit/server/diff/BUILD
deleted file mode 100644
index a136c49..0000000
--- a/javatests/com/google/gerrit/server/diff/BUILD
+++ /dev/null
@@ -1,15 +0,0 @@
-load("//tools/bzl:junit.bzl", "junit_tests")
-
-junit_tests(
- name = "diff_tests",
- srcs = glob(["**/*.java"]),
- visibility = ["//visibility:public"],
- deps = [
- "//java/com/google/gerrit/reviewdb:server",
- "//java/com/google/gerrit/server/diff",
- "//java/org/eclipse/jgit:server",
- "//lib:guava",
- "//lib:truth-java8-extension",
- "//lib/commons:codec",
- ],
-)
diff --git a/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java b/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java
new file mode 100644
index 0000000..70d5bf6
--- /dev/null
+++ b/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java
@@ -0,0 +1,143 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.group.db;
+
+import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat;
+
+import com.google.gerrit.common.TimeUtil;
+import com.google.gerrit.extensions.common.CommitInfo;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.config.AllUsersNameProvider;
+import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
+import com.google.gerrit.server.git.CommitUtil;
+import com.google.gerrit.server.git.MetaDataUpdate;
+import com.google.gerrit.testing.GerritBaseTests;
+import com.google.gerrit.testing.InMemoryRepositoryManager;
+import java.sql.Timestamp;
+import java.util.TimeZone;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+
+@Ignore
+public class AbstractGroupTest extends GerritBaseTests {
+ protected static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
+ protected static final String SERVER_ID = "server-id";
+ protected static final String SERVER_NAME = "Gerrit Server";
+ protected static final String SERVER_EMAIL = "noreply@gerritcodereview.com";
+ protected static final int SERVER_ACCOUNT_NUMBER = 100000;
+ protected static final int USER_ACCOUNT_NUMBER = 100001;
+
+ protected AllUsersName allUsersName;
+ protected InMemoryRepositoryManager repoManager;
+ protected Repository allUsersRepo;
+ protected Account.Id serverAccountId;
+ protected PersonIdent serverIdent;
+ protected Account.Id userId;
+ protected PersonIdent userIdent;
+
+ @Before
+ public void abstractGroupTestSetUp() throws Exception {
+ allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
+ repoManager = new InMemoryRepositoryManager();
+ allUsersRepo = repoManager.createRepository(allUsersName);
+ serverAccountId = new Account.Id(SERVER_ACCOUNT_NUMBER);
+ serverIdent = new PersonIdent(SERVER_NAME, SERVER_EMAIL, TimeUtil.nowTs(), TZ);
+ userId = new Account.Id(USER_ACCOUNT_NUMBER);
+ userIdent = newPersonIdent(userId, serverIdent);
+ }
+
+ @After
+ public void abstractGroupTestTearDown() throws Exception {
+ allUsersRepo.close();
+ }
+
+ protected Timestamp getTipTimestamp(AccountGroup.UUID uuid) throws Exception {
+ try (RevWalk rw = new RevWalk(allUsersRepo)) {
+ Ref ref = allUsersRepo.exactRef(RefNames.refsGroups(uuid));
+ return ref == null
+ ? null
+ : new Timestamp(rw.parseCommit(ref.getObjectId()).getAuthorIdent().getWhen().getTime());
+ }
+ }
+
+ protected void assertTipCommit(AccountGroup.UUID uuid, String expectedMessage) throws Exception {
+ try (RevWalk rw = new RevWalk(allUsersRepo)) {
+ Ref ref = allUsersRepo.exactRef(RefNames.refsGroups(uuid));
+ assertCommit(
+ CommitUtil.toCommitInfo(rw.parseCommit(ref.getObjectId()), rw),
+ expectedMessage,
+ getAccountName(userId),
+ getAccountEmail(userId));
+ }
+ }
+
+ protected static void assertServerCommit(CommitInfo commitInfo, String expectedMessage) {
+ assertCommit(commitInfo, expectedMessage, SERVER_NAME, SERVER_EMAIL);
+ }
+
+ protected static void assertCommit(
+ CommitInfo commitInfo, String expectedMessage, String expectedName, String expectedEmail) {
+ assertThat(commitInfo).message().isEqualTo(expectedMessage);
+ assertThat(commitInfo).author().name().isEqualTo(expectedName);
+ assertThat(commitInfo).author().email().isEqualTo(expectedEmail);
+
+ // Committer should always be the server, regardless of author.
+ assertThat(commitInfo).committer().name().isEqualTo(SERVER_NAME);
+ assertThat(commitInfo).committer().email().isEqualTo(SERVER_EMAIL);
+ assertThat(commitInfo).committer().date().isEqualTo(commitInfo.author.date);
+ assertThat(commitInfo).committer().tz().isEqualTo(commitInfo.author.tz);
+ }
+
+ protected MetaDataUpdate createMetaDataUpdate(PersonIdent authorIdent) {
+ MetaDataUpdate md =
+ new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, allUsersRepo);
+ md.getCommitBuilder().setAuthor(authorIdent);
+ md.getCommitBuilder().setCommitter(serverIdent); // Committer is always the server identity.
+ return md;
+ }
+
+ protected static PersonIdent newPersonIdent() {
+ return new PersonIdent(SERVER_NAME, SERVER_EMAIL, TimeUtil.nowTs(), TZ);
+ }
+
+ protected static PersonIdent newPersonIdent(Account.Id id, PersonIdent ident) {
+ return new PersonIdent(
+ getAccountName(id), getAccountEmail(id), ident.getWhen(), ident.getTimeZone());
+ }
+
+ protected static String getAccountNameEmail(Account.Id id) {
+ return String.format("%s <%s>", getAccountName(id), getAccountEmail(id));
+ }
+
+ protected static String getGroupName(AccountGroup.UUID uuid) {
+ return String.format("Group <%s>", uuid);
+ }
+
+ protected static String getAccountName(Account.Id id) {
+ return "Account " + id;
+ }
+
+ protected static String getAccountEmail(Account.Id id) {
+ return String.format("%s@%s", id, SERVER_ID);
+ }
+}
diff --git a/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java b/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java
new file mode 100644
index 0000000..321580c
--- /dev/null
+++ b/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java
@@ -0,0 +1,381 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.group.db;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.gerrit.common.TimeUtil;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
+import com.google.gerrit.server.account.GroupUUID;
+import com.google.gerrit.server.git.CommitUtil;
+import com.google.gerrit.server.group.InternalGroup;
+import java.sql.Timestamp;
+import java.util.Set;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Before;
+import org.junit.Test;
+
+/** Unit tests for {@link AuditLogReader}. */
+public final class AuditLogReaderTest extends AbstractGroupTest {
+
+ private AuditLogReader auditLogReader;
+
+ @Before
+ public void setUp() throws Exception {
+ auditLogReader = new AuditLogReader(SERVER_ID, repoManager, allUsersName);
+ }
+
+ @Test
+ public void createGroupAsUserIdent() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.UUID uuid = group.getGroupUUID();
+
+ AccountGroupMemberAudit expAudit =
+ createExpMemberAudit(group.getId(), userId, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid)).containsExactly(expAudit);
+ }
+
+ @Test
+ public void createGroupAsServerIdent() throws Exception {
+ InternalGroup group = createGroup(1, "test-group", serverIdent, null);
+ assertThat(auditLogReader.getMembersAudit(group.getGroupUUID())).hasSize(0);
+ }
+
+ @Test
+ public void addAndRemoveMember() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.UUID uuid = group.getGroupUUID();
+
+ AccountGroupMemberAudit expAudit1 =
+ createExpMemberAudit(group.getId(), userId, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid)).containsExactly(expAudit1);
+
+ // User adds account 100002 to the group.
+ Account.Id id = new Account.Id(100002);
+ addMembers(uuid, ImmutableSet.of(id));
+
+ AccountGroupMemberAudit expAudit2 =
+ createExpMemberAudit(group.getId(), id, userId, getTipTimestamp(uuid));
+ assertTipCommit(uuid, "Update group\n\nAdd: Account 100002 <100002@server-id>");
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(expAudit1, expAudit2)
+ .inOrder();
+
+ // User removes account 100002 from the group.
+ removeMembers(uuid, ImmutableSet.of(id));
+ assertTipCommit(uuid, "Update group\n\nRemove: Account 100002 <100002@server-id>");
+
+ expAudit2.removed(userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(expAudit1, expAudit2)
+ .inOrder();
+ }
+
+ @Test
+ public void addMultiMembers() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.Id groupId = group.getId();
+ AccountGroup.UUID uuid = group.getGroupUUID();
+
+ AccountGroupMemberAudit expAudit1 =
+ createExpMemberAudit(groupId, userId, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid)).containsExactly(expAudit1);
+
+ Account.Id id1 = new Account.Id(100002);
+ Account.Id id2 = new Account.Id(100003);
+ addMembers(uuid, ImmutableSet.of(id1, id2));
+
+ AccountGroupMemberAudit expAudit2 =
+ createExpMemberAudit(groupId, id1, userId, getTipTimestamp(uuid));
+ AccountGroupMemberAudit expAudit3 =
+ createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
+
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + "Add: Account 100002 <100002@server-id>\n"
+ + "Add: Account 100003 <100003@server-id>");
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(expAudit1, expAudit2, expAudit3)
+ .inOrder();
+ }
+
+ @Test
+ public void addAndRemoveSubgroups() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.UUID uuid = group.getGroupUUID();
+
+ InternalGroup subgroup = createGroupAsUser(2, "test-group-2");
+ AccountGroup.UUID subgroupUuid = subgroup.getGroupUUID();
+
+ addSubgroups(uuid, ImmutableSet.of(subgroupUuid));
+ assertTipCommit(uuid, String.format("Update group\n\nAdd-group: Group <%s>", subgroupUuid));
+
+ AccountGroupByIdAud expAudit =
+ createExpGroupAudit(group.getId(), subgroupUuid, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid)).containsExactly(expAudit);
+
+ removeSubgroups(uuid, ImmutableSet.of(subgroupUuid));
+ assertTipCommit(uuid, String.format("Update group\n\nRemove-group: Group <%s>", subgroupUuid));
+
+ expAudit.removed(userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid)).containsExactly(expAudit);
+ }
+
+ @Test
+ public void addMultiSubgroups() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.UUID uuid = group.getGroupUUID();
+
+ InternalGroup subgroup1 = createGroupAsUser(2, "test-group-2");
+ InternalGroup subgroup2 = createGroupAsUser(3, "test-group-3");
+ AccountGroup.UUID subgroupUuid1 = subgroup1.getGroupUUID();
+ AccountGroup.UUID subgroupUuid2 = subgroup2.getGroupUUID();
+
+ addSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid2));
+
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + String.format("Add-group: Group <%s>\n", subgroupUuid1)
+ + String.format("Add-group: Group <%s>", subgroupUuid2));
+
+ AccountGroupByIdAud expAudit1 =
+ createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
+ AccountGroupByIdAud expAudit2 =
+ createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid))
+ .containsExactly(expAudit1, expAudit2)
+ .inOrder();
+ }
+
+ @Test
+ public void addAndRemoveMembersAndSubgroups() throws Exception {
+ InternalGroup group = createGroupAsUser(1, "test-group");
+ AccountGroup.Id groupId = group.getId();
+ AccountGroup.UUID uuid = group.getGroupUUID();
+ AccountGroupMemberAudit expMemberAudit =
+ createExpMemberAudit(groupId, userId, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid)).containsExactly(expMemberAudit);
+
+ Account.Id id1 = new Account.Id(100002);
+ Account.Id id2 = new Account.Id(100003);
+ Account.Id id3 = new Account.Id(100004);
+ InternalGroup subgroup1 = createGroupAsUser(2, "test-group-2");
+ InternalGroup subgroup2 = createGroupAsUser(3, "test-group-3");
+ InternalGroup subgroup3 = createGroupAsUser(4, "test-group-4");
+ AccountGroup.UUID subgroupUuid1 = subgroup1.getGroupUUID();
+ AccountGroup.UUID subgroupUuid2 = subgroup2.getGroupUUID();
+ AccountGroup.UUID subgroupUuid3 = subgroup3.getGroupUUID();
+
+ // Add two accounts.
+ addMembers(uuid, ImmutableSet.of(id1, id2));
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + String.format("Add: Account %s <%s@server-id>\n", id1, id1)
+ + String.format("Add: Account %s <%s@server-id>", id2, id2));
+ AccountGroupMemberAudit expMemberAudit1 =
+ createExpMemberAudit(groupId, id1, userId, getTipTimestamp(uuid));
+ AccountGroupMemberAudit expMemberAudit2 =
+ createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(expMemberAudit, expMemberAudit1, expMemberAudit2)
+ .inOrder();
+
+ // Add one subgroup.
+ addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
+ assertTipCommit(uuid, String.format("Update group\n\nAdd-group: Group <%s>", subgroupUuid1));
+ AccountGroupByIdAud expGroupAudit1 =
+ createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid)).containsExactly(expGroupAudit1);
+
+ // Remove one account.
+ removeMembers(uuid, ImmutableSet.of(id2));
+ assertTipCommit(
+ uuid, String.format("Update group\n\nRemove: Account %s <%s@server-id>", id2, id2));
+ expMemberAudit2.removed(userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(expMemberAudit, expMemberAudit1, expMemberAudit2)
+ .inOrder();
+
+ // Add two subgroups.
+ addSubgroups(uuid, ImmutableSet.of(subgroupUuid2, subgroupUuid3));
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + String.format("Add-group: Group <%s>\n", subgroupUuid2)
+ + String.format("Add-group: Group <%s>", subgroupUuid3));
+ AccountGroupByIdAud expGroupAudit2 =
+ createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
+ AccountGroupByIdAud expGroupAudit3 =
+ createExpGroupAudit(group.getId(), subgroupUuid3, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid))
+ .containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
+ .inOrder();
+
+ // Add two account, including a removed account.
+ addMembers(uuid, ImmutableSet.of(id2, id3));
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + String.format("Add: Account %s <%s@server-id>\n", id2, id2)
+ + String.format("Add: Account %s <%s@server-id>", id3, id3));
+ AccountGroupMemberAudit expMemberAudit4 =
+ createExpMemberAudit(groupId, id2, userId, getTipTimestamp(uuid));
+ AccountGroupMemberAudit expMemberAudit3 =
+ createExpMemberAudit(groupId, id3, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getMembersAudit(uuid))
+ .containsExactly(
+ expMemberAudit, expMemberAudit1, expMemberAudit2, expMemberAudit4, expMemberAudit3)
+ .inOrder();
+
+ // Remove two subgroups.
+ removeSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid3));
+ assertTipCommit(
+ uuid,
+ "Update group\n"
+ + "\n"
+ + String.format("Remove-group: Group <%s>\n", subgroupUuid1)
+ + String.format("Remove-group: Group <%s>", subgroupUuid3));
+ expGroupAudit1.removed(userId, getTipTimestamp(uuid));
+ expGroupAudit3.removed(userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid))
+ .containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
+ .inOrder();
+
+ // Add back one removed subgroup.
+ addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
+ AccountGroupByIdAud expGroupAudit4 =
+ createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
+ assertThat(auditLogReader.getSubgroupsAudit(uuid))
+ .containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3, expGroupAudit4)
+ .inOrder();
+ }
+
+ private InternalGroup createGroupAsUser(int next, String groupName) throws Exception {
+ return createGroup(next, groupName, userIdent, userId);
+ }
+
+ private InternalGroup createGroup(
+ int next, String groupName, PersonIdent authorIdent, Account.Id authorId) throws Exception {
+ InternalGroupCreation groupCreation =
+ InternalGroupCreation.builder()
+ .setGroupUUID(GroupUUID.make(groupName, serverIdent))
+ .setNameKey(new AccountGroup.NameKey(groupName))
+ .setId(new AccountGroup.Id(next))
+ .setCreatedOn(TimeUtil.nowTs())
+ .build();
+ InternalGroupUpdate groupUpdate =
+ authorIdent.equals(serverIdent)
+ ? InternalGroupUpdate.builder().setDescription("Groups").build()
+ : InternalGroupUpdate.builder()
+ .setDescription("Groups")
+ .setMemberModification(members -> ImmutableSet.of(authorId))
+ .build();
+
+ GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsersRepo, groupCreation);
+ groupConfig.setGroupUpdate(
+ groupUpdate, AbstractGroupTest::getAccountNameEmail, AbstractGroupTest::getGroupName);
+
+ RevCommit commit = groupConfig.commit(createMetaDataUpdate(authorIdent));
+ assertCreateGroup(authorIdent, commit);
+ return groupConfig
+ .getLoadedGroup()
+ .orElseThrow(() -> new IllegalStateException("create group failed"));
+ }
+
+ private void assertCreateGroup(PersonIdent authorIdent, RevCommit commit) throws Exception {
+ if (authorIdent.equals(serverIdent)) {
+ assertServerCommit(CommitUtil.toCommitInfo(commit), "Create group");
+ } else {
+ assertCommit(
+ CommitUtil.toCommitInfo(commit),
+ String.format("Create group\n\nAdd: Account %s <%s@%s>", userId, userId, SERVER_ID),
+ getAccountName(userId),
+ getAccountEmail(userId));
+ }
+ }
+
+ private InternalGroup updateGroup(AccountGroup.UUID uuid, InternalGroupUpdate groupUpdate)
+ throws Exception {
+ GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersRepo, uuid);
+ groupConfig.setGroupUpdate(
+ groupUpdate, AbstractGroupTest::getAccountNameEmail, AbstractGroupTest::getGroupName);
+
+ groupConfig.commit(createMetaDataUpdate(userIdent));
+ return groupConfig
+ .getLoadedGroup()
+ .orElseThrow(() -> new IllegalStateException("updated group failed"));
+ }
+
+ private InternalGroup addMembers(AccountGroup.UUID groupUuid, Set<Account.Id> ids)
+ throws Exception {
+ InternalGroupUpdate update =
+ InternalGroupUpdate.builder()
+ .setMemberModification(memberIds -> Sets.union(memberIds, ids))
+ .build();
+ return updateGroup(groupUuid, update);
+ }
+
+ private InternalGroup removeMembers(AccountGroup.UUID groupUuid, Set<Account.Id> ids)
+ throws Exception {
+ InternalGroupUpdate update =
+ InternalGroupUpdate.builder()
+ .setMemberModification(memberIds -> Sets.difference(memberIds, ids))
+ .build();
+ return updateGroup(groupUuid, update);
+ }
+
+ private InternalGroup addSubgroups(AccountGroup.UUID groupUuid, Set<AccountGroup.UUID> uuids)
+ throws Exception {
+ InternalGroupUpdate update =
+ InternalGroupUpdate.builder()
+ .setSubgroupModification(memberIds -> Sets.union(memberIds, uuids))
+ .build();
+ return updateGroup(groupUuid, update);
+ }
+
+ private InternalGroup removeSubgroups(AccountGroup.UUID groupUuid, Set<AccountGroup.UUID> uuids)
+ throws Exception {
+ InternalGroupUpdate update =
+ InternalGroupUpdate.builder()
+ .setSubgroupModification(memberIds -> Sets.difference(memberIds, uuids))
+ .build();
+ return updateGroup(groupUuid, update);
+ }
+
+ private AccountGroupMemberAudit createExpMemberAudit(
+ AccountGroup.Id groupId, Account.Id id, Account.Id addedBy, Timestamp addedOn) {
+ return new AccountGroupMemberAudit(
+ new AccountGroupMemberAudit.Key(id, groupId, addedOn), addedBy);
+ }
+
+ private AccountGroupByIdAud createExpGroupAudit(
+ AccountGroup.Id groupId, AccountGroup.UUID uuid, Account.Id addedBy, Timestamp addedOn) {
+ return new AccountGroupByIdAud(new AccountGroupByIdAud.Key(groupId, uuid, addedOn), addedBy);
+ }
+}
diff --git a/javatests/com/google/gerrit/server/group/db/GroupRebuilderTest.java b/javatests/com/google/gerrit/server/group/db/GroupRebuilderTest.java
index 4e9fc7f..e2177e2 100644
--- a/javatests/com/google/gerrit/server/group/db/GroupRebuilderTest.java
+++ b/javatests/com/google/gerrit/server/group/db/GroupRebuilderTest.java
@@ -16,7 +16,6 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_GROUPNAMES;
import static com.google.gerrit.server.group.db.GroupBundle.builder;
@@ -31,58 +30,48 @@
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.db.testing.GroupTestUtil;
import com.google.gerrit.server.update.RefUpdateUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.TestTimeUtil;
import java.sql.Timestamp;
-import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
-import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-public class GroupRebuilderTest extends GerritBaseTests {
- private static final String SERVER_NAME = "Gerrit Server";
- private static final String SERVER_EMAIL = "noreply@gerritcodereview.com";
- private static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
-
+public class GroupRebuilderTest extends AbstractGroupTest {
private AtomicInteger idCounter;
private Repository repo;
private GroupRebuilder rebuilder;
+ private GroupBundle.Factory bundleFactory;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
idCounter = new AtomicInteger();
- repo = new InMemoryRepository(new DfsRepositoryDescription(AllUsersNameProvider.DEFAULT));
+ repo = repoManager.createRepository(allUsersName);
rebuilder =
new GroupRebuilder(
GroupRebuilderTest::newPersonIdent,
- new AllUsersName(AllUsersNameProvider.DEFAULT),
+ allUsersName,
(project, repo, batch) ->
new MetaDataUpdate(GitReferenceUpdated.DISABLED, project, repo, batch),
// Note that the expected name/email values in tests are not necessarily realistic,
// since they use these trivial name/email functions. GroupRebuilderIT checks the actual
// values.
- (id, ident) ->
- new PersonIdent(
- "Account " + id, id + "@server-id", ident.getWhen(), ident.getTimeZone()),
- id -> String.format("Account %s <%s@server-id>", id, id),
- uuid -> "Group " + uuid);
+ AbstractGroupTest::newPersonIdent,
+ AbstractGroupTest::getAccountNameEmail,
+ AbstractGroupTest::getGroupName);
+ bundleFactory =
+ new GroupBundle.Factory(new AuditLogReader(SERVER_ID, repoManager, allUsersName));
}
@After
@@ -97,7 +86,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(1);
assertCommit(log.get(0), "Create group", SERVER_NAME, SERVER_EMAIL);
@@ -114,7 +103,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(1);
assertServerCommit(log.get(0), "Create group");
@@ -132,7 +121,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(2);
assertServerCommit(log.get(0), "Create group");
@@ -142,8 +131,8 @@
+ "\n"
+ "Add: Account 1 <1@server-id>\n"
+ "Add: Account 2 <2@server-id>\n"
- + "Add-group: Group x\n"
- + "Add-group: Group y");
+ + "Add-group: Group <x>\n"
+ + "Add-group: Group <y>");
}
@Test
@@ -161,7 +150,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(4);
assertServerCommit(log.get(0), "Create group");
@@ -187,7 +176,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(4);
assertServerCommit(log.get(0), "Create group");
@@ -211,7 +200,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(3);
assertServerCommit(log.get(0), "Create group");
@@ -236,13 +225,13 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(4);
assertServerCommit(log.get(0), "Create group");
- assertCommit(log.get(1), "Update group\n\nAdd-group: Group y", "Account 8", "8@server-id");
- assertCommit(log.get(2), "Update group\n\nAdd-group: Group x", "Account 8", "8@server-id");
- assertCommit(log.get(3), "Update group\n\nRemove-group: Group y", "Account 9", "9@server-id");
+ assertCommit(log.get(1), "Update group\n\nAdd-group: Group <y>", "Account 8", "8@server-id");
+ assertCommit(log.get(2), "Update group\n\nAdd-group: Group <x>", "Account 8", "8@server-id");
+ assertCommit(log.get(3), "Update group\n\nRemove-group: Group <y>", "Account 9", "9@server-id");
}
@Test
@@ -257,12 +246,12 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(3);
assertServerCommit(log.get(0), "Create group");
- assertCommit(log.get(1), "Update group\n\nAdd-group: Group x", "Account 8", "8@server-id");
- assertServerCommit(log.get(2), "Update group\n\nAdd-group: Group y\nAdd-group: Group z");
+ assertCommit(log.get(1), "Update group\n\nAdd-group: Group <x>", "Account 8", "8@server-id");
+ assertServerCommit(log.get(2), "Update group\n\nAdd-group: Group <y>\nAdd-group: Group <z>");
}
@Test
@@ -287,7 +276,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(5);
assertServerCommit(log.get(0), "Create group");
@@ -306,12 +295,12 @@
log.get(3),
"Update group\n"
+ "\n"
- + "Add-group: Group x\n"
- + "Add-group: Group y\n"
- + "Add-group: Group z",
+ + "Add-group: Group <x>\n"
+ + "Add-group: Group <y>\n"
+ + "Add-group: Group <z>",
"Account 8",
"8@server-id");
- assertCommit(log.get(4), "Update group\n\nRemove-group: Group z", "Account 8", "8@server-id");
+ assertCommit(log.get(4), "Update group\n\nRemove-group: Group <z>", "Account 8", "8@server-id");
}
@Test
@@ -334,7 +323,7 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(5);
assertServerCommit(log.get(0), "Create group");
@@ -345,12 +334,12 @@
"8@server-id");
assertCommit(
log.get(2),
- "Update group\n\nAdd-group: Group x\nAdd-group: Group z",
+ "Update group\n\nAdd-group: Group <x>\nAdd-group: Group <z>",
"Account 8",
"8@server-id");
assertCommit(
log.get(3), "Update group\n\nAdd: Account 2 <2@server-id>", "Account 9", "9@server-id");
- assertCommit(log.get(4), "Update group\n\nAdd-group: Group y", "Account 9", "9@server-id");
+ assertCommit(log.get(4), "Update group\n\nAdd-group: Group <y>", "Account 9", "9@server-id");
}
@Test
@@ -369,12 +358,12 @@
rebuilder.rebuild(repo, b, null);
- assertThat(reload(g)).isEqualTo(b.toInternalGroup());
+ assertThat(reload(g)).isEqualTo(b);
ImmutableList<CommitInfo> log = log(g);
assertThat(log).hasSize(3);
assertServerCommit(log.get(0), "Create group");
- assertCommit(log.get(1), "Update group\n\nAdd-group: Group x", "Account 8", "8@server-id");
- assertServerCommit(log.get(2), "Update group\n\nAdd-group: Group y\nAdd-group: Group z");
+ assertCommit(log.get(1), "Update group\n\nAdd-group: Group <x>", "Account 8", "8@server-id");
+ assertServerCommit(log.get(2), "Update group\n\nAdd-group: Group <y>\nAdd-group: Group <z>");
assertThat(log.stream().map(c -> c.committer.date).collect(toImmutableList()))
.named("%s", log)
@@ -410,14 +399,14 @@
assertThat(log(g1)).hasSize(1);
assertThat(log(g2)).hasSize(1);
assertThat(logGroupNames()).hasSize(1);
- assertThat(reload(g1)).isEqualTo(b1.toInternalGroup());
- assertThat(reload(g2)).isEqualTo(b2.toInternalGroup());
+ assertThat(reload(g1)).isEqualTo(b1);
+ assertThat(reload(g2)).isEqualTo(b2);
assertThat(GroupTestUtil.readNameToUuidMap(repo)).containsExactly("a", "a-1", "b", "b-2");
}
- private InternalGroup reload(AccountGroup g) throws Exception {
- return removeRefState(GroupConfig.loadForGroup(repo, g.getGroupUUID()).getLoadedGroup().get());
+ private GroupBundle reload(AccountGroup g) throws Exception {
+ return bundleFactory.fromNoteDb(repo, g.getGroupUUID());
}
private AccountGroup newGroup(String name) {
@@ -487,28 +476,7 @@
return GroupTestUtil.log(repo, REFS_GROUPNAMES);
}
- private static void assertServerCommit(CommitInfo commitInfo, String expectedMessage) {
- assertCommit(commitInfo, expectedMessage, SERVER_NAME, SERVER_EMAIL);
- }
-
- private static void assertCommit(
- CommitInfo commitInfo, String expectedMessage, String expectedName, String expectedEmail) {
- assertThat(commitInfo).message().isEqualTo(expectedMessage);
- assertThat(commitInfo).author().name().isEqualTo(expectedName);
- assertThat(commitInfo).author().email().isEqualTo(expectedEmail);
-
- // Committer should always be the server, regardless of author.
- assertThat(commitInfo).committer().name().isEqualTo(SERVER_NAME);
- assertThat(commitInfo).committer().email().isEqualTo(SERVER_EMAIL);
- assertThat(commitInfo).committer().date().isEqualTo(commitInfo.author.date);
- assertThat(commitInfo).committer().tz().isEqualTo(commitInfo.author.tz);
- }
-
private static InternalGroup removeRefState(InternalGroup group) throws Exception {
return group.toBuilder().setRefState(null).build();
}
-
- private static PersonIdent newPersonIdent() {
- return new PersonIdent(SERVER_NAME, SERVER_EMAIL, TimeUtil.nowTs(), TZ);
- }
}
diff --git a/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java b/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
index c1a0ac8..eb31abd 100644
--- a/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
+++ b/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
@@ -18,8 +18,6 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.server.diff.IntraLineDiff;
-import com.google.gerrit.server.diff.Text;
import java.util.List;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
diff --git a/javatests/com/google/gerrit/server/patch/PatchListCacheTest.java b/javatests/com/google/gerrit/server/patch/PatchListCacheTest.java
deleted file mode 100644
index 788802c..0000000
--- a/javatests/com/google/gerrit/server/patch/PatchListCacheTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.patch;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.gerrit.server.patch.PatchListCacheImpl.LargeObjectTombstone;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import org.junit.Test;
-
-public class PatchListCacheTest {
- @Test
- public void largeObjectTombstoneCanBeSerializedAndDeserialized() throws Exception {
- // Serialize
- byte[] serializedObject;
- try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream objectStream = new ObjectOutputStream(baos)) {
- objectStream.writeObject(new LargeObjectTombstone());
- serializedObject = baos.toByteArray();
- assertThat(serializedObject).isNotNull();
- }
- // Deserialize
- try (InputStream is = new ByteArrayInputStream(serializedObject);
- ObjectInputStream ois = new ObjectInputStream(is)) {
- assertThat(ois.readObject()).isInstanceOf(LargeObjectTombstone.class);
- }
- }
-}
diff --git a/javatests/com/google/gerrit/server/diff/PatchListEntryTest.java b/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
similarity index 96%
rename from javatests/com/google/gerrit/server/diff/PatchListEntryTest.java
rename to javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
index 49f5815..81f03af 100644
--- a/javatests/com/google/gerrit/server/diff/PatchListEntryTest.java
+++ b/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
diff --git a/javatests/com/google/gerrit/server/diff/PatchListTest.java b/javatests/com/google/gerrit/server/patch/PatchListTest.java
similarity index 67%
rename from javatests/com/google/gerrit/server/diff/PatchListTest.java
rename to javatests/com/google/gerrit/server/patch/PatchListTest.java
index 03c1515..0a7b97cc 100644
--- a/javatests/com/google/gerrit/server/diff/PatchListTest.java
+++ b/javatests/com/google/gerrit/server/patch/PatchListTest.java
@@ -12,11 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.server.diff;
+package com.google.gerrit.server.patch;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.reviewdb.client.Patch;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Comparator;
import org.junit.Test;
@@ -65,4 +70,21 @@
});
assertThat(names).isEqualTo(want);
}
+
+ @Test
+ public void largeObjectTombstoneCanBeSerializedAndDeserialized() throws Exception {
+ // Serialize
+ byte[] serializedObject;
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream objectStream = new ObjectOutputStream(baos)) {
+ objectStream.writeObject(new PatchListCacheImpl.LargeObjectTombstone());
+ serializedObject = baos.toByteArray();
+ assertThat(serializedObject).isNotNull();
+ }
+ // Deserialize
+ try (InputStream is = new ByteArrayInputStream(serializedObject);
+ ObjectInputStream ois = new ObjectInputStream(is)) {
+ assertThat(ois.readObject()).isInstanceOf(PatchListCacheImpl.LargeObjectTombstone.class);
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/server/schema/SchemaUpdaterTest.java b/javatests/com/google/gerrit/server/schema/SchemaUpdaterTest.java
index bdcee40..e4b0da5 100644
--- a/javatests/com/google/gerrit/server/schema/SchemaUpdaterTest.java
+++ b/javatests/com/google/gerrit/server/schema/SchemaUpdaterTest.java
@@ -32,6 +32,7 @@
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.group.SystemGroupBackend;
+import com.google.gerrit.server.notedb.GroupsMigration;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.testing.InMemoryDatabase;
import com.google.gerrit.testing.InMemoryH2Type;
@@ -115,6 +116,7 @@
bind(SystemGroupBackend.class);
install(new NotesMigration.Module());
+ install(new GroupsMigration.Module());
bind(MetricMaker.class).to(DisabledMetricMaker.class);
}
})
diff --git a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html
index 25bb545..9745f9e 100644
--- a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html
+++ b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html
@@ -212,11 +212,11 @@
* Check whether there is no newer patch than the latest patch that was
* available when this change was loaded.
*
- * @return {Promise<boolean>} A promise that yields true if the latest patch
+ * @return {Promise<!Object>} A promise that yields true if the latest patch
* has been loaded, and false if a newer patch has been uploaded in the
* meantime. The promise is rejected on network error.
*/
- fetchIsLatestKnown(change, restAPI) {
+ fetchChangeUpdates(change, restAPI) {
const knownLatest = Gerrit.PatchSetBehavior.computeLatestPatchNum(
Gerrit.PatchSetBehavior.computeAllPatchSets(change));
return restAPI.getChangeDetail(change._number)
@@ -226,7 +226,11 @@
}
const actualLatest = Gerrit.PatchSetBehavior.computeLatestPatchNum(
Gerrit.PatchSetBehavior.computeAllPatchSets(detail));
- return actualLatest <= knownLatest;
+ return {
+ isLatest: actualLatest <= knownLatest,
+ newStatus: change.status !== detail.status ? detail.status : null,
+ newMessages: change.messages.length < detail.messages.length,
+ };
});
},
diff --git a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
index bad47b9..7116c5d 100644
--- a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
@@ -35,31 +35,37 @@
assert.equal(get(revisions, '3'), undefined);
});
- test('fetchIsLatestKnown on latest', done => {
+ test('fetchChangeUpdates on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
+ status: 'NEW',
+ messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(knownChange);
},
};
- Gerrit.PatchSetBehavior.fetchIsLatestKnown(knownChange, mockRestApi)
- .then(isLatest => {
- assert.isTrue(isLatest);
+ Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
+ .then(result => {
+ assert.isTrue(result.isLatest);
+ assert.isNotOk(result.newStatus);
+ assert.isFalse(result.newMessages);
done();
});
});
- test('fetchIsLatestKnown not on latest', done => {
+ test('fetchChangeUpdates not on latest', done => {
const knownChange = {
revisions: {
sha1: {description: 'patch 1', _number: 1},
sha2: {description: 'patch 2', _number: 2},
},
+ status: 'NEW',
+ messages: [],
};
const actualChange = {
revisions: {
@@ -67,15 +73,81 @@
sha2: {description: 'patch 2', _number: 2},
sha3: {description: 'patch 3', _number: 3},
},
+ status: 'NEW',
+ messages: [],
};
const mockRestApi = {
getChangeDetail() {
return Promise.resolve(actualChange);
},
};
- Gerrit.PatchSetBehavior.fetchIsLatestKnown(knownChange, mockRestApi)
- .then(isLatest => {
- assert.isFalse(isLatest);
+ Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
+ .then(result => {
+ assert.isFalse(result.isLatest);
+ assert.isNotOk(result.newStatus);
+ assert.isFalse(result.newMessages);
+ done();
+ });
+ });
+
+ test('fetchChangeUpdates new status', done => {
+ const knownChange = {
+ revisions: {
+ sha1: {description: 'patch 1', _number: 1},
+ sha2: {description: 'patch 2', _number: 2},
+ },
+ status: 'NEW',
+ messages: [],
+ };
+ const actualChange = {
+ revisions: {
+ sha1: {description: 'patch 1', _number: 1},
+ sha2: {description: 'patch 2', _number: 2},
+ },
+ status: 'MERGED',
+ messages: [],
+ };
+ const mockRestApi = {
+ getChangeDetail() {
+ return Promise.resolve(actualChange);
+ },
+ };
+ Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
+ .then(result => {
+ assert.isTrue(result.isLatest);
+ assert.equal(result.newStatus, 'MERGED');
+ assert.isFalse(result.newMessages);
+ done();
+ });
+ });
+
+ test('fetchChangeUpdates new messages', done => {
+ const knownChange = {
+ revisions: {
+ sha1: {description: 'patch 1', _number: 1},
+ sha2: {description: 'patch 2', _number: 2},
+ },
+ status: 'NEW',
+ messages: [],
+ };
+ const actualChange = {
+ revisions: {
+ sha1: {description: 'patch 1', _number: 1},
+ sha2: {description: 'patch 2', _number: 2},
+ },
+ status: 'NEW',
+ messages: [{message: 'blah blah'}],
+ };
+ const mockRestApi = {
+ getChangeDetail() {
+ return Promise.resolve(actualChange);
+ },
+ };
+ Gerrit.PatchSetBehavior.fetchChangeUpdates(knownChange, mockRestApi)
+ .then(result => {
+ assert.isTrue(result.isLatest);
+ assert.isNotOk(result.newStatus);
+ assert.isTrue(result.newMessages);
done();
});
});
diff --git a/polygerrit-ui/app/elements/admin/gr-project/gr-project.js b/polygerrit-ui/app/elements/admin/gr-project/gr-project.js
index 0f14088..b54824b 100644
--- a/polygerrit-ui/app/elements/admin/gr-project/gr-project.js
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project.js
@@ -165,7 +165,7 @@
_formatBooleanSelect(item) {
if (!item) { return; }
let inheritLabel = 'Inherit';
- if (item.inherited_value) {
+ if (!(item.inherited_value === undefined)) {
inheritLabel = `Inherit (${item.inherited_value})`;
}
return [
diff --git a/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
index 4decadb..ce7fe80 100644
--- a/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-project/gr-project_test.html
@@ -166,7 +166,7 @@
});
test('_formatBooleanSelect', () => {
- let item = {inherited_value: 'true'};
+ let item = {inherited_value: true};
assert.deepEqual(element._formatBooleanSelect(item), [
{
label: 'Inherit (true)',
@@ -181,6 +181,21 @@
},
]);
+ item = {inherited_value: false};
+ assert.deepEqual(element._formatBooleanSelect(item), [
+ {
+ label: 'Inherit (false)',
+ value: 'INHERIT',
+ },
+ {
+ label: 'True',
+ value: 'TRUE',
+ }, {
+ label: 'False',
+ value: 'FALSE',
+ },
+ ]);
+
// For items without inherited values
item = {};
assert.deepEqual(element._formatBooleanSelect(item), [
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
index 8007993..481cd76 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
@@ -52,11 +52,6 @@
/* px because don't have the same font size */
margin-left: 12px;
}
- gr-button[data-action-key='submit'] {
- --gr-button-background: #f67070;
- --gr-button-color: #fff;
- --gr-button-hover-background-color: #dc5151;
- }
#actionLoadingMessage {
align-items: center;
color: #777;
@@ -107,11 +102,6 @@
on-tap="_handleActionTap">[[action.label]]</gr-button>
</template>
</section>
- <gr-button
- class="reply"
- secondary
- disabled="[[replyDisabled]]"
- on-tap="_handleReplyTap">[[replyButtonLabel]]</gr-button>
<section id="secondaryActions"
hidden$="[[_shouldHideActions(_topLevelActions.*, _loading)]]">
<template
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index c86c251..b2a6f0d 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -160,12 +160,6 @@
* @event reload-change
*/
- /**
- * Fired when the reply button is tapped.
- *
- * @event reply-tap
- */
-
/**
* Fired when an action is tapped.
*
@@ -214,8 +208,6 @@
type: Object,
value() { return {}; },
},
- replyButtonLabel: String,
- replyDisabled: Boolean,
_loading: {
type: Boolean,
@@ -729,11 +721,6 @@
this._showActionDialog(this.$.confirmRevertDialog);
},
- _handleReplyTap(e) {
- e.preventDefault();
- this.dispatchEvent(new CustomEvent('reply-tap'));
- },
-
_handleActionTap(e) {
e.preventDefault();
const el = Polymer.dom(e).localTarget;
@@ -1062,9 +1049,9 @@
this._handleResponseError(response);
};
- return this.fetchIsLatestKnown(this.change, this.$.restAPI)
- .then(isLatest => {
- if (!isLatest) {
+ return this.fetchChangeUpdates(this.change, this.$.restAPI)
+ .then(result => {
+ if (!result.isLatest) {
this.fire('show-alert', {
message: 'Cannot set label: a newer patch has been ' +
'uploaded to this change.',
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
index a3932c2..62b4626 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -194,7 +194,7 @@
const buttonEls = Polymer.dom(element.root)
.querySelectorAll('gr-button');
const menuItems = element.$.moreActions.items;
- assert.equal(buttonEls.length + menuItems.length, 7);
+ assert.equal(buttonEls.length + menuItems.length, 6);
assert.isFalse(element.hidden);
done();
});
@@ -241,8 +241,8 @@
test('submit change', done => {
sandbox.stub(element.$.restAPI, 'getFromProjectLookup')
.returns(Promise.resolve('test'));
- sandbox.stub(element, 'fetchIsLatestKnown',
- () => { return Promise.resolve(true); });
+ sandbox.stub(element, 'fetchChangeUpdates',
+ () => { return Promise.resolve({isLatest: true}); });
element.change = {
revisions: {
rev1: {_number: 1},
@@ -1264,8 +1264,8 @@
let sendStub;
setup(() => {
- sandbox.stub(element, 'fetchIsLatestKnown')
- .returns(Promise.resolve(true));
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: true}));
sendStub = sandbox.stub(element.$.restAPI, 'getChangeURLAndSend')
.returns(Promise.resolve({}));
});
@@ -1293,8 +1293,8 @@
suite('failure modes', () => {
test('non-latest', () => {
- sandbox.stub(element, 'fetchIsLatestKnown')
- .returns(Promise.resolve(false));
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: false}));
const sendStub = sandbox.stub(element.$.restAPI,
'getChangeURLAndSend');
@@ -1307,8 +1307,8 @@
});
test('send fails', () => {
- sandbox.stub(element, 'fetchIsLatestKnown')
- .returns(Promise.resolve(true));
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: true}));
const sendStub = sandbox.stub(element.$.restAPI,
'getChangeURLAndSend',
(num, method, patchNum, endpoint, payload, onErr) => {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
index eff4345..936b284 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
@@ -329,6 +329,7 @@
</span>
</section>
<gr-endpoint-decorator name="change-metadata-item">
+ <gr-endpoint-param name="change" value="[[change]]"></gr-endpoint-param>
</gr-endpoint-decorator>
</gr-external-style>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 3365098..9e58204 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -87,6 +87,9 @@
.header-title .headerSubject {
font-family: var(--font-family-bold);
}
+ .replyContainer {
+ margin-bottom: 1em;
+ }
gr-change-star {
margin-right: .25em;
vertical-align: -.425em;
@@ -133,6 +136,10 @@
}
.editCommitMessage {
margin-top: 1em;
+ --gr-button: {
+ padding-left: 0;
+ padding-right: 0;
+ }
}
.changeStatuses,
.commitActions {
@@ -343,8 +350,7 @@
edit-loaded="[[_editLoaded]]"
edit-based-on-current-patch-set="[[hasEditBasedOnCurrentPatchSet(_allPatchSets)]]"
on-reload-change="_handleReloadChange"
- on-download-tap="_handleOpenDownloadDialog"
- on-reply-tap="_handleReplyTap"></gr-change-actions>
+ on-download-tap="_handleOpenDownloadDialog"></gr-change-actions>
</div><!-- end commit actions -->
</div><!-- end header -->
<section class="changeInfo">
@@ -365,6 +371,14 @@
<hr class="mobile">
<div id="commitAndRelated" class="hideOnMobileOverlay">
<div class="commitContainer">
+ <div class="replyContainer">
+ <gr-button
+ id="replyBtn"
+ class="reply"
+ secondary
+ disabled="[[_replyDisabled]]"
+ on-tap="_handleReplyTap">[[_replyButtonLabel]]</gr-button>
+ </div>
<div
id="commitMessage"
class$="commitMessage [[_computeCommitClass(_commitCollapsed, _latestCommitMessage)]]">
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index a4f621b..cd56752 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -41,6 +41,14 @@
const TRAILING_WHITESPACE_REGEX = /[ \t]+$/gm;
+ const ReloadToastMessage = {
+ NEWER_REVISION: 'A newer patch set has been uploaded',
+ RESTORED: 'This change has been restored',
+ ABANDONED: 'This change has been abandoned',
+ MERGED: 'This change has been merged',
+ NEW_MESSAGE: 'There are new messages on this change',
+ };
+
Polymer({
is: 'gr-change-view',
@@ -1241,23 +1249,37 @@
}
this._updateCheckTimerHandle = this.async(() => {
- this.fetchIsLatestKnown(this._change, this.$.restAPI)
- .then(latest => {
- if (latest) {
- this._startUpdateCheckTimer();
- } else {
- this._cancelUpdateCheckTimer();
- this.fire('show-alert', {
- message: 'A newer patch set has been uploaded.',
- // Persist this alert.
- dismissOnNavigation: true,
- action: 'Reload',
- callback: function() {
- // Load the current change without any patch range.
- Gerrit.Nav.navigateToChange(this._change);
- }.bind(this),
- });
+ this.fetchChangeUpdates(this._change, this.$.restAPI)
+ .then(result => {
+ let toastMessage = null;
+ if (!result.isLatest) {
+ toastMessage = ReloadToastMessage.NEWER_REVISION;
+ } else if (result.newStatus === this.ChangeStatus.MERGED) {
+ toastMessage = ReloadToastMessage.MERGED;
+ } else if (result.newStatus === this.ChangeStatus.ABANDONED) {
+ toastMessage = ReloadToastMessage.ABANDONED;
+ } else if (result.newStatus === this.ChangeStatus.NEW) {
+ toastMessage = ReloadToastMessage.RESTORED;
+ } else if (result.newMessages) {
+ toastMessage = ReloadToastMessage.NEW_MESSAGE;
}
+
+ if (!toastMessage) {
+ this._startUpdateCheckTimer();
+ return;
+ }
+
+ this._cancelUpdateCheckTimer();
+ this.fire('show-alert', {
+ message: toastMessage,
+ // Persist this alert.
+ dismissOnNavigation: true,
+ action: 'Reload',
+ callback: function() {
+ // Load the current change without any patch range.
+ Gerrit.Nav.navigateToChange(this._change);
+ }.bind(this),
+ });
});
}, this._serverConfig.change.update_delay * 1000);
},
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index 7d81f4d..4a4cd5c 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -120,8 +120,8 @@
test('A toggles overlay when logged in', done => {
sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
- sandbox.stub(element.$.replyDialog, 'fetchIsLatestKnown')
- .returns(Promise.resolve(true));
+ sandbox.stub(element.$.replyDialog, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: true}));
element._change = {labels: {}};
const openSpy = sandbox.spy(element, '_openReplyDialog');
@@ -840,14 +840,16 @@
});
});
- test('_openReplyDialog called with `ANY` when coming from tap event', () => {
- const openStub = sandbox.stub(element, '_openReplyDialog');
- element.$.actions.fire('reply-tap');
- assert(openStub.lastCall.calledWithExactly(
- element.$.replyDialog.FocusTarget.ANY),
- '_openReplyDialog should have been passed ANY');
- assert.equal(openStub.callCount, 1);
- });
+ test('_openReplyDialog called with `ANY` when coming from tap event',
+ () => {
+ const openStub = sandbox.stub(element, '_openReplyDialog');
+ element._serverConfig = {};
+ MockInteractions.tap(element.$.replyBtn);
+ assert(openStub.lastCall.calledWithExactly(
+ element.$.replyDialog.FocusTarget.ANY),
+ '_openReplyDialog should have been passed ANY');
+ assert.equal(openStub.callCount, 1);
+ });
test('_openReplyDialog called with `BODY` when coming from message reply' +
'event', () => {
@@ -967,8 +969,8 @@
suite('reply dialog tests', () => {
setup(() => {
sandbox.stub(element.$.replyDialog, '_draftChanged');
- sandbox.stub(element.$.replyDialog, 'fetchIsLatestKnown',
- () => { return Promise.resolve(true); });
+ sandbox.stub(element.$.replyDialog, 'fetchChangeUpdates',
+ () => { return Promise.resolve({isLatest: true}); });
element._change = {labels: {}};
});
@@ -1018,8 +1020,8 @@
suite('commit message expand/collapse', () => {
setup(() => {
- sandbox.stub(element, 'fetchIsLatestKnown',
- () => { return Promise.resolve(false); });
+ sandbox.stub(element, 'fetchChangeUpdates',
+ () => { return Promise.resolve({isLatest: false}); });
});
test('commitCollapseToggle hidden for short commit message', () => {
@@ -1169,29 +1171,58 @@
});
test('_startUpdateCheckTimer negative delay', () => {
- sandbox.stub(element, 'fetchIsLatestKnown');
+ sandbox.stub(element, 'fetchChangeUpdates');
element._serverConfig = {change: {update_delay: -1}};
assert.isTrue(element._startUpdateCheckTimer.called);
- assert.isFalse(element.fetchIsLatestKnown.called);
+ assert.isFalse(element.fetchChangeUpdates.called);
});
test('_startUpdateCheckTimer up-to-date', () => {
- sandbox.stub(element, 'fetchIsLatestKnown',
- () => { return Promise.resolve(true); });
+ sandbox.stub(element, 'fetchChangeUpdates',
+ () => { return Promise.resolve({isLatest: true}); });
element._serverConfig = {change: {update_delay: 12345}};
assert.isTrue(element._startUpdateCheckTimer.called);
- assert.isTrue(element.fetchIsLatestKnown.called);
+ assert.isTrue(element.fetchChangeUpdates.called);
assert.equal(element.async.lastCall.args[1], 12345 * 1000);
});
test('_startUpdateCheckTimer out-of-date shows an alert', done => {
- sandbox.stub(element, 'fetchIsLatestKnown',
- () => { return Promise.resolve(false); });
- element.addEventListener('show-alert', () => {
+ sandbox.stub(element, 'fetchChangeUpdates',
+ () => { return Promise.resolve({isLatest: false}); });
+ element.addEventListener('show-alert', e => {
+ assert.equal(e.detail.message,
+ 'A newer patch set has been uploaded');
+ done();
+ });
+ element._serverConfig = {change: {update_delay: 12345}};
+ });
+
+ test('_startUpdateCheckTimer new status shows an alert', done => {
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({
+ isLatest: true,
+ newStatus: element.ChangeStatus.MERGED,
+ }));
+ element.addEventListener('show-alert', e => {
+ assert.equal(e.detail.message, 'This change has been merged');
+ done();
+ });
+ element._serverConfig = {change: {update_delay: 12345}};
+ });
+
+ test('_startUpdateCheckTimer new messages shows an alert', done => {
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({
+ isLatest: true,
+ newMessages: true,
+ }));
+ element.addEventListener('show-alert', e => {
+ assert.equal(e.detail.message,
+ 'There are new messages on this change');
done();
});
element._serverConfig = {change: {update_delay: 12345}};
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
index 780dca2..0143196 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
@@ -76,6 +76,12 @@
clear() {
this.loading = true;
this.hidden = true;
+
+ this._relatedResponse = {changes: []};
+ this._submittedTogether = [];
+ this._conflicts = [];
+ this._cherryPicks = [];
+ this._sameTopic = [];
},
reload() {
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
index df4391e..c035b44 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
@@ -337,12 +337,37 @@
true);
});
- test('clear hides', () => {
+ test('clear and empties', () => {
+ const changes = [{
+ project: 'foo/bar',
+ change_id: 'Ideadbeef',
+ commit: {
+ commit: 'deadbeef',
+ parents: [{commit: 'abc123'}],
+ author: {},
+ subject: 'do that thing',
+ },
+ _change_number: 12345,
+ _revision_number: 1,
+ _current_revision_number: 1,
+ status: 'NEW',
+ }];
+ element._relatedResponse = {changes};
+ element._submittedTogether = changes;
+ element._conflicts = changes;
+ element._cherryPicks = changes;
+ element._sameTopic = changes;
+
element.loading = false;
element.hidden = false;
element.clear();
assert.isTrue(element.loading);
assert.isTrue(element.hidden);
+ assert.equal(element._relatedResponse.changes.length, 0);
+ assert.equal(element._submittedTogether.length, 0);
+ assert.equal(element._conflicts.length, 0);
+ assert.equal(element._cherryPicks.length, 0);
+ assert.equal(element._sameTopic.length, 0);
});
test('update fires', () => {
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 babd95c..22b53c8 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
@@ -86,7 +86,8 @@
],
};
element.serverConfig = {note_db_enabled: true};
- sandbox.stub(element, 'fetchIsLatestKnown', () => Promise.resolve(true));
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: true}));
};
setup(() => {
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 1830216..6a41652 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -237,9 +237,9 @@
open(opt_focusTarget) {
this.knownLatestState = LatestPatchState.CHECKING;
- this.fetchIsLatestKnown(this.change, this.$.restAPI)
- .then(isUpToDate => {
- this.knownLatestState = isUpToDate ?
+ this.fetchChangeUpdates(this.change, this.$.restAPI)
+ .then(result => {
+ this.knownLatestState = result.isLatest ?
LatestPatchState.LATEST : LatestPatchState.NOT_LATEST;
});
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index 3cede6a..9c19267 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -103,8 +103,8 @@
eraseDraftCommentStub = sandbox.stub(element.$.storage,
'eraseDraftComment');
- sandbox.stub(element, 'fetchIsLatestKnown',
- () => { return Promise.resolve(true); });
+ sandbox.stub(element, 'fetchChangeUpdates')
+ .returns(Promise.resolve({isLatest: true}));
// Allow the elements created by dom-repeat to be stamped.
flushAsynchronousOperations();
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
index 5dbd466..55164e0 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
@@ -48,7 +48,7 @@
<span class="title">Username</span>
<span
hidden$="[[usernameMutable]]"
- class="value">[[_account.username]]</span>
+ class="value">[[_username]]</span>
<span
hidden$="[[!usernameMutable]]"
class="value">
@@ -57,7 +57,7 @@
id="usernameInput"
disabled="[[_saving]]"
on-keydown="_handleKeydown"
- bind-value="{{_account.username}}">
+ bind-value="{{_username}}">
</section>
<section id="nameSection">
<span class="title">Full name</span>
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
index 03795f6..a698c71 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.js
@@ -27,7 +27,7 @@
usernameMutable: {
type: Boolean,
notify: true,
- computed: '_computeUsernameMutable(_serverConfig)',
+ computed: '_computeUsernameMutable(_serverConfig, _account.username)',
},
nameMutable: {
type: Boolean,
@@ -64,11 +64,14 @@
/** @type {?} */
_account: Object,
_serverConfig: Object,
+ _username: {
+ type: String,
+ observer: '_usernameChanged',
+ },
},
observers: [
'_nameChanged(_account.name)',
- '_usernameChanged(_account.username)',
'_statusChanged(_account.status)',
],
@@ -82,7 +85,11 @@
}));
promises.push(this.$.restAPI.getAccount().then(account => {
+ // Provide predefined value for username to trigger computation of
+ // username mutability.
+ account.username = account.username || '';
this._account = account;
+ this._username = account.username;
}));
return Promise.all(promises).then(() => {
@@ -117,7 +124,7 @@
_maybeSetUsername() {
return this._hasUsernameChange && this.usernameMutable ?
- this.$.restAPI.setAccountUsername(this._account.username) :
+ this.$.restAPI.setAccountUsername(this._username) :
Promise.resolve();
},
@@ -131,8 +138,10 @@
return nameChanged || usernameChanged || statusChanged;
},
- _computeUsernameMutable(config) {
- return config.auth.editable_account_fields.includes('USER_NAME');
+ _computeUsernameMutable(config, username) {
+ // Username may not be changed once it is set.
+ return config.auth.editable_account_fields.includes('USER_NAME') &&
+ !username;
},
_computeNameMutable(config) {
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
index e46be5b..d27d153 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
@@ -123,6 +123,8 @@
test('username render (mutable)', () => {
element.set('_serverConfig',
{auth: {editable_account_fields: ['USER_NAME']}});
+ element.set('_account.username', '');
+ element.set('_username', '');
const section = element.$.usernameSection;
const displaySpan = section.querySelectorAll('.value')[0];
@@ -179,10 +181,11 @@
});
test('username', done => {
+ element.set('_account.username', '');
+ element._hasUsernameChange = false;
assert.isTrue(element.usernameMutable);
- assert.isFalse(element.hasUnsavedChanges);
- element.set('_account.username', 'new username');
+ element.set('_username', 'new username');
assert.isTrue(usernameChangedSpy.called);
assert.isFalse(statusChangedSpy.called);
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
index 6918f30..a56394e 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
@@ -75,7 +75,7 @@
/* styles for raised buttons specifically*/
:host([primary]) paper-button[raised],
:host([secondary]) paper-button[raised] {
- background-color: var(--gr-button-background, --color-link);
+ background-color: var(--color-link);
color: #fff;
}
:host([primary]) paper-button[raised]:hover,
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 55acfd5..45def55 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -845,6 +845,7 @@
this.ListChangesOption.CHANGE_ACTIONS,
this.ListChangesOption.CURRENT_ACTIONS,
this.ListChangesOption.DOWNLOAD_COMMANDS,
+ this.ListChangesOption.MESSAGES,
this.ListChangesOption.SUBMITTABLE,
this.ListChangesOption.WEB_LINKS
);