Skip to content

Commit

Permalink
Addons: refactor sorting versions for flyout (#11278)
Browse files Browse the repository at this point in the history
* Addons: refactor sorting versions for flyout

Closes #11207

* Apply suggestions from code review

Co-authored-by: Santos Gallegos <stsewd@proton.me>

---------

Co-authored-by: Santos Gallegos <stsewd@proton.me>
  • Loading branch information
humitos and stsewd committed Apr 23, 2024
1 parent 3912b7d commit ea333be
Showing 1 changed file with 56 additions and 47 deletions.
103 changes: 56 additions & 47 deletions readthedocs/projects/version_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,27 @@ def determine_stable_version(version_list):
return None


def sort_versions_python_packaging(version_list, latest_stable_at_beginning):
def sort_versions_generic(
version_list,
exception,
parse_version,
latest_stable_at_beginning,
raw_pattern=None,
):
"""
Sort Read the Docs versions list using ``packaging`` algorithm.
Sort Read the Docs versions based on ``parse_version`` function.
All the invalid version (raise ``InvalidVersion``) are added at the end
sorted alphabetically.
``parse_version`` function is called with ``slug`` and ``raw_pattern`` as arguments to decide how to sort them.
https://pypi.org/project/packaging/
https://packaging.python.org/en/latest/specifications/version-specifiers/
All versions that raise ``exception`` are added at the end sorted alphabetically.
"""

alphabetically_sorted_version_list = sorted(
version_list,
key=operator.attrgetter("slug"),
)

initial_versions = []

valid_versions = []
invalid_versions = []
for i, version in enumerate(alphabetically_sorted_version_list):
Expand All @@ -196,8 +200,16 @@ def sort_versions_python_packaging(version_list, latest_stable_at_beginning):
continue

try:
valid_versions.append((version, Version(version.slug)))
except InvalidVersion:
valid_versions.append(
(
version,
parse_version(
slug=version.slug,
raw_pattern=raw_pattern,
),
)
)
except exception:
# When the version is invalid, we put it at the end while keeping
# the alphabetically sorting between the invalid ones.
invalid_versions.append((version, None))
Expand All @@ -207,19 +219,28 @@ def sort_versions_python_packaging(version_list, latest_stable_at_beginning):
+ sorted(valid_versions, key=operator.itemgetter(1), reverse=True)
+ invalid_versions
)

return [item[0] for item in all_versions if item[0] is not None]


def sort_versions_calver(version_list, latest_stable_at_beginning):
def sort_versions_python_packaging(version_list, latest_stable_at_beginning):
"""
Sort Read the Docs versions using CalVer pattern: ``YYYY.0M.0M``.
Sort Read the Docs versions list using ``packaging`` algorithm.
All the invalid version are added at the end sorted alphabetically.
All the invalid version (raise ``InvalidVersion``) are added at the end
sorted alphabetically.
https://pypi.org/project/packaging/
https://packaging.python.org/en/latest/specifications/version-specifiers/
"""
raw_pattern = "YYYY.0M.0D"
return sort_versions_custom_pattern(
version_list, raw_pattern, latest_stable_at_beginning

def parse_version(*args, slug=None, **kwargs):
return Version(slug)

return sort_versions_generic(
version_list,
InvalidVersion,
parse_version,
latest_stable_at_beginning,
)


Expand All @@ -233,40 +254,28 @@ def sort_versions_custom_pattern(version_list, raw_pattern, latest_stable_at_beg
It uses ``Bumpver`` behinds the scenes for the parsing and sorting.
https://github.com/mbarkhau/bumpver
"""
alphabetically_sorted_version_list = sorted(

def parse_version(*args, slug=None, raw_pattern=None, **kwargs):
return parse_version_info(slug, raw_pattern=raw_pattern)

return sort_versions_generic(
version_list,
key=operator.attrgetter("slug"),
PatternError,
parse_version,
latest_stable_at_beginning,
raw_pattern,
)

initial_versions = []
valid_versions = []
invalid_versions = []
for i, version in enumerate(alphabetically_sorted_version_list):
if latest_stable_at_beginning:
if version.slug in (STABLE, LATEST):
# It relies on the version list sorted alphabetically first ("l" comes first than "s")
initial_versions.append((version, version.slug))
continue

try:
valid_versions.append(
(
version,
parse_version_info(
version.slug,
raw_pattern=raw_pattern,
),
)
)
except PatternError:
# When the version is invalid, we put it at the end while keeping
# the alphabetically sorting between the invalid ones.
invalid_versions.append((version, None))
def sort_versions_calver(version_list, latest_stable_at_beginning):
"""
Sort Read the Docs versions using CalVer pattern: ``YYYY.0M.0M``.
all_versions = (
initial_versions
+ sorted(valid_versions, key=operator.itemgetter(1), reverse=True)
+ invalid_versions
All the invalid version are added at the end sorted alphabetically.
"""
raw_pattern = "YYYY.0M.0D"
return sort_versions_custom_pattern(
version_list,
raw_pattern,
latest_stable_at_beginning,
)

return [item[0] for item in all_versions if item[0] is not None]

0 comments on commit ea333be

Please sign in to comment.