diff --git a/minimum_versions/policy.py b/minimum_versions/policy.py index 6dd144a..aa268a2 100644 --- a/minimum_versions/policy.py +++ b/minimum_versions/policy.py @@ -58,9 +58,21 @@ def is_suitable_release(release): if release.timestamp is None: return False - segments = release.version.extend_to_length(3).segments() + segments = release.version.segments() - return segments[2] == [0] + return all(isinstance(part, int) for segment in segments for part in segment) + + +def first_release_of_each_minor(releases): + # not every minor version has a x.y.0 release (e.g. netcdf4 1.7 starts at + # 1.7.1), so use the first release of each minor version instead + first_releases = {} + for release in sorted(releases): + segments = release.version.extend_to_length(2).segments() + minor = tuple(tuple(segment) for segment in segments[:2]) + first_releases.setdefault(minor, release) + + return sorted(first_releases.values(), key=lambda release: release.timestamp) @dataclass @@ -80,9 +92,9 @@ def minimum_version(self, today, package_name, releases): if (override := self.overrides.get(package_name)) is not None: return find_release(releases, version=override) - suitable_releases = [ + suitable_releases = first_release_of_each_minor( release for release in releases if is_suitable_release(release) - ] + ) if not suitable_releases: raise ValueError(f"Cannot find valid releases for {package_name}") diff --git a/minimum_versions/tests/test_policy.py b/minimum_versions/tests/test_policy.py index 1e0decd..76e54e1 100644 --- a/minimum_versions/tests/test_policy.py +++ b/minimum_versions/tests/test_policy.py @@ -30,6 +30,20 @@ dt.date(2024, 9, 5), Release(Version("1.1.1"), 0, dt.datetime(2023, 12, 1)), ), + pytest.param( + "netcdf4", + Policy({}, 12, {}), + dt.date(2025, 9, 1), + Release(Version("1.7.1"), 0, dt.datetime(2024, 6, 18)), + id="no-x.y.0-release", + ), + pytest.param( + "netcdf4", + Policy({}, 12, {}), + dt.date(2024, 9, 1), + Release(Version("1.6.0"), 0, dt.datetime(2022, 6, 29)), + id="no-x.y.0-release-too-recent", + ), ), ) def test_policy_minimum_version(package_name, policy, today, expected): @@ -49,6 +63,13 @@ def test_policy_minimum_version(package_name, policy, today, expected): Release(Version("1.2.0"), 0, dt.datetime(2024, 1, 3)), Release(Version("1.2.1"), 0, dt.datetime(2024, 2, 5)), ], + "netcdf4": [ + Release(Version("1.6.0"), 0, dt.datetime(2022, 6, 29)), + Release(Version("1.6.5"), 0, dt.datetime(2023, 10, 20)), + Release(Version("1.7.0rc1"), 0, dt.datetime(2024, 5, 1)), + Release(Version("1.7.1"), 0, dt.datetime(2024, 6, 18)), + Release(Version("1.7.2"), 0, dt.datetime(2024, 10, 22)), + ], } actual = policy.minimum_version(today, package_name, releases[package_name])