Notify users mentioned in commit footer on draft publish
If a user is mentioned in a footer of a commit message (e.g. by a 'Signed-off-by') then this user is notified about this change/patchset. This is important because the mentioned user may want to check that he is correctly referenced. If a draft change/patchset is uploaded the users mentioned in the footers cannot be notified because the draft is not visible to them. But they should be notified when the draft is published since the change/patchset is now visible to them. Change-Id: Id28a7b0aa47d2de9dc97f2f3a743300ff7f4c559 Signed-off-by: Edwin Kempin <edwin.kempin@sap.com>
This commit is contained in:
committed by
Gerrit Code Review
parent
013229c9a4
commit
be46e51a20
@@ -15,15 +15,24 @@
|
||||
|
||||
package com.google.gerrit.server.changedetail;
|
||||
|
||||
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
|
||||
|
||||
import com.google.gerrit.common.ChangeHooks;
|
||||
import com.google.gerrit.common.data.ReviewResult;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ApprovalsUtil;
|
||||
import com.google.gerrit.server.ChangeUtil;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||
import com.google.gerrit.server.mail.MailUtil.MailRecipients;
|
||||
import com.google.gerrit.server.mail.ReplacePatchSetSender;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
@@ -33,9 +42,16 @@ import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.FooterLine;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class PublishDraft implements Callable<ReviewResult> {
|
||||
@@ -49,29 +65,39 @@ public class PublishDraft implements Callable<ReviewResult> {
|
||||
private final ChangeControl.Factory changeControlFactory;
|
||||
private final ReviewDb db;
|
||||
private final ChangeHooks hooks;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final PatchSetInfoFactory patchSetInfoFactory;
|
||||
private final AccountResolver accountResolver;
|
||||
private final CreateChangeSender.Factory createChangeSenderFactory;
|
||||
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
|
||||
|
||||
private final PatchSet.Id patchSetId;
|
||||
|
||||
@Inject
|
||||
PublishDraft(final ChangeControl.Factory changeControlFactory,
|
||||
final ReviewDb db, final ChangeHooks hooks,
|
||||
final GitRepositoryManager repoManager,
|
||||
final PatchSetInfoFactory patchSetInfoFactory,
|
||||
final ApprovalsUtil approvalsUtil,
|
||||
final AccountResolver accountResolver,
|
||||
final CreateChangeSender.Factory createChangeSenderFactory,
|
||||
final ReplacePatchSetSender.Factory replacePatchSetFactory,
|
||||
@Assisted final PatchSet.Id patchSetId) {
|
||||
this.changeControlFactory = changeControlFactory;
|
||||
this.db = db;
|
||||
this.hooks = hooks;
|
||||
this.repoManager = repoManager;
|
||||
this.patchSetInfoFactory = patchSetInfoFactory;
|
||||
this.accountResolver = accountResolver;
|
||||
this.createChangeSenderFactory = createChangeSenderFactory;
|
||||
this.replacePatchSetFactory = replacePatchSetFactory;
|
||||
|
||||
this.patchSetId = patchSetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewResult call() throws NoSuchChangeException, OrmException,
|
||||
PatchSetInfoNotAvailableException {
|
||||
IOException, PatchSetInfoNotAvailableException {
|
||||
final ReviewResult result = new ReviewResult();
|
||||
|
||||
final Change.Id changeId = patchSetId.getParentKey();
|
||||
@@ -115,27 +141,65 @@ public class PublishDraft implements Callable<ReviewResult> {
|
||||
if (!updatedPatchSet.isDraft() || updatedChange.getStatus() == Change.Status.NEW) {
|
||||
hooks.doDraftPublishedHook(updatedChange, updatedPatchSet, db);
|
||||
|
||||
if (control.getChange().getStatus() == Change.Status.DRAFT) {
|
||||
notifyWatchers((IdentifiedUser) control.getCurrentUser(),
|
||||
updatedChange, updatedPatchSet);
|
||||
}
|
||||
sendNotifications(control.getChange().getStatus() == Change.Status.DRAFT,
|
||||
(IdentifiedUser) control.getCurrentUser(), updatedChange, updatedPatchSet);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void notifyWatchers(final IdentifiedUser currentUser,
|
||||
final Change updatedChange, final PatchSet updatedPatchSet)
|
||||
throws PatchSetInfoNotAvailableException {
|
||||
final PatchSetInfo info = patchSetInfoFactory.get(updatedChange, updatedPatchSet);
|
||||
private void sendNotifications(final boolean newChange,
|
||||
final IdentifiedUser currentUser, final Change updatedChange,
|
||||
final PatchSet updatedPatchSet) throws OrmException, IOException,
|
||||
PatchSetInfoNotAvailableException {
|
||||
final Repository git = repoManager.openRepository(updatedChange.getProject());
|
||||
try {
|
||||
CreateChangeSender cm = createChangeSenderFactory.create(updatedChange);
|
||||
cm.setFrom(currentUser.getAccountId());
|
||||
cm.setPatchSet(updatedPatchSet, info);
|
||||
cm.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot send email for new change " + updatedChange.getId(), e);
|
||||
final RevWalk revWalk = new RevWalk(git);
|
||||
final RevCommit commit;
|
||||
try {
|
||||
commit = revWalk.parseCommit(ObjectId.fromString(updatedPatchSet.getRevision().get()));
|
||||
} finally {
|
||||
revWalk.release();
|
||||
}
|
||||
final PatchSetInfo info = patchSetInfoFactory.get(commit, updatedPatchSet.getId());
|
||||
final List<FooterLine> footerLines = commit.getFooterLines();
|
||||
final Account.Id me = currentUser.getAccountId();
|
||||
final MailRecipients recipients =
|
||||
getRecipientsFromFooters(accountResolver, updatedPatchSet, footerLines);
|
||||
recipients.remove(me);
|
||||
|
||||
if (newChange) {
|
||||
try {
|
||||
CreateChangeSender cm = createChangeSenderFactory.create(updatedChange);
|
||||
cm.setFrom(me);
|
||||
cm.setPatchSet(updatedPatchSet, info);
|
||||
cm.addReviewers(recipients.getReviewers());
|
||||
cm.addExtraCC(recipients.getCcOnly());
|
||||
cm.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot send email for new change " + updatedChange.getId(), e);
|
||||
}
|
||||
} else {
|
||||
final ChangeMessage msg =
|
||||
new ChangeMessage(new ChangeMessage.Key(updatedChange.getId(),
|
||||
ChangeUtil.messageUUID(db)), me,
|
||||
updatedPatchSet.getCreatedOn(), updatedPatchSet.getId());
|
||||
msg.setMessage("Uploaded patch set " + updatedPatchSet.getPatchSetId() + ".");
|
||||
try {
|
||||
ReplacePatchSetSender cm = replacePatchSetFactory.create(updatedChange);
|
||||
cm.setFrom(me);
|
||||
cm.setPatchSet(updatedPatchSet, info);
|
||||
cm.setChangeMessage(msg);
|
||||
cm.addReviewers(recipients.getReviewers());
|
||||
cm.addExtraCC(recipients.getCcOnly());
|
||||
cm.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot send email for new patch set " + updatedPatchSet.getId(), e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
git.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user