Merge changes Iee55a0f0,I3cf28f16
* changes: Merge branch 'stable-2.15' Update JGit to 4.9.2.201712150930-r.175-gd8a24ac1c
This commit is contained in:
@@ -261,6 +261,33 @@ oldTopic:: Topic name before it was changed.
|
||||
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
||||
created.
|
||||
|
||||
=== Work In Progress State Changed
|
||||
|
||||
Sent when the the link:intro-user.html#wip[WIP] state of the change has changed.
|
||||
|
||||
type:: wip-state-changed
|
||||
|
||||
change:: link:json.html#change[change attribute]
|
||||
|
||||
changer:: link:json.html#account[account attribute]
|
||||
|
||||
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
||||
created.
|
||||
|
||||
=== Private State Changed
|
||||
|
||||
Sent when the the link:intro-user.html#private-changes[private] state of the
|
||||
change has changed.
|
||||
|
||||
type:: private-state-changed
|
||||
|
||||
change:: link:json.html#change[change attribute]
|
||||
|
||||
changer:: link:json.html#account[account attribute]
|
||||
|
||||
eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
|
||||
created.
|
||||
|
||||
=== Vote Deleted
|
||||
|
||||
Sent when a vote was removed from a change.
|
||||
|
@@ -45,6 +45,12 @@ status:: Current state of this change.
|
||||
|
||||
ABANDONED;; Change was abandoned by its owner or administrator.
|
||||
|
||||
private:: Boolean indicating if the change is
|
||||
link:intro-user.html#private-changes[private].
|
||||
|
||||
wip:: Boolean indicating if the change is
|
||||
link:intro-user.html#wip[work in progress].
|
||||
|
||||
comments:: All inline/file comments for this change in <<message,message attributes>>.
|
||||
|
||||
trackingIds:: Issue tracking system links in
|
||||
|
@@ -1386,9 +1386,6 @@ allowed].
|
||||
|`large_change` ||
|
||||
link:config-gerrit.html#change.largeChange[Number of changed lines from
|
||||
which on a change is considered as a large change].
|
||||
|`private_by_default` |not set if `false`|
|
||||
Returns true if changes are by default created as private.
|
||||
See link:config-gerrit.html#change.privateByDefault[privateByDefault]
|
||||
|`reply_label` ||
|
||||
link:config-gerrit.html#change.replyTooltip[Label name for the reply
|
||||
button].
|
||||
|
@@ -1165,12 +1165,14 @@ As result a link:#project-access-info[ProjectAccessInfo] entity is returned.
|
||||
|
||||
{
|
||||
"remove": [
|
||||
"refs/*": {
|
||||
"permissions": {
|
||||
"read": {
|
||||
"rules": {
|
||||
"c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
|
||||
"action": "ALLOW"
|
||||
{
|
||||
"refs/*": {
|
||||
"permissions": {
|
||||
"read": {
|
||||
"rules": {
|
||||
"c2ce4749a32ceb82cd6adcce65b8216e12afb41c": {
|
||||
"action": "ALLOW"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,6 @@ public class ChangeConfigInfo {
|
||||
public Boolean showAssigneeInChangesTable;
|
||||
public Boolean allowDrafts;
|
||||
public int largeChange;
|
||||
public Boolean privateByDefault;
|
||||
public String replyLabel;
|
||||
public String replyTooltip;
|
||||
public int updateDelay;
|
||||
|
@@ -0,0 +1,21 @@
|
||||
// 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.extensions.events;
|
||||
|
||||
public interface PrivateStateChangedListener {
|
||||
interface Event extends ChangeEvent {}
|
||||
|
||||
void onPrivateStateChanged(Event event);
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
// 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.extensions.events;
|
||||
|
||||
public interface WorkInProgressStateChangedListener {
|
||||
interface Event extends ChangeEvent {}
|
||||
|
||||
void onWorkInProgressStateChanged(Event event);
|
||||
}
|
@@ -31,6 +31,7 @@ import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.change.ChangeResource;
|
||||
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||
import com.google.gerrit.server.index.DummyIndexModule;
|
||||
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
|
||||
import com.google.gerrit.server.notedb.rebuild.NoteDbMigrator;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
@@ -145,7 +146,12 @@ public class MigrateToNoteDb extends SiteProgram {
|
||||
// their server is offline.
|
||||
List<String> reindexArgs =
|
||||
ImmutableList.of(
|
||||
"--site-path", getSitePath().toString(), "--threads", Integer.toString(threads));
|
||||
"--site-path",
|
||||
getSitePath().toString(),
|
||||
"--threads",
|
||||
Integer.toString(threads),
|
||||
"--index",
|
||||
ChangeSchemaDefinitions.NAME);
|
||||
System.out.println("Migration complete, reindexing changes with:");
|
||||
System.out.println(" reindex " + reindexArgs.stream().collect(joining(" ")));
|
||||
Reindex reindexPgm = new Reindex();
|
||||
|
@@ -40,17 +40,20 @@ public class DeletePrivate
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final SetPrivateOp.Factory setPrivateOpFactory;
|
||||
|
||||
@Inject
|
||||
DeletePrivate(
|
||||
Provider<ReviewDb> dbProvider,
|
||||
RetryHelper retryHelper,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PermissionBackend permissionBackend) {
|
||||
PermissionBackend permissionBackend,
|
||||
SetPrivateOp.Factory setPrivateOpFactory) {
|
||||
super(retryHelper);
|
||||
this.dbProvider = dbProvider;
|
||||
this.cmUtil = cmUtil;
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.setPrivateOpFactory = setPrivateOpFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,7 +68,7 @@ public class DeletePrivate
|
||||
throw new ResourceConflictException("change is not private");
|
||||
}
|
||||
|
||||
SetPrivateOp op = new SetPrivateOp(cmUtil, false, input);
|
||||
SetPrivateOp op = setPrivateOpFactory.create(cmUtil, false, input);
|
||||
try (BatchUpdate u =
|
||||
updateFactory.create(
|
||||
dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
||||
|
@@ -32,8 +32,9 @@ public class DeletePrivateByPost extends DeletePrivate implements UiAction<Chang
|
||||
Provider<ReviewDb> dbProvider,
|
||||
RetryHelper retryHelper,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PermissionBackend permissionBackend) {
|
||||
super(dbProvider, retryHelper, cmUtil, permissionBackend);
|
||||
PermissionBackend permissionBackend,
|
||||
SetPrivateOp.Factory setPrivateOpFactory) {
|
||||
super(dbProvider, retryHelper, cmUtil, permissionBackend, setPrivateOpFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -177,6 +177,7 @@ public class Module extends RestApiModule {
|
||||
factory(ReviewerResource.Factory.class);
|
||||
factory(SetAssigneeOp.Factory.class);
|
||||
factory(SetHashtagsOp.Factory.class);
|
||||
factory(SetPrivateOp.Factory.class);
|
||||
factory(WorkInProgressOp.Factory.class);
|
||||
}
|
||||
}
|
||||
|
@@ -43,17 +43,20 @@ public class PostPrivate
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final Provider<ReviewDb> dbProvider;
|
||||
private final PermissionBackend permissionBackend;
|
||||
private final SetPrivateOp.Factory setPrivateOpFactory;
|
||||
|
||||
@Inject
|
||||
PostPrivate(
|
||||
Provider<ReviewDb> dbProvider,
|
||||
RetryHelper retryHelper,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
PermissionBackend permissionBackend) {
|
||||
PermissionBackend permissionBackend,
|
||||
SetPrivateOp.Factory setPrivateOpFactory) {
|
||||
super(retryHelper);
|
||||
this.dbProvider = dbProvider;
|
||||
this.cmUtil = cmUtil;
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.setPrivateOpFactory = setPrivateOpFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,7 +71,7 @@ public class PostPrivate
|
||||
return Response.ok("");
|
||||
}
|
||||
|
||||
SetPrivateOp op = new SetPrivateOp(cmUtil, true, input);
|
||||
SetPrivateOp op = setPrivateOpFactory.create(cmUtil, true, input);
|
||||
try (BatchUpdate u =
|
||||
updateFactory.create(
|
||||
dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
||||
|
@@ -19,10 +19,14 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.extensions.events.PrivateStateChanged;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.update.BatchUpdateOp;
|
||||
import com.google.gerrit.server.update.ChangeContext;
|
||||
import com.google.gerrit.server.update.Context;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
public class SetPrivateOp implements BatchUpdateOp {
|
||||
public static class Input {
|
||||
@@ -35,19 +39,32 @@ public class SetPrivateOp implements BatchUpdateOp {
|
||||
}
|
||||
}
|
||||
|
||||
public interface Factory {
|
||||
SetPrivateOp create(ChangeMessagesUtil cmUtil, boolean isPrivate, Input input);
|
||||
}
|
||||
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
private final boolean isPrivate;
|
||||
private final Input input;
|
||||
private final PrivateStateChanged privateStateChanged;
|
||||
|
||||
SetPrivateOp(ChangeMessagesUtil cmUtil, boolean isPrivate, Input input) {
|
||||
private Change change;
|
||||
|
||||
@Inject
|
||||
SetPrivateOp(
|
||||
PrivateStateChanged privateStateChanged,
|
||||
@Assisted ChangeMessagesUtil cmUtil,
|
||||
@Assisted boolean isPrivate,
|
||||
@Assisted Input input) {
|
||||
this.cmUtil = cmUtil;
|
||||
this.isPrivate = isPrivate;
|
||||
this.input = input;
|
||||
this.privateStateChanged = privateStateChanged;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateChange(ChangeContext ctx) throws ResourceConflictException, OrmException {
|
||||
Change change = ctx.getChange();
|
||||
change = ctx.getChange();
|
||||
ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
|
||||
change.setPrivate(isPrivate);
|
||||
change.setLastUpdatedOn(ctx.getWhen());
|
||||
@@ -56,6 +73,11 @@ public class SetPrivateOp implements BatchUpdateOp {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postUpdate(Context ctx) {
|
||||
privateStateChanged.fire(change, ctx.getAccount(), ctx.getWhen());
|
||||
}
|
||||
|
||||
private void addMessage(ChangeContext ctx, ChangeUpdate update) throws OrmException {
|
||||
Change c = ctx.getChange();
|
||||
StringBuilder buf = new StringBuilder(c.isPrivate() ? "Set private" : "Unset private");
|
||||
|
@@ -25,6 +25,7 @@ import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.PatchSetUtil;
|
||||
import com.google.gerrit.server.extensions.events.WorkInProgressStateChanged;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.update.BatchUpdateOp;
|
||||
@@ -58,6 +59,7 @@ public class WorkInProgressOp implements BatchUpdateOp {
|
||||
private final boolean workInProgress;
|
||||
private final Input in;
|
||||
private final NotifyHandling notify;
|
||||
private final WorkInProgressStateChanged stateChanged;
|
||||
|
||||
private Change change;
|
||||
private ChangeNotes notes;
|
||||
@@ -69,11 +71,13 @@ public class WorkInProgressOp implements BatchUpdateOp {
|
||||
ChangeMessagesUtil cmUtil,
|
||||
EmailReviewComments.Factory email,
|
||||
PatchSetUtil psUtil,
|
||||
WorkInProgressStateChanged stateChanged,
|
||||
@Assisted boolean workInProgress,
|
||||
@Assisted Input in) {
|
||||
this.cmUtil = cmUtil;
|
||||
this.email = email;
|
||||
this.psUtil = psUtil;
|
||||
this.stateChanged = stateChanged;
|
||||
this.workInProgress = workInProgress;
|
||||
this.in = in;
|
||||
notify =
|
||||
@@ -121,6 +125,7 @@ public class WorkInProgressOp implements BatchUpdateOp {
|
||||
|
||||
@Override
|
||||
public void postUpdate(Context ctx) {
|
||||
stateChanged.fire(change, ctx.getAccount(), ctx.getWhen());
|
||||
if (workInProgress || notify.ordinal() < NotifyHandling.OWNER_REVIEWERS.ordinal()) {
|
||||
return;
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ import com.google.gerrit.extensions.events.HeadUpdatedListener;
|
||||
import com.google.gerrit.extensions.events.LifecycleListener;
|
||||
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
|
||||
import com.google.gerrit.extensions.events.PluginEventListener;
|
||||
import com.google.gerrit.extensions.events.PrivateStateChangedListener;
|
||||
import com.google.gerrit.extensions.events.ProjectDeletedListener;
|
||||
import com.google.gerrit.extensions.events.ProjectIndexedListener;
|
||||
import com.google.gerrit.extensions.events.ReviewerAddedListener;
|
||||
@@ -54,6 +55,7 @@ import com.google.gerrit.extensions.events.RevisionCreatedListener;
|
||||
import com.google.gerrit.extensions.events.TopicEditedListener;
|
||||
import com.google.gerrit.extensions.events.UsageDataPublishedListener;
|
||||
import com.google.gerrit.extensions.events.VoteDeletedListener;
|
||||
import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
@@ -326,9 +328,11 @@ public class GerritGlobalModule extends FactoryModule {
|
||||
|
||||
DynamicSet.setOf(binder(), ChangeRestoredListener.class);
|
||||
DynamicSet.setOf(binder(), ChangeRevertedListener.class);
|
||||
DynamicSet.setOf(binder(), PrivateStateChangedListener.class);
|
||||
DynamicSet.setOf(binder(), ReviewerAddedListener.class);
|
||||
DynamicSet.setOf(binder(), ReviewerDeletedListener.class);
|
||||
DynamicSet.setOf(binder(), VoteDeletedListener.class);
|
||||
DynamicSet.setOf(binder(), WorkInProgressStateChangedListener.class);
|
||||
DynamicSet.setOf(binder(), RevisionCreatedListener.class);
|
||||
DynamicSet.setOf(binder(), TopicEditedListener.class);
|
||||
DynamicSet.setOf(binder(), AgreementSignupListener.class);
|
||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.server.data;
|
||||
|
||||
import com.google.gerrit.extensions.common.PluginDefinedInfo;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class ChangeAttribute {
|
||||
@@ -35,6 +36,10 @@ public class ChangeAttribute {
|
||||
public Boolean open;
|
||||
public Change.Status status;
|
||||
public List<MessageAttribute> comments;
|
||||
public Boolean wip;
|
||||
|
||||
@SerializedName("private")
|
||||
public Boolean isPrivate;
|
||||
|
||||
public List<TrackingIdAttribute> trackingIds;
|
||||
public PatchSetAttribute currentPatchSet;
|
||||
|
@@ -158,6 +158,8 @@ public class EventFactory {
|
||||
a.assignee = asAccountAttribute(change.getAssignee());
|
||||
a.status = change.getStatus();
|
||||
a.createdOn = change.getCreatedOn().getTime() / 1000L;
|
||||
a.wip = change.isWorkInProgress() ? true : null;
|
||||
a.isPrivate = change.isPrivate() ? true : null;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@ public class EventTypes {
|
||||
register(CommitReceivedEvent.TYPE, CommitReceivedEvent.class);
|
||||
register(HashtagsChangedEvent.TYPE, HashtagsChangedEvent.class);
|
||||
register(PatchSetCreatedEvent.TYPE, PatchSetCreatedEvent.class);
|
||||
register(PrivateStateChangedEvent.TYPE, PrivateStateChangedEvent.class);
|
||||
register(ProjectCreatedEvent.TYPE, ProjectCreatedEvent.class);
|
||||
register(RefReceivedEvent.TYPE, RefReceivedEvent.class);
|
||||
register(RefUpdatedEvent.TYPE, RefUpdatedEvent.class);
|
||||
@@ -37,6 +38,7 @@ public class EventTypes {
|
||||
register(ReviewerDeletedEvent.TYPE, ReviewerDeletedEvent.class);
|
||||
register(TopicChangedEvent.TYPE, TopicChangedEvent.class);
|
||||
register(VoteDeletedEvent.TYPE, VoteDeletedEvent.class);
|
||||
register(WorkInProgressStateChangedEvent.TYPE, WorkInProgressStateChangedEvent.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,28 @@
|
||||
// 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.events;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.data.AccountAttribute;
|
||||
|
||||
public class PrivateStateChangedEvent extends ChangeEvent {
|
||||
static final String TYPE = "private-state-changed";
|
||||
public Supplier<AccountAttribute> changer;
|
||||
|
||||
protected PrivateStateChangedEvent(Change change) {
|
||||
super(TYPE, change);
|
||||
}
|
||||
}
|
@@ -31,11 +31,13 @@ import com.google.gerrit.extensions.events.CommentAddedListener;
|
||||
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
|
||||
import com.google.gerrit.extensions.events.HashtagsEditedListener;
|
||||
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
|
||||
import com.google.gerrit.extensions.events.PrivateStateChangedListener;
|
||||
import com.google.gerrit.extensions.events.ReviewerAddedListener;
|
||||
import com.google.gerrit.extensions.events.ReviewerDeletedListener;
|
||||
import com.google.gerrit.extensions.events.RevisionCreatedListener;
|
||||
import com.google.gerrit.extensions.events.TopicEditedListener;
|
||||
import com.google.gerrit.extensions.events.VoteDeletedListener;
|
||||
import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
@@ -76,6 +78,8 @@ public class StreamEventsApiListener
|
||||
ChangeAbandonedListener,
|
||||
ChangeMergedListener,
|
||||
ChangeRestoredListener,
|
||||
WorkInProgressStateChangedListener,
|
||||
PrivateStateChangedListener,
|
||||
CommentAddedListener,
|
||||
GitReferenceUpdatedListener,
|
||||
HashtagsEditedListener,
|
||||
@@ -99,11 +103,15 @@ public class StreamEventsApiListener
|
||||
.to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), HashtagsEditedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), NewProjectCreatedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), PrivateStateChangedListener.class)
|
||||
.to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), ReviewerAddedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), ReviewerDeletedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), RevisionCreatedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), TopicEditedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), VoteDeletedListener.class).to(StreamEventsApiListener.class);
|
||||
DynamicSet.bind(binder(), WorkInProgressStateChangedListener.class)
|
||||
.to(StreamEventsApiListener.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +469,36 @@ public class StreamEventsApiListener
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWorkInProgressStateChanged(WorkInProgressStateChangedListener.Event ev) {
|
||||
try {
|
||||
Change change = getChange(ev.getChange());
|
||||
WorkInProgressStateChangedEvent event = new WorkInProgressStateChangedEvent(change);
|
||||
|
||||
event.change = changeAttributeSupplier(change);
|
||||
event.changer = accountAttributeSupplier(ev.getWho());
|
||||
|
||||
dispatcher.get().postEvent(change, event);
|
||||
} catch (OrmException | PermissionBackendException e) {
|
||||
log.error("Failed to dispatch event", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrivateStateChanged(PrivateStateChangedListener.Event ev) {
|
||||
try {
|
||||
Change change = getChange(ev.getChange());
|
||||
PrivateStateChangedEvent event = new PrivateStateChangedEvent(change);
|
||||
|
||||
event.change = changeAttributeSupplier(change);
|
||||
event.changer = accountAttributeSupplier(ev.getWho());
|
||||
|
||||
dispatcher.get().postEvent(change, event);
|
||||
} catch (OrmException | PermissionBackendException e) {
|
||||
log.error("Failed to dispatch event", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVoteDeleted(VoteDeletedListener.Event ev) {
|
||||
try {
|
||||
|
@@ -0,0 +1,28 @@
|
||||
// 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.events;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.data.AccountAttribute;
|
||||
|
||||
public class WorkInProgressStateChangedEvent extends ChangeEvent {
|
||||
static final String TYPE = "wip-state-changed";
|
||||
public Supplier<AccountAttribute> changer;
|
||||
|
||||
protected WorkInProgressStateChangedEvent(Change change) {
|
||||
super(TYPE, change);
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
// 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.extensions.events;
|
||||
|
||||
import com.google.gerrit.extensions.api.changes.NotifyHandling;
|
||||
import com.google.gerrit.extensions.common.AccountInfo;
|
||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||
import com.google.gerrit.extensions.events.PrivateStateChangedListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PrivateStateChanged {
|
||||
private static final Logger log = LoggerFactory.getLogger(PrivateStateChanged.class);
|
||||
|
||||
private final DynamicSet<PrivateStateChangedListener> listeners;
|
||||
private final EventUtil util;
|
||||
|
||||
@Inject
|
||||
PrivateStateChanged(DynamicSet<PrivateStateChangedListener> listeners, EventUtil util) {
|
||||
this.listeners = listeners;
|
||||
this.util = util;
|
||||
}
|
||||
|
||||
public void fire(Change change, Account account, Timestamp when) {
|
||||
|
||||
if (!listeners.iterator().hasNext()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Event event = new Event(util.changeInfo(change), util.accountInfo(account), when);
|
||||
for (PrivateStateChangedListener l : listeners) {
|
||||
try {
|
||||
l.onPrivateStateChanged(event);
|
||||
} catch (Exception e) {
|
||||
util.logEventListenerError(event, l, e);
|
||||
}
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
log.error("Couldn't fire event", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Event extends AbstractChangeEvent
|
||||
implements PrivateStateChangedListener.Event {
|
||||
|
||||
protected Event(ChangeInfo change, AccountInfo who, Timestamp when) {
|
||||
super(change, who, when, NotifyHandling.ALL);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
// 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.extensions.events;
|
||||
|
||||
import com.google.gerrit.extensions.api.changes.NotifyHandling;
|
||||
import com.google.gerrit.extensions.common.AccountInfo;
|
||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||
import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import java.sql.Timestamp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class WorkInProgressStateChanged {
|
||||
private static final Logger log = LoggerFactory.getLogger(WorkInProgressStateChanged.class);
|
||||
|
||||
private final DynamicSet<WorkInProgressStateChangedListener> listeners;
|
||||
private final EventUtil util;
|
||||
|
||||
@Inject
|
||||
WorkInProgressStateChanged(
|
||||
DynamicSet<WorkInProgressStateChangedListener> listeners, EventUtil util) {
|
||||
this.listeners = listeners;
|
||||
this.util = util;
|
||||
}
|
||||
|
||||
public void fire(Change change, Account account, Timestamp when) {
|
||||
|
||||
if (!listeners.iterator().hasNext()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Event event = new Event(util.changeInfo(change), util.accountInfo(account), when);
|
||||
for (WorkInProgressStateChangedListener l : listeners) {
|
||||
try {
|
||||
l.onWorkInProgressStateChanged(event);
|
||||
} catch (Exception e) {
|
||||
util.logEventListenerError(event, l, e);
|
||||
}
|
||||
}
|
||||
} catch (OrmException e) {
|
||||
log.error("Couldn't fire event", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Event extends AbstractChangeEvent
|
||||
implements WorkInProgressStateChangedListener.Event {
|
||||
|
||||
protected Event(ChangeInfo change, AccountInfo who, Timestamp when) {
|
||||
super(change, who, when, NotifyHandling.ALL);
|
||||
}
|
||||
}
|
||||
}
|
@@ -147,7 +147,10 @@ public abstract class AbstractChangeNotes<T> {
|
||||
throw new OrmException("NoteDb is required to read change " + changeId);
|
||||
}
|
||||
boolean readOrWrite = read || args.migration.rawWriteChangesSetting();
|
||||
if (!readOrWrite && !autoRebuild) {
|
||||
if (!readOrWrite) {
|
||||
// Don't even open the repo if we neither write to nor read from NoteDb. It's possible that
|
||||
// there is some garbage in the noteDbState field and/or the repo, but at this point NoteDb is
|
||||
// completely off so it's none of our business.
|
||||
loadDefaults();
|
||||
return self();
|
||||
}
|
||||
|
@@ -737,6 +737,9 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||
if (state == null) {
|
||||
return super.openHandle(repo, id);
|
||||
} else if (shouldExist) {
|
||||
// TODO(dborowitz): This means we have a state recorded in noteDbState but the ref doesn't
|
||||
// exist for whatever reason. Doesn't this mean we should trigger an auto-rebuild, rather
|
||||
// than throwing?
|
||||
throw new NoSuchChangeException(getChangeId());
|
||||
}
|
||||
}
|
||||
|
@@ -265,7 +265,7 @@ public class PrimaryStorageMigrator {
|
||||
// the primary storage to NoteDb.
|
||||
|
||||
setPrimaryStorageNoteDb(id, rebuiltState);
|
||||
log.info("Migrated change {} to NoteDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
|
||||
log.debug("Migrated change {} to NoteDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
|
||||
}
|
||||
|
||||
private Change setReadOnlyInReviewDb(Change.Id id) throws OrmException {
|
||||
@@ -399,7 +399,7 @@ public class PrimaryStorageMigrator {
|
||||
rebuilder.rebuildReviewDb(db(), project, id);
|
||||
setPrimaryStorageReviewDb(id, newMetaId);
|
||||
releaseReadOnlyLeaseInNoteDb(project, id);
|
||||
log.info("Migrated change {} to ReviewDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
|
||||
log.debug("Migrated change {} to ReviewDb primary in {}ms", id, sw.elapsed(MILLISECONDS));
|
||||
}
|
||||
|
||||
private ObjectId setReadOnlyInNoteDb(Project.NameKey project, Change.Id id)
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package com.google.gerrit.server.notedb.rebuild;
|
||||
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
|
||||
import static com.google.gerrit.server.notedb.ChangeNoteUtil.FOOTER_HASHTAGS;
|
||||
@@ -228,9 +229,16 @@ public class ChangeRebuilderImpl extends ChangeRebuilder {
|
||||
throw new NoSuchChangeException(changeId);
|
||||
}
|
||||
|
||||
final String oldNoteDbState = change.getNoteDbState();
|
||||
String oldNoteDbStateStr = change.getNoteDbState();
|
||||
Result r = manager.stageAndApplyDelta(change);
|
||||
final String newNoteDbState = change.getNoteDbState();
|
||||
String newNoteDbStateStr = change.getNoteDbState();
|
||||
if (newNoteDbStateStr == null) {
|
||||
throw new OrmException(
|
||||
"Rebuilding change %s produced no writes to NoteDb: "
|
||||
+ bundleReader.fromReviewDb(db, changeId));
|
||||
}
|
||||
NoteDbChangeState newNoteDbState =
|
||||
checkNotNull(NoteDbChangeState.parse(changeId, newNoteDbStateStr));
|
||||
try {
|
||||
db.changes()
|
||||
.atomicUpdate(
|
||||
@@ -241,15 +249,15 @@ public class ChangeRebuilderImpl extends ChangeRebuilder {
|
||||
if (checkReadOnly) {
|
||||
NoteDbChangeState.checkNotReadOnly(change, skewMs);
|
||||
}
|
||||
String currNoteDbState = change.getNoteDbState();
|
||||
if (Objects.equals(currNoteDbState, newNoteDbState)) {
|
||||
String currNoteDbStateStr = change.getNoteDbState();
|
||||
if (Objects.equals(currNoteDbStateStr, newNoteDbStateStr)) {
|
||||
// Another thread completed the same rebuild we were about to.
|
||||
throw new AbortUpdateException();
|
||||
} else if (!Objects.equals(oldNoteDbState, currNoteDbState)) {
|
||||
} else if (!Objects.equals(oldNoteDbStateStr, currNoteDbStateStr)) {
|
||||
// Another thread updated the state to something else.
|
||||
throw new ConflictingUpdateRuntimeException(change, oldNoteDbState);
|
||||
throw new ConflictingUpdateRuntimeException(change, oldNoteDbStateStr);
|
||||
}
|
||||
change.setNoteDbState(newNoteDbState);
|
||||
change.setNoteDbState(newNoteDbStateStr);
|
||||
return change;
|
||||
}
|
||||
});
|
||||
@@ -259,10 +267,9 @@ public class ChangeRebuilderImpl extends ChangeRebuilder {
|
||||
// rebuild had executed before the other thread.
|
||||
throw new ConflictingUpdateException(e);
|
||||
} catch (AbortUpdateException e) {
|
||||
if (NoteDbChangeState.parse(changeId, newNoteDbState)
|
||||
.isUpToDate(
|
||||
manager.getChangeRepo().cmds.getRepoRefCache(),
|
||||
manager.getAllUsersRepo().cmds.getRepoRefCache())) {
|
||||
if (newNoteDbState.isUpToDate(
|
||||
manager.getChangeRepo().cmds.getRepoRefCache(),
|
||||
manager.getAllUsersRepo().cmds.getRepoRefCache())) {
|
||||
// If the state in ReviewDb matches NoteDb at this point, it means another thread
|
||||
// successfully completed this rebuild. It's ok to not execute the update in this case,
|
||||
// since the object referenced in the Result was flushed to the repo by whatever thread won
|
||||
|
@@ -91,6 +91,7 @@ import java.util.function.Predicate;
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.internal.storage.file.FileRepository;
|
||||
import org.eclipse.jgit.internal.storage.file.PackInserter;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.ObjectInserter;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
@@ -748,9 +749,12 @@ public class NoteDbMigrator implements AutoCloseable {
|
||||
}
|
||||
|
||||
private static ObjectInserter newPackInserter(Repository repo) {
|
||||
return repo instanceof FileRepository
|
||||
? ((FileRepository) repo).getObjectDatabase().newPackInserter()
|
||||
: repo.newObjectInserter();
|
||||
if (!(repo instanceof FileRepository)) {
|
||||
return repo.newObjectInserter();
|
||||
}
|
||||
PackInserter ins = ((FileRepository) repo).getObjectDatabase().newPackInserter();
|
||||
ins.checkExisting(false);
|
||||
return ins;
|
||||
}
|
||||
|
||||
private boolean rebuildProject(
|
||||
|
@@ -239,7 +239,6 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
||||
toBoolean(
|
||||
cfg.getBoolean("change", "showAssigneeInChangesTable", false) && hasAssigneeInIndex);
|
||||
info.largeChange = cfg.getInt("change", "largeChange", 500);
|
||||
info.privateByDefault = toBoolean(cfg.getBoolean("change", "privateByDefault", false));
|
||||
info.replyTooltip =
|
||||
Optional.ofNullable(cfg.getString("change", null, "replyTooltip")).orElse("Reply and score")
|
||||
+ " (Shortcut: a)";
|
||||
|
@@ -14,6 +14,9 @@
|
||||
|
||||
package com.google.gerrit.server.schema;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.GerritPersonIdent;
|
||||
@@ -22,23 +25,40 @@ import com.google.gerrit.server.config.AllUsersName;
|
||||
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.gwtorm.jdbc.JdbcSchema;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.TextProgressMonitor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** Migrate accounts to NoteDb. */
|
||||
public class Schema_154 extends SchemaVersion {
|
||||
private static final Logger log = LoggerFactory.getLogger(Schema_154.class);
|
||||
private static final String TABLE = "accounts";
|
||||
private static final Map<String, AccountSetter> ACCOUNT_FIELDS_MAP =
|
||||
ImmutableMap.<String, AccountSetter>builder()
|
||||
.put("full_name", (a, rs, field) -> a.setFullName(rs.getString(field)))
|
||||
.put("preferred_email", (a, rs, field) -> a.setPreferredEmail(rs.getString(field)))
|
||||
.put("status", (a, rs, field) -> a.setStatus(rs.getString(field)))
|
||||
.put("inactive", (a, rs, field) -> a.setActive(rs.getString(field).equals("N")))
|
||||
.build();
|
||||
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final AllUsersName allUsersName;
|
||||
private final Provider<PersonIdent> serverIdent;
|
||||
@@ -76,23 +96,24 @@ public class Schema_154 extends SchemaVersion {
|
||||
}
|
||||
|
||||
private Set<Account> scanAccounts(ReviewDb db, ProgressMonitor pm) throws SQLException {
|
||||
Map<String, AccountSetter> fields = getFields(db);
|
||||
if (fields.isEmpty()) {
|
||||
log.warn("Only account_id and registered_on fields are migrated for accounts");
|
||||
}
|
||||
|
||||
List<String> queryFields = new ArrayList<>();
|
||||
queryFields.add("account_id");
|
||||
queryFields.add("registered_on");
|
||||
queryFields.addAll(fields.keySet());
|
||||
String query = "SELECT " + String.join(", ", queryFields) + String.format(" FROM %s", TABLE);
|
||||
try (Statement stmt = newStatement(db);
|
||||
ResultSet rs =
|
||||
stmt.executeQuery(
|
||||
"SELECT account_id,"
|
||||
+ " registered_on,"
|
||||
+ " full_name, "
|
||||
+ " preferred_email,"
|
||||
+ " status,"
|
||||
+ " inactive"
|
||||
+ " FROM accounts")) {
|
||||
ResultSet rs = stmt.executeQuery(query)) {
|
||||
Set<Account> s = new HashSet<>();
|
||||
while (rs.next()) {
|
||||
Account a = new Account(new Account.Id(rs.getInt(1)), rs.getTimestamp(2));
|
||||
a.setFullName(rs.getString(3));
|
||||
a.setPreferredEmail(rs.getString(4));
|
||||
a.setStatus(rs.getString(5));
|
||||
a.setActive(rs.getString(6).equals("N"));
|
||||
for (Map.Entry<String, AccountSetter> field : fields.entrySet()) {
|
||||
field.getValue().set(a, rs, field.getKey());
|
||||
}
|
||||
s.add(a);
|
||||
pm.update(1);
|
||||
}
|
||||
@@ -100,6 +121,17 @@ public class Schema_154 extends SchemaVersion {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, AccountSetter> getFields(ReviewDb db) throws SQLException {
|
||||
JdbcSchema schema = (JdbcSchema) db;
|
||||
Connection connection = schema.getConnection();
|
||||
Set<String> columns = schema.getDialect().listColumns(connection, TABLE);
|
||||
return ACCOUNT_FIELDS_MAP
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> columns.contains(e.getKey()))
|
||||
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
private void updateAccountInNoteDb(Repository allUsersRepo, Account account)
|
||||
throws IOException, ConfigInvalidException {
|
||||
MetaDataUpdate md =
|
||||
@@ -112,4 +144,9 @@ public class Schema_154 extends SchemaVersion {
|
||||
accountConfig.setAccount(account);
|
||||
accountConfig.commit(md);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface AccountSetter {
|
||||
void set(Account a, ResultSet rs, String field) throws SQLException;
|
||||
}
|
||||
}
|
||||
|
@@ -56,7 +56,6 @@ public class ServerInfoIT extends AbstractDaemonTest {
|
||||
// change
|
||||
@GerritConfig(name = "change.allowDrafts", value = "false")
|
||||
@GerritConfig(name = "change.largeChange", value = "300")
|
||||
@GerritConfig(name = "change.privateByDefault", value = "true")
|
||||
@GerritConfig(name = "change.replyTooltip", value = "Publish votes and draft comments")
|
||||
@GerritConfig(name = "change.replyLabel", value = "Vote")
|
||||
@GerritConfig(name = "change.updateDelay", value = "50s")
|
||||
@@ -101,7 +100,6 @@ public class ServerInfoIT extends AbstractDaemonTest {
|
||||
// change
|
||||
assertThat(i.change.allowDrafts).isNull();
|
||||
assertThat(i.change.largeChange).isEqualTo(300);
|
||||
assertThat(i.change.privateByDefault).isTrue();
|
||||
assertThat(i.change.replyTooltip).startsWith("Publish votes and draft comments");
|
||||
assertThat(i.change.replyLabel).isEqualTo("Vote\u2026");
|
||||
assertThat(i.change.updateDelay).isEqualTo(50);
|
||||
|
@@ -1287,6 +1287,28 @@ public class ChangeRebuilderIT extends AbstractDaemonTest {
|
||||
assertThat(newPs3.getCreatedOn()).isGreaterThan(ps1.getCreatedOn());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreNoteDbStateWithNoCorrespondingRefWhenWritesAndReadsDisabled() throws Exception {
|
||||
PushOneCommit.Result r = createChange();
|
||||
Change.Id id = r.getChange().getId();
|
||||
ReviewDb db = getUnwrappedDb();
|
||||
Change c = db.changes().get(id);
|
||||
c.setNoteDbState("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
|
||||
db.changes().update(Collections.singleton(c));
|
||||
c = db.changes().get(id);
|
||||
|
||||
String refName = RefNames.changeMetaRef(id);
|
||||
assertThat(getMetaRef(project, refName)).isNull();
|
||||
|
||||
ChangeNotes notes = notesFactory.create(dbProvider.get(), project, id);
|
||||
assertThat(notes.getChange().getRowVersion()).isEqualTo(c.getRowVersion());
|
||||
|
||||
notes = notesFactory.createChecked(dbProvider.get(), project, id);
|
||||
assertThat(notes.getChange().getRowVersion()).isEqualTo(c.getRowVersion());
|
||||
|
||||
assertThat(getMetaRef(project, refName)).isNull();
|
||||
}
|
||||
|
||||
private void assertChangesReadOnly(RestApiException e) throws Exception {
|
||||
Throwable cause = e.getCause();
|
||||
assertThat(cause).isInstanceOf(UpdateException.class);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
load("//tools/bzl:maven_jar.bzl", "GERRIT", "MAVEN_LOCAL", "MAVEN_CENTRAL", "maven_jar")
|
||||
|
||||
_JGIT_VERS = "4.9.2.201712150930-r.171-gfdbaa25db"
|
||||
_JGIT_VERS = "4.9.2.201712150930-r.175-gd8a24ac1c"
|
||||
|
||||
_DOC_VERS = "4.9.2.201712150930-r" # Set to _JGIT_VERS unless using a snapshot
|
||||
|
||||
@@ -26,28 +26,28 @@ def jgit_maven_repos():
|
||||
name = "jgit_lib",
|
||||
artifact = "org.eclipse.jgit:org.eclipse.jgit:" + _JGIT_VERS,
|
||||
repository = _JGIT_REPO,
|
||||
sha1 = "29b822410b29286a09df728f8379e5cb8b1a486e",
|
||||
src_sha1 = "5106b81910a057470cfd2584d9cb3502bcbebbc2",
|
||||
sha1 = "4286555f5851fbfcf0ff89ec884f7f806b0c7e37",
|
||||
src_sha1 = "5e38b7e7936ebbd778914dc4f9d76d245a5a4518",
|
||||
unsign = True,
|
||||
)
|
||||
maven_jar(
|
||||
name = "jgit_servlet",
|
||||
artifact = "org.eclipse.jgit:org.eclipse.jgit.http.server:" + _JGIT_VERS,
|
||||
repository = _JGIT_REPO,
|
||||
sha1 = "01f6718f6b629e28caad38e00190811b38574e74",
|
||||
sha1 = "da0d2c7a048cc213274cd06a5baf277c85ea152e",
|
||||
unsign = True,
|
||||
)
|
||||
maven_jar(
|
||||
name = "jgit_archive",
|
||||
artifact = "org.eclipse.jgit:org.eclipse.jgit.archive:" + _JGIT_VERS,
|
||||
repository = _JGIT_REPO,
|
||||
sha1 = "9c9e9332e7dc724dbe1837e21feccd98bc25e6b4",
|
||||
sha1 = "1cd91bedf8b591626d341c2d896181ddba5f9aa9",
|
||||
)
|
||||
maven_jar(
|
||||
name = "jgit_junit",
|
||||
artifact = "org.eclipse.jgit:org.eclipse.jgit.junit:" + _JGIT_VERS,
|
||||
repository = _JGIT_REPO,
|
||||
sha1 = "4154c70b78b62035dad446332b24f7816b7a2a1b",
|
||||
sha1 = "5b7cc1aa0ba062ad587b6daa64743b704b997f74",
|
||||
unsign = True,
|
||||
)
|
||||
|
||||
|
@@ -45,10 +45,7 @@ def gerrit_plugin(
|
||||
|
||||
native.java_binary(
|
||||
name = '%s__non_stamped' % name,
|
||||
deploy_manifest_lines = manifest_entries + [
|
||||
"Gerrit-ApiType: plugin",
|
||||
"Implementation-Vendor: Gerrit Code Review",
|
||||
],
|
||||
deploy_manifest_lines = manifest_entries + ["Gerrit-ApiType: plugin"],
|
||||
main_class = 'Dummy',
|
||||
runtime_deps = [
|
||||
':%s__plugin' % name,
|
||||
|
Reference in New Issue
Block a user