Allow ITS comments for a change's patch sets that first associate an issue When setting commentOnFirstLinkedPatchSetCreated to true (and not taking other commenting options into account), adding * patch set 1 that associates issue 101, and issue 103, and * patch set 2 that associates issue 102, and issue 103, * patch set 3 that associates issue 101, and issue 102, to some change amounts for * issue 101 getting a single ITS comment for patch set 1, * issue 102 getting a single ITS comment for patch set 2, and * issue 103 getting a single ITS comment for patch set 1. Change-Id: Ie882107f4b4bb58dee5fb67899bbe8816364f8eb
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java index f5611fa..4d2ed8d 100644 --- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java +++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
@@ -33,6 +33,7 @@ import com.google.gerrit.server.events.PatchSetCreatedEvent; import com.google.gerrit.server.events.RefUpdatedEvent; import com.google.gerrit.server.git.GitRepositoryManager; +import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; public class GerritHookFilter implements ChangeListener { @@ -56,7 +57,8 @@ } } - public void doFilter(PatchSetCreatedEvent hook) throws IOException { + public void doFilter(PatchSetCreatedEvent hook) throws IOException, + OrmException { } public void doFilter(CommentAddedEvent hook) throws IOException {
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java index c3ad727..3a8314b 100644 --- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java +++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilterAddRelatedLinkToChangeId.java
@@ -16,13 +16,21 @@ import java.io.IOException; import java.net.URL; +import java.util.Iterator; +import java.util.List; import org.eclipse.jgit.lib.Config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; +import com.google.gerrit.reviewdb.client.Change; +import com.google.gerrit.reviewdb.client.PatchSet; +import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.events.PatchSetCreatedEvent; +import com.google.gwtorm.server.OrmException; +import com.google.gwtorm.server.ResultSet; import com.google.inject.Inject; import com.googlesource.gerrit.plugins.hooks.its.ItsFacade; import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor; @@ -43,8 +51,52 @@ @Inject private IssueExtractor issueExtractor; + @Inject + private ReviewDb db; + + /** + * Filter issues to those that occur for the first time in a change + * + * @param issues The issues to filter. + * @param patchSet Filter for this patch set. + * @return the issues that occur for the first time. + * @throws IOException + * @throws OrmException + */ + private List<String> filterForFirstLinkedIssues(String[] issues, + PatchSetCreatedEvent patchSet) throws IOException, OrmException { + List<String> ret = Lists.newArrayList(issues); + int patchSetNumberCurrent = Integer.parseInt(patchSet.patchSet.number); + + if (patchSetNumberCurrent > 1) { + String project = patchSet.change.project; + int changeNumber = Integer.parseInt(patchSet.change.number); + Change.Id changeId = new Change.Id(changeNumber); + + // It would be nice to get patch sets directly via + // patchSetCreated.change.patchSets + // but it turns out that it's null for our events. So we fetch the patch + // sets from the db instead. + ResultSet<PatchSet> patchSets = db.patchSets().byChange(changeId); + Iterator<PatchSet> patchSetIter = patchSets.iterator(); + + while (!ret.isEmpty() && patchSetIter.hasNext()) { + PatchSet previousPatchSet = patchSetIter.next(); + if (previousPatchSet.getPatchSetId() < patchSetNumberCurrent) { + String commitMessage = getComment(project, + previousPatchSet.getRevision().get()); + for (String issue : issueExtractor.getIssueIds(commitMessage)) { + ret.remove(issue); + } + } + } + } + return ret; + } + @Override - public void doFilter(PatchSetCreatedEvent patchsetCreated) throws IOException { + public void doFilter(PatchSetCreatedEvent patchsetCreated) + throws IOException, OrmException { boolean addPatchSetComment = gerritConfig.getBoolean(its.name(), null, "commentOnPatchSetCreated", true); @@ -52,13 +104,21 @@ gerritConfig.getBoolean(its.name(), null, "commentOnChangeCreated", false); - if (addPatchSetComment || addChangeComment) { + boolean addFirstLinkedPatchSetComment = gerritConfig.getBoolean(its.name(), + null, "commentOnFirstLinkedPatchSetCreated", false); + + if (addPatchSetComment || addFirstLinkedPatchSetComment || addChangeComment) { String gitComment = getComment(patchsetCreated.change.project, patchsetCreated.patchSet.revision); String[] issues = issueExtractor.getIssueIds(gitComment); + List<String> firstLinkedIssues = null; + if (addFirstLinkedPatchSetComment) { + firstLinkedIssues = filterForFirstLinkedIssues(issues, patchsetCreated); + } + for (String issue : issues) { if (addChangeComment) { its.addRelatedLink(issue, new URL(patchsetCreated.change.url), @@ -70,6 +130,12 @@ "Gerrit Patch-Set " + patchsetCreated.change.id + "/" + patchsetCreated.patchSet.number); } + + if (addFirstLinkedPatchSetComment && firstLinkedIssues.contains(issue)) { + its.addRelatedLink(issue, new URL(patchsetCreated.change.url), + "Gerrit Patch-Set " + patchsetCreated.change.id + "/" + + patchsetCreated.patchSet.number); + } } } }
diff --git a/hooks-its/src/main/resources/Documentation/config.md b/hooks-its/src/main/resources/Documentation/config.md index adaaf47..f817ccd 100644 --- a/hooks-its/src/main/resources/Documentation/config.md +++ b/hooks-its/src/main/resources/Documentation/config.md
@@ -54,6 +54,14 @@ + Default is `true`. +[[itsName.commentOnFirstLinkedPatchSetCreated]]itsName.commentOnFirstLinkedPatchSetCreated:: ++ +If true, creating a patch set for a change adds an ITS comment to the change's +associated issue, if the issue has not been mentioned in previous patch sets of +the same change. ++ +Default is `false`. + [[itsName.commentOnPatchSetCreated]]itsName.commentOnPatchSetCreated:: + If true, creating a patch set for a change adds an ITS comment to the change's