From d99e5d4aa4c1d1f464b0b264f146f4515c6866f9 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sat, 19 Oct 2024 15:41:27 +0200 Subject: [PATCH 1/2] Refactor compute_stub_version for better understandability * Rename `date` argument to `today`. * Cache `last_date` and add an explaining comment. --- stub_uploader/get_version.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/stub_uploader/get_version.py b/stub_uploader/get_version.py index 9c1c7c08..8c9a6c49 100644 --- a/stub_uploader/get_version.py +++ b/stub_uploader/get_version.py @@ -50,8 +50,9 @@ def ensure_specificity(ver: list[int], specificity: int) -> None: ver.extend([0] * (specificity - len(ver))) +# `today` can be passed as an argument for testing purposes. def compute_stub_version( - version_spec: Specifier, published_versions: list[Version], date: datetime.date + version_spec: Specifier, published_versions: list[Version], today: datetime.date ) -> Version: # The most important postcondition is that the incremented version is greater than # all published versions. This ensures that users who don't pin get the most @@ -111,7 +112,7 @@ def compute_stub_version( base_version_changed = False ensure_specificity(base_version_parts, stub_specificity) - unused_date = find_unused_date(max_published, base_version_changed, date) + unused_date = find_unused_date(max_published, base_version_changed, today) new_version_parts = [*base_version_parts[:-1], unused_date.strftime("%Y%m%d")] new_version = Version(".".join(map(str, new_version_parts))) assert_compatibility( @@ -123,19 +124,25 @@ def compute_stub_version( return new_version +# `today` can be passed as an argument for testing purposes. def find_unused_date( - max_published: Version, base_version_changed: bool, date: datetime.date + max_published: Version, base_version_changed: bool, today: datetime.date ) -> datetime.date: + # Is not necessarily a date in case the package predates the switch + # to the current versioning scheme. + last_date = max_published.release[-1] + # If the base version changed, we should always be able to use the current date. if base_version_changed: - return date + return today # Make sure that the last published release is not unreasonable large. - assert int(date.strftime("%Y%m%d")) + 14 > max_published.release[-1] + assert int(today.strftime("%Y%m%d")) + 14 > last_date - while int(date.strftime("%Y%m%d")) <= max_published.release[-1]: - date = date + datetime.timedelta(days=1) - return date + new_date = today + while int(new_date.strftime("%Y%m%d")) <= last_date: + new_date += datetime.timedelta(days=1) + return new_date def assert_compatibility( From b5d76e95aec23ede964e6774ba19836ca0fee765 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sat, 19 Oct 2024 15:51:36 +0200 Subject: [PATCH 2/2] Fix version date calculation in corner cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, if the latest published stub version was higher than the upstream version (which could happen with our old versioning scheme), we always used the current date as last component. This failed when uploading the same package twice in a day – but also in our stub_uploader tests, which simulate a new upload. --- stub_uploader/get_version.py | 3 ++- tests/test_unit.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/stub_uploader/get_version.py b/stub_uploader/get_version.py index 8c9a6c49..f9ea7c77 100644 --- a/stub_uploader/get_version.py +++ b/stub_uploader/get_version.py @@ -97,7 +97,8 @@ def compute_stub_version( # But can't keep versioning compatible with upstream... is_compatible = False - base_version_changed = True + # We also use the latest stub version as the base version, not the version_spec. + base_version_changed = False elif version_base.release > max_published.release[:specificity]: # For example, version_base=1.2, max_published=1.1.0.4, return 1.2.0.YYYYMMDD diff --git a/tests/test_unit.py b/tests/test_unit.py index f69cf37c..77a0d01d 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -110,6 +110,7 @@ def test_compute_stub_version() -> None: _stub_ver("~=1.2.3", [f"1.2.3.{TODAY_V}", f"1.2.3.{TOMORROW_V}"]) == f"1.2.3.{IN_TWO_DAYS_V}" ) + assert _stub_ver("~=1.2.3", [f"1.4.0.{TODAY_V}"]) == f"1.4.0.{TOMORROW_V}" def test_collect_package_data() -> None: