Skip to content

Commit c2b2eef

Browse files
nibzardclaude
andcommitted
fix(ci): treat an edit to a listed item as maintenance
The validator counted every `+- [` line in the diff as a new submission. A change to an entry that is already listed produces such a line, so any correction to an existing item, a typo, a description, a badge, was told to use the `Add:` title and the new-item template. Compare the added line against the line it replaced, and report a new item only when that name and URL were not listed before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent a54aadb commit c2b2eef

2 files changed

Lines changed: 58 additions & 6 deletions

File tree

scripts/test_validate_contribution.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
import unittest
77

8-
from validate_contribution import REQUIRED_BODY_SECTIONS, extract_body_sections, normalize_section
8+
from validate_contribution import (
9+
REQUIRED_BODY_SECTIONS,
10+
extract_body_sections,
11+
new_items_in_diff,
12+
normalize_section,
13+
)
914

1015

1116
BODY = """## Summary
@@ -63,5 +68,33 @@ def test_empty_section_is_not_reported(self) -> None:
6368
self.assertFalse(sections.get("Public reference"))
6469

6570

71+
ITEM = "- [Zoom Search](https://github.com/goofrey/zoom-search) - A tool."
72+
BADGED = ITEM + " ![stars](https://img.shields.io/github/stars/goofrey/zoom-search?style=social)"
73+
74+
75+
class NewItemsInDiffTest(unittest.TestCase):
76+
def test_added_line_is_a_new_item(self) -> None:
77+
diff = "--- a/README.md\n+++ b/README.md\n@@ -1 +1,2 @@\n+" + ITEM
78+
self.assertEqual(new_items_in_diff(diff), [ITEM])
79+
80+
def test_edited_line_is_not_a_new_item(self) -> None:
81+
# Changing the text of an entry that is already listed is maintenance.
82+
diff = "--- a/README.md\n+++ b/README.md\n@@ -1 +1 @@\n-" + ITEM + "\n+" + BADGED
83+
self.assertEqual(new_items_in_diff(diff), [])
84+
85+
def test_an_edit_does_not_hide_a_new_item(self) -> None:
86+
other = "- [Other](https://example.com) - Another tool."
87+
diff = ("--- a/README.md\n+++ b/README.md\n@@ -1 +1,2 @@\n"
88+
"-" + ITEM + "\n+" + BADGED + "\n+" + other)
89+
self.assertEqual(new_items_in_diff(diff), [other])
90+
91+
def test_removal_alone_adds_nothing(self) -> None:
92+
diff = "--- a/README.md\n+++ b/README.md\n@@ -1 +0,0 @@\n-" + ITEM
93+
self.assertEqual(new_items_in_diff(diff), [])
94+
95+
def test_diff_headers_are_ignored(self) -> None:
96+
self.assertEqual(new_items_in_diff("--- a/README.md\n+++ b/README.md\n"), [])
97+
98+
6699
if __name__ == "__main__":
67100
unittest.main()

scripts/validate_contribution.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,34 @@ def changed_files(base_sha: str) -> set[str]:
6060
return {line.strip() for line in diff.splitlines() if line.strip()}
6161

6262

63+
def item_key(item_line: str) -> tuple[str, str] | None:
64+
match = ITEM_LINE_RE.match(item_line)
65+
if not match:
66+
return None
67+
return match.group("name").strip(), match.group("url").strip()
68+
69+
70+
def new_items_in_diff(diff: str) -> list[str]:
71+
new_lines: list[str] = []
72+
changed_keys: set[tuple[str, str]] = set()
73+
for line in diff.splitlines():
74+
if line.startswith(("+++", "---")):
75+
continue
76+
if re.match(r"^\+- \[", line):
77+
new_lines.append(line[1:])
78+
elif re.match(r"^-- \[", line):
79+
key = item_key(line[1:])
80+
if key:
81+
changed_keys.add(key)
82+
# A rewritten line for an item that was already listed is an edit, not a submission.
83+
return [line for line in new_lines if item_key(line) not in changed_keys]
84+
85+
6386
def added_item_lines(base_sha: str) -> list[tuple[str, str]]:
6487
added: list[tuple[str, str]] = []
6588
for path in ("README.md", "ARCHIVE.md"):
6689
diff = run_git("diff", "--unified=0", f"{base_sha}...HEAD", "--", path)
67-
for line in diff.splitlines():
68-
if line.startswith("+++"):
69-
continue
70-
if re.match(r"^\+- \[", line):
71-
added.append((path, line[1:]))
90+
added.extend((path, line) for line in new_items_in_diff(diff))
7291
return added
7392

7493

0 commit comments

Comments
 (0)