Files
PortProtonQt/portprotonqt/version_utils.py
2026-01-06 11:51:53 +05:00

80 lines
2.6 KiB
Python

import os
import re
import urllib.parse
def version_sort_key(entry):
"""
Create a sort key for version-aware sorting of Proton/Wine entries.
Sorts by prefix alphabetically, then by version number (descending - newer first).
"""
if isinstance(entry, dict):
name = entry.get('name', '')
url = entry.get('url', '')
if url and not name:
parsed_url = urllib.parse.urlparse(url)
name = os.path.basename(parsed_url.path)
else:
name = entry
# Remove extensions
for ext in ['.tar.gz', '.tar.xz', '.zip']:
if name.lower().endswith(ext):
name = name[:-len(ext)]
break
# Normalize the name
name_lower = name.lower().strip()
# Replace underscores and spaces with hyphens for consistency
normalized = name_lower.replace('_', '-').replace(' ', '-')
# Extract all numeric sequences and text parts
tokens = re.findall(r'\d+|\D+', normalized)
# Find where the version numbers start
# Usually after the first text token(s)
prefix_parts = []
version_parts = []
first_number_index = -1
# Find the first number token
for i, token in enumerate(tokens):
if token.isdigit():
first_number_index = i
break
# If we found a number, everything before it is prefix
if first_number_index > 0:
for i in range(first_number_index):
prefix_parts.append(tokens[i].strip('-'))
# Everything from first number onwards is version
for i in range(first_number_index, len(tokens)):
token = tokens[i]
if token.isdigit():
# Negative for descending order (higher versions first)
version_parts.append((0, -int(token)))
else:
# Part of version string (like "rc", "staging", etc.)
cleaned = token.strip('-')
if cleaned:
version_parts.append((1, cleaned))
else:
# No numbers found, treat entire thing as prefix
prefix_parts = [t.strip('-') for t in tokens if t.strip('-')]
# Clean up prefix
prefix = '-'.join(p for p in prefix_parts if p).strip('-')
# If no prefix found, use first token
if not prefix:
prefix = tokens[0] if tokens else normalized
# If no version parts found, add a default
if not version_parts:
version_parts = [(0, 0)]
# Return sort key: (prefix for grouping, version parts for version sorting, normalized name)
# Use normalized name for tie-breaking to avoid issues with spaces vs underscores
return (prefix, version_parts, normalized)