Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions release_notes_generator/chapters/custom_chapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def populate(self, records: dict[str, Record]) -> None:
# Quick intersection check
if any(lbl in ch.labels for lbl in record_labels):
if record_id not in ch.rows:
record.added_into_chapters(ch.title)
ch.add_row(record_id, record.to_chapter_row(True))
# Track for backward compatibility (not used for gating anymore)
if record_id not in self.populated_record_numbers_list:
Expand Down
11 changes: 11 additions & 0 deletions release_notes_generator/chapters/service_chapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def populate(self, records: dict[str, Record]) -> None:
logger.debug("Skipping open HierarchyIssueRecord %s (pr_count=%d)", record_id, pr_count)
elif is_issue_like and pr_count > 0:
# Open issue/sub-issue with linked PRs → add to the specific chapter
record.added_into_chapters(MERGED_PRS_LINKED_TO_NOT_CLOSED_ISSUES)
self.chapters[MERGED_PRS_LINKED_TO_NOT_CLOSED_ISSUES].add_row(
record_id, record.to_chapter_row()
)
Expand All @@ -145,6 +146,7 @@ def populate(self, records: dict[str, Record]) -> None:
pass
else:
if record_id not in self.used_record_numbers:
record.added_into_chapters(OTHERS_NO_TOPIC)
self.chapters[OTHERS_NO_TOPIC].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -164,6 +166,7 @@ def __populate_closed_issues(self, record: IssueRecord, record_id: int | str) ->
pulls_count = record.pull_requests_count()

if pulls_count == 0:
record.added_into_chapters(CLOSED_ISSUES_WITHOUT_PULL_REQUESTS)
self.chapters[CLOSED_ISSUES_WITHOUT_PULL_REQUESTS].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)
populated = True
Expand All @@ -174,6 +177,7 @@ def __populate_closed_issues(self, record: IssueRecord, record_id: int | str) ->
if self.__is_row_present(record_id) and not self.duplicity_allowed():
return

record.added_into_chapters(CLOSED_ISSUES_WITHOUT_USER_DEFINED_LABELS)
self.chapters[CLOSED_ISSUES_WITHOUT_USER_DEFINED_LABELS].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)
populated = True
Expand All @@ -189,6 +193,7 @@ def __populate_closed_issues(self, record: IssueRecord, record_id: int | str) ->
if record_id in self.used_record_numbers:
return

record.added_into_chapters(OTHERS_NO_TOPIC)
self.chapters[OTHERS_NO_TOPIC].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -209,6 +214,7 @@ def __populate_pr(self, record: PullRequestRecord, record_id: int | str) -> None
if self.__is_row_present(record_id) and not self.duplicity_allowed():
return

record.added_into_chapters(MERGED_PRS_WITHOUT_ISSUE_AND_USER_DEFINED_LABELS)
self.chapters[MERGED_PRS_WITHOUT_ISSUE_AND_USER_DEFINED_LABELS].add_row(
record_id, record.to_chapter_row()
)
Expand All @@ -219,6 +225,7 @@ def __populate_pr(self, record: PullRequestRecord, record_id: int | str) -> None
if self.__is_row_present(record_id) and not self.duplicity_allowed():
return

record.added_into_chapters(MERGED_PRS_LINKED_TO_NOT_CLOSED_ISSUES)
self.chapters[MERGED_PRS_LINKED_TO_NOT_CLOSED_ISSUES].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -229,6 +236,7 @@ def __populate_pr(self, record: PullRequestRecord, record_id: int | str) -> None
if record_id in self.used_record_numbers:
return

record.added_into_chapters(OTHERS_NO_TOPIC)
self.chapters[OTHERS_NO_TOPIC].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -241,6 +249,7 @@ def __populate_pr(self, record: PullRequestRecord, record_id: int | str) -> None
if self.__is_row_present(record_id) and not self.duplicity_allowed():
return

record.added_into_chapters(CLOSED_PRS_WITHOUT_ISSUE_AND_USER_DEFINED_LABELS)
self.chapters[CLOSED_PRS_WITHOUT_ISSUE_AND_USER_DEFINED_LABELS].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -252,6 +261,7 @@ def __populate_pr(self, record: PullRequestRecord, record_id: int | str) -> None
return

# not record.is_present_in_chapters:
record.added_into_chapters(OTHERS_NO_TOPIC)
self.chapters[OTHERS_NO_TOPIC].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand All @@ -262,6 +272,7 @@ def __populate_direct_commit(self, record: CommitRecord, record_id: int | str) -
@param record: The CommitRecord object representing the direct commit.
@return: None
"""
record.added_into_chapters(DIRECT_COMMITS)
self.chapters[DIRECT_COMMITS].add_row(record_id, record.to_chapter_row())
self.used_record_numbers.append(record_id)

Expand Down
2 changes: 0 additions & 2 deletions release_notes_generator/model/record/commit_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ def commit(self) -> Commit:
# methods - override Record methods

def to_chapter_row(self, add_into_chapters: bool = True) -> str:
if add_into_chapters:
self.added_into_chapters()
row_prefix = f"{ActionInputs.get_duplicity_icon()} " if self.present_in_chapters() > 1 else ""

# collecting values for formatting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ def get_labels(self) -> list[str]:
# methods - override ancestor methods
def to_chapter_row(self, add_into_chapters: bool = True) -> str:
logger.debug("Rendering hierarchy issue row for issue #%s", self.issue.number)
if add_into_chapters:
self.added_into_chapters()
row_prefix = f"{ActionInputs.get_duplicity_icon()} " if self.present_in_chapters() > 1 else ""
format_values: dict[str, Any] = {}

Expand Down
2 changes: 0 additions & 2 deletions release_notes_generator/model/record/issue_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ def find_issue(self, issue_number: int) -> Optional["IssueRecord"]:
return None

def to_chapter_row(self, add_into_chapters: bool = True) -> str:
if add_into_chapters:
self.added_into_chapters()
row_prefix = f"{ActionInputs.get_duplicity_icon()} " if self.present_in_chapters() > 1 else ""
format_values: dict[str, Any] = {}

Expand Down
3 changes: 0 additions & 3 deletions release_notes_generator/model/record/pull_request_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ def get_labels(self) -> list[str]:
return self.labels

def to_chapter_row(self, add_into_chapters: bool = True) -> str:
if add_into_chapters:
self.added_into_chapters()

row_prefix = f"{ActionInputs.get_duplicity_icon()} " if self.present_in_chapters() > 1 else ""
format_values: dict[str, Any] = {}

Expand Down
22 changes: 12 additions & 10 deletions release_notes_generator/model/record/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Record(metaclass=ABCMeta):
RELEASE_NOTE_LINE_MARKS: list[str] = ["-", "*", "+"]

def __init__(self, labels: Optional[list[str]] = None, skip: bool = False):
self._present_in_chapters = 0
self._present_in_chapters: set[str] = set()
self._skip = skip
self._is_cross_repo: bool = False
self._is_release_note_detected: Optional[bool] = None
Expand All @@ -52,7 +52,7 @@ def is_present_in_chapters(self) -> bool:
Returns:
bool: True if the record is present in at least one chapter, False otherwise.
"""
return self._present_in_chapters > 0
return len(self._present_in_chapters) > 0

@property
def is_cross_repo(self) -> bool:
Expand Down Expand Up @@ -190,21 +190,23 @@ def get_rls_notes(self, line_marks: Optional[list[str]] = None) -> str:

# shared methods

def added_into_chapters(self) -> None:
def added_into_chapters(self, chapter_id: str) -> None:
"""
Increments the count of chapters in which the record is present.
Returns: None
Adds a chapter identifier to track which chapters contain this record.

Parameters:
chapter_id (str): The unique identifier of the chapter.
"""
# TODO - fix in #191
self._present_in_chapters += 1
self._present_in_chapters.add(chapter_id)

def present_in_chapters(self) -> int:
"""
Gets the count of chapters in which the record is present.
Gets the count of unique chapters in which the record is present.

Returns:
int: The count of chapters in which the record is present.
int: The count of unique chapters containing this record.
"""
return self._present_in_chapters
return len(self._present_in_chapters)

def contains_min_one_label(self, labels: list[str]) -> bool:
"""
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/test_release_notes_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ def __init__(self, _id: str, _labels: list[str]):
self.labels = _labels
self.skip = False
self.is_present_in_chapters = False
self._chapters = set()

def contains_change_increment(self): # matches code expectation in populate
return True

def to_chapter_row(self, _include_prs: bool): # simplified row rendering
return f"{self.id} row"

def added_into_chapters(self, chapter_id: str): # track chapter additions
self._chapters.add(chapter_id)

return R(record_id, labels)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ def test_to_chapter_row_duplicate_with_icon(monkeypatch, mock_commit):
lambda: "[D]",
)
rec = CommitRecord(mock_commit)
# Simulate adding to first chapter
rec.added_into_chapters("chapter1")
first = rec.to_chapter_row(True)
# Simulate adding to second chapter
rec.added_into_chapters("chapter2")
second = rec.to_chapter_row(True)
assert not first.startswith("[D] ")
assert second.startswith("[D] ")
Expand Down
16 changes: 13 additions & 3 deletions tests/unit/release_notes_generator/model/test_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def contains_change_increment(self) -> bool:
def test_is_present_in_chapters():
rec = DummyRecord()
assert not rec.is_present_in_chapters
rec.added_into_chapters()
rec.added_into_chapters("chapter1")
assert rec.is_present_in_chapters

def test_skip_property():
Expand All @@ -82,8 +82,18 @@ def test_skip_property():
def test_present_in_chapters_count():
rec = DummyRecord()
assert rec.present_in_chapters() == 0
rec.added_into_chapters()
rec.added_into_chapters()
rec.added_into_chapters("chapter1")
rec.added_into_chapters("chapter2")
assert rec.present_in_chapters() == 2

def test_present_in_chapters_unique():
"""Test that adding the same chapter multiple times doesn't increase the count."""
rec = DummyRecord()
assert rec.present_in_chapters() == 0
rec.added_into_chapters("chapter1")
rec.added_into_chapters("chapter1") # Same chapter again
assert rec.present_in_chapters() == 1 # Should still be 1
rec.added_into_chapters("chapter2")
assert rec.present_in_chapters() == 2

def test_contains_min_one_label():
Expand Down
Loading