Introduce '/review_last' command support
Implemented support for the '/review_last' command within comments. If a
comment within a Change targets ChatGPT and contains this command, it
initiates a review of the Change's most recent PatchSet.
Jira-Id: IT-103
Change-Id: I3d03c75bf1ae3b8158323bb392593ccf6b23ed91
Signed-off-by: Patrizio <patrizio.gelosi@amarulasolutions.com>
diff --git a/README.md b/README.md
index e2ed963..8f94326 100644
--- a/README.md
+++ b/README.md
@@ -161,6 +161,11 @@
- `isEnabled`: The default is false. If set to true, the plugin will review the Patch Set of this project.
+## Commands
+
+The `/review_last` command, when used in a comment directed at ChatGPT on any Change, triggers a review of the last
+Patch Set of the Change.
+
## Testing
- You can run the unit tests in the project to familiarize yourself with the plugin's source code.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClient.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClient.java
index b710afc..6317e79 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClient.java
@@ -54,6 +54,11 @@
return gerritClientPatchSet.getPatchSet(fullChangeId, isCommentEvent);
}
+ public boolean getForcedReview(String fullChangeId) {
+ updateGerritClient(GerritClientType.COMMENTS, fullChangeId);
+ return gerritClientComments.getForcedReview();
+ }
+
public boolean isDisabledUser(String authorUsername) {
return gerritClientPatchSet.isDisabledUser(authorUsername);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClientComments.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClientComments.java
index 772d598..2adadbe 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClientComments.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/gerrit/GerritClientComments.java
@@ -26,6 +26,7 @@
public class GerritClientComments extends GerritClientAccount {
private static final String ROLE_USER = "user";
private static final String ROLE_ASSISTANT = "assistant";
+ private static final Pattern REVIEW_LAST_COMMAND_PATTERN = Pattern.compile("/review_last\\b");
private static final Integer MAX_SECS_GAP_BETWEEN_EVENT_AND_COMMENT = 2;
private final Gson gson = new Gson();
@@ -36,6 +37,8 @@
private String authorUsername;
@Getter
private List<GerritComment> commentProperties;
+ @Getter
+ private Boolean forcedReview;
public GerritClientComments(Configuration config) {
super(config);
@@ -47,6 +50,7 @@
public boolean retrieveLastComments(Event event, String fullChangeId) {
commentsStartTimestamp = event.eventCreatedOn;
+ forcedReview = false;
CommentAddedEvent commentAddedEvent = (CommentAddedEvent) event;
authorUsername = commentAddedEvent.author.get().username;
log.debug("Found comments by '{}' on {}", authorUsername, commentsStartTimestamp);
@@ -127,6 +131,11 @@
return true;
}
+ private boolean isForcingReview(String comment) {
+ Matcher reviewCommandMatcher = REVIEW_LAST_COMMAND_PATTERN.matcher(comment);
+ return reviewCommandMatcher.find();
+ }
+
private void addAllComments(String fullChangeId) {
try {
List<GerritComment> latestComments = getLastComments(fullChangeId);
@@ -135,6 +144,12 @@
}
for (GerritComment latestComment : latestComments) {
String commentMessage = latestComment.getMessage();
+ if (isForcingReview(commentMessage)) {
+ log.debug("Forced review command detected in message {}", commentMessage);
+ forcedReview = true;
+ commentProperties.clear();
+ return;
+ }
if (isBotAddressed(commentMessage)) {
commentProperties.add(latestComment);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
index 22efacd..b360ff4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/EventListenerHandler.java
@@ -20,6 +20,7 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.concurrent.*;
@@ -27,6 +28,10 @@
@Slf4j
public class EventListenerHandler {
+ private final static Map<String, Boolean> EVENT_COMMENT_MAP = Map.of(
+ "patchset-created", false,
+ "comment-added", true
+ );
private final PatchSetReviewer reviewer;
private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);
@@ -166,28 +171,34 @@
private boolean preprocessEvent(Event event, String fullChangeId, Project.NameKey projectNameKey) {
String eventType = Optional.ofNullable(event.getType()).orElse("");
log.info("Event type {}", eventType);
+ if (!EVENT_COMMENT_MAP.containsKey(eventType) ) {
+ return false;
+ }
PatchSetEvent patchSetEvent = (PatchSetEvent) event;
if (!isReviewEnabled(patchSetEvent, projectNameKey)) {
return false;
}
- switch (eventType) {
- case "patchset-created":
- if (!isPatchSetReviewEnabled(patchSetEvent)) {
- return false;
+ boolean isCommentEvent = EVENT_COMMENT_MAP.get(eventType);
+ if (isCommentEvent) {
+ if (!gerritClient.retrieveLastComments(event, fullChangeId)) {
+ if (gerritClient.getForcedReview(fullChangeId)) {
+ isCommentEvent = false;
}
- reviewer.setCommentEvent(false);
- break;
- case "comment-added":
- if (!gerritClient.retrieveLastComments(event, fullChangeId)) {
+ else {
log.info("No comments found for review");
return false;
}
- reviewer.setCommentEvent(true);
- break;
- default:
- return false;
+ }
}
+ else {
+ if (!isPatchSetReviewEnabled(patchSetEvent)) {
+ log.debug("Patch Set review disabled");
+ return false;
+ }
+ }
+ log.debug("Flag `isCommentEvent` set to {}", isCommentEvent);
+ reviewer.setCommentEvent(isCommentEvent);
return true;
}