Skip to content

Commit c5dada8

Browse files
authored
fix: don't mark a subject red when only its author is wrong (#339)
1 parent 21674f1 commit c5dada8

2 files changed

Lines changed: 59 additions & 6 deletions

File tree

‎main.py‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,12 +1161,18 @@ def _first_value(scope: ScopeResult) -> str:
11611161
11621162
The text the action piped in when it has it, then the whole message the
11631163
``message`` rule reports, then whichever rule names a value first. A PR
1164-
description has no such line: its first line does not identify it.
1164+
description has no such line: its first line does not identify it. An
1165+
AI rule's value is the tool or the author it found, never the text, so
1166+
it never stands in for a commit's subject.
11651167
"""
11661168
if scope.label == "PR description":
11671169
return ""
11681170
values = [scope.text, _message_value(scope)]
1169-
values.extend(str(check.get("value") or "") for check in scope.checks)
1171+
values.extend(
1172+
str(check.get("value") or "")
1173+
for check in scope.checks
1174+
if check.get("rule_id") not in AI_RULE_IDS
1175+
)
11701176
for value in values:
11711177
if value.strip():
11721178
return value.strip().splitlines()[0].strip()
@@ -1697,23 +1703,31 @@ def _hunk(scope: ScopeResult, status: str) -> list[str]:
16971703
"""
16981704
is_commit = bool(scope.sha) and scope.label.startswith("Commit")
16991705
lines = [f"@@ {scope.sha[:7] if is_commit else scope.label} @@"]
1706+
value = _first_value(scope)
17001707
removed: list[str] = []
17011708
added: list[str] = []
17021709
advice: list[str] = []
1710+
# Whether a piece of advice is about the value itself: a subject or a
1711+
# branch name that has to change. Advice about something else, such as
1712+
# an AI tool as the commit's author, leaves the subject as context.
1713+
about_value = False
17031714
for check in _findings(scope, status):
17041715
minus, plus = _line_edits(scope, check)
17051716
removed.extend(minus)
17061717
added.extend(plus)
17071718
if not (minus or plus):
17081719
advice.append(_advice(check))
1720+
checked = str(check.get("value") or "").strip()
1721+
about_value |= not checked or checked.splitlines()[0].strip() == value
17091722
if scope.raw_text and not scope.checks:
17101723
advice.append("the output could not be parsed, see the step log")
1724+
about_value = True
17111725
removed, added, advice = (list(dict.fromkeys(x)) for x in (removed, added, advice))
1712-
value = _first_value(scope)
17131726
if value and value not in removed:
1714-
# Advice is about the value itself, so it is what was found; a fix
1715-
# that only touches other lines leaves it as context.
1716-
lines.append(f"{'-' if advice else ' '} {value}")
1727+
# Advice about the value means it is what was found; a fix that only
1728+
# touches other lines, or advice about something else, leaves it as
1729+
# context.
1730+
lines.append(f"{'-' if about_value else ' '} {value}")
17171731
lines.extend(f"- {line}" for line in removed)
17181732
lines.extend(f"+ {line}" for line in added)
17191733
lines.extend(f"# {line}" for line in advice)

‎main_test.py‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,45 @@ def test_advice_is_about_the_value_so_the_value_is_red(self):
25862586
],
25872587
)
25882588

2589+
def test_an_ai_author_leaves_the_subject_as_context(self):
2590+
# CC017 is about who made the commit, not what its subject says.
2591+
scope = main.ScopeResult(
2592+
label="Commit 1/1",
2593+
sha=SHA_A,
2594+
text="fix: handle the empty case\n",
2595+
checks=[
2596+
make_check(
2597+
"message", "pass", "CC001", value="fix: handle the empty case"
2598+
),
2599+
make_check(
2600+
"ai_author",
2601+
"fail",
2602+
"CC017",
2603+
value="Claude <noreply@anthropic.com>",
2604+
suggest="Commit as yourself",
2605+
),
2606+
],
2607+
)
2608+
self.assertEqual(
2609+
self._hunks([scope]),
2610+
["@@ d87faca @@", " fix: handle the empty case", "# Commit as yourself"],
2611+
)
2612+
2613+
def test_an_ai_rules_value_never_stands_in_for_the_subject(self):
2614+
# An empty message has no subject; the author CC017 reports is not one.
2615+
scope = main.ScopeResult(
2616+
label="Commit 1/1",
2617+
sha=SHA_A,
2618+
checks=[
2619+
make_check("message", "pass", "CC001"),
2620+
make_check(
2621+
"ai_author", "pass", "CC017", value="Jane <jane@example.com>"
2622+
),
2623+
],
2624+
)
2625+
self.assertEqual(main._first_value(scope), "")
2626+
self.assertEqual(main._render_scopes([scope], False), [" ✔ d87faca"])
2627+
25892628
def test_two_rules_that_ask_for_the_same_line_show_it_once(self):
25902629
scope = ai_scope()
25912630
scope.checks.append({**scope.checks[0], "rule_id": "CC015"})

0 commit comments

Comments
 (0)