Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

refactor(changelog): simplify logic for get_oldest_and_newest_rev #1539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: v4-9-0-test
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
62 changes: 30 additions & 32 deletions commitizen/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from collections.abc import Generator, Iterable, Mapping, Sequence
from dataclasses import dataclass
from datetime import date
from itertools import chain, tee
from typing import TYPE_CHECKING, Any

from jinja2 import (
Expand Down Expand Up @@ -281,6 +282,16 @@ def incremental_build(
return output_lines


def get_next_tag_name_after_version(tags: Iterable[GitTag], version: str) -> str | None:
a, b = tee(chain((tag.name for tag in tags), [None]))
next(b, None)
try:
return next(y for x, y in zip(a, b) if x == version)
except StopIteration:
raise NoCommitsFoundError(f"Could not find a valid revision range. {version=}")
Comment on lines +285 to +291
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gbaian10 for reminding me here we don't have to use a while loop.



# TODO: unused, deprecate this?
def get_smart_tag_range(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if removing the function is a breaking change.

tags: Sequence[GitTag], newest: str, oldest: str | None = None
) -> list[GitTag]:
Expand Down Expand Up @@ -308,7 +319,7 @@ def get_smart_tag_range(


def get_oldest_and_newest_rev(
tags: Sequence[GitTag],
tags: Iterable[GitTag],
version: str,
rules: TagRules,
) -> tuple[str | None, str]:
Expand All @@ -318,39 +329,26 @@ def get_oldest_and_newest_rev(
- `0.1.0..0.4.0`: as a range
- `0.3.0`: as a single version
"""
oldest: str | None = None
newest: str | None = None
try:
oldest, newest = version.split("..")
except ValueError:
newest = version
if not (newest_tag := rules.find_tag_for(tags, newest)):
oldest_version, sep, newest_version = version.partition("..")
if not sep:
newest_version = version
oldest_version = ""

def get_tag_name(v: str) -> str:
if tag := rules.find_tag_for(tags, v):
return tag.name
raise NoCommitsFoundError("Could not find a valid revision range.")

oldest_tag = None
oldest_tag_name = None
if oldest:
if not (oldest_tag := rules.find_tag_for(tags, oldest)):
raise NoCommitsFoundError("Could not find a valid revision range.")
oldest_tag_name = oldest_tag.name
newest_tag_name = get_tag_name(newest_version)
oldest_tag_name = get_tag_name(oldest_version) if oldest_version else None

tags_range = get_smart_tag_range(
tags, newest=newest_tag.name, oldest=oldest_tag_name
oldest_rev = get_next_tag_name_after_version(
tags, oldest_tag_name or newest_tag_name
)
if not tags_range:
raise NoCommitsFoundError("Could not find a valid revision range.")

oldest_rev: str | None = tags_range[-1].name
newest_rev = newest_tag.name

# check if it's the first tag created
# and it's also being requested as part of the range
if oldest_rev == tags[-1].name and oldest_rev == oldest_tag_name:
return None, newest_rev

# when they are the same, and it's also the
# first tag created
if oldest_rev == newest_rev:
return None, newest_rev

return oldest_rev, newest_rev
# Return None for oldest_rev if:
# 1. The oldest tag is the last tag in the list and matches the requested oldest tag
# 2. The oldest and the newest tag are the same
if oldest_rev == newest_tag_name:
return None, newest_tag_name
return oldest_rev, newest_tag_name
18 changes: 18 additions & 0 deletions tests/test_changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,24 @@ def test_get_smart_tag_range_returns_an_extra_for_a_single_tag(tags):
assert 2 == len(res)


def test_get_next_tag_name_after_version(tags):
# Test finding next tag after a version
next_tag_name = changelog.get_next_tag_name_after_version(tags, "v1.2.0")
assert next_tag_name == "v1.1.1"

next_tag_name = changelog.get_next_tag_name_after_version(tags, "v1.1.0")
assert next_tag_name == "v1.0.0"

# Test finding last tag when given version is last
last_tag_name = changelog.get_next_tag_name_after_version(tags, "v0.9.1")
assert last_tag_name is None

# Test error when version not found
with pytest.raises(changelog.NoCommitsFoundError) as exc_info:
changelog.get_next_tag_name_after_version(tags, "nonexistent")
assert "Could not find a valid revision range" in str(exc_info.value)


@dataclass
class TagDef:
name: str
Expand Down