This patch fixes a bug where review-patch.py would detect and report an
error or warning only based off of the occurrence of the headers of the
error and warning sections. This led to consistent false positives as
often AI reviewers will create the header but put "none" or similar
filler text within the following body.

This patch updates the code in order to check if the AI review has a
body with error or warnings to fix and not just filler text. This is
done by keeping track of whether the for loop parser is within an error
or warning section; analyzing the first non-whitespace line within the
section. If the first non-whitespace line matches known filler then the
section can be ignored.  It has been observed that if the AI includes
filler then there is no actual concern.

These changes were tested against 10+ markdown AI review outputs with
several variations in formatting and filler text. The changes caught
error or warning sections with actual concerns and successfully ignored
sections containing only filler.

Signed-off-by: Matthew Gee <[email protected]>
---
 devtools/ai/review-patch.py | 48 +++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/devtools/ai/review-patch.py b/devtools/ai/review-patch.py
index 52601ac156..53ae7e6a4f 100755
--- a/devtools/ai/review-patch.py
+++ b/devtools/ai/review-patch.py
@@ -19,6 +19,7 @@
 from email.message import EmailMessage
 from pathlib import Path
 from typing import Any, Iterator
+from enum import Flag, auto
 
 from _common import (
     PROVIDERS,
@@ -120,6 +121,12 @@
 EXIT_ERRORS = 3
 
 
+class ReviewParseState(Flag):
+    NORMAL = auto()
+    IN_ERROR = auto()
+    IN_WARNING = auto()
+
+
 def classify_review(review_text: str, output_format: str) -> int:
     """Classify review result and return appropriate exit code.
 
@@ -147,22 +154,43 @@ def classify_review(review_text: str, output_format: str) 
-> int:
             pass  # Fall through to text scanning
 
     if not has_errors and not has_warnings:
-        # Scan review text for severity indicators.
-        # Match section headers and inline markers across text/markdown/html.
-        for line in review_text.splitlines():
-            stripped = line.strip().lower()
-            # Skip quoted patch context lines
-            if stripped.startswith(">") or stripped.startswith("diff --git"):
+        # Matches against error or warning section headers
+        rgx_header_match: str = r"(#+\s)?(\*+)?(<h[1-3]>)?{err_or_warn}"
+        # Matches against observed filler text
+        rgx_filler_match: str = r"(none(.)?$|\(must fix\)$|$)"
+
+        curr_line: str
+        for curr_line in review_text.splitlines():
+            stripped: str = curr_line.strip().lower()
+
+            if (
+                stripped.startswith(">")
+                or stripped.startswith("diff --git")
+                or stripped == ""
+            ):
                 continue
-            if re.match(r"^(#{1,3}\s+)?(\*{0,2})error", stripped) or re.match(
-                r"^<h[1-3]>\s*error", stripped
+
+            elif re.match(rgx_header_match.format(err_or_warn="error"), 
stripped):
+                curr_state = ReviewParseState.IN_ERROR
+
+            elif re.match(rgx_header_match.format(err_or_warn="warning"), 
stripped):
+                curr_state = ReviewParseState.IN_WARNING
+
+            elif curr_state == ReviewParseState.IN_ERROR and not re.match(
+                rgx_filler_match, stripped
             ):
+                curr_state = ReviewParseState.NORMAL
                 has_errors = True
-            elif re.match(r"^(#{1,3}\s+)?(\*{0,2})warning", stripped) or 
re.match(
-                r"^<h[1-3]>\s*warning", stripped
+
+            elif curr_state == ReviewParseState.IN_WARNING and not re.match(
+                rgx_filler_match, stripped
             ):
+                curr_state = ReviewParseState.NORMAL
                 has_warnings = True
 
+            else:
+                curr_state = ReviewParseState.NORMAL
+
     if has_errors:
         return EXIT_ERRORS
     if has_warnings:
-- 
2.54.0

Reply via email to