Skip to content

Commit

Permalink
feat(api): add version comparison logic (#8902)
Browse files Browse the repository at this point in the history
  • Loading branch information
laipz8200 authored Sep 30, 2024
1 parent 369e1e6 commit 3af65b2
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 4 deletions.
49 changes: 45 additions & 4 deletions api/controllers/console/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,52 @@ def get(self):
return result

content = json.loads(response.content)
result["version"] = content["version"]
result["release_date"] = content["releaseDate"]
result["release_notes"] = content["releaseNotes"]
result["can_auto_update"] = content["canAutoUpdate"]
if _has_new_version(latest_version=content["version"], current_version=f"{args.get('current_version')}"):
result["version"] = content["version"]
result["release_date"] = content["releaseDate"]
result["release_notes"] = content["releaseNotes"]
result["can_auto_update"] = content["canAutoUpdate"]
return result


def _has_new_version(*, latest_version: str, current_version: str) -> bool:
def parse_version(version: str) -> tuple:
# Split version into parts and pre-release suffix if any
parts = version.split("-")
version_parts = parts[0].split(".")
pre_release = parts[1] if len(parts) > 1 else None

# Validate version format
if len(version_parts) != 3:
raise ValueError(f"Invalid version format: {version}")

try:
# Convert version parts to integers
major, minor, patch = map(int, version_parts)
return (major, minor, patch, pre_release)
except ValueError:
raise ValueError(f"Invalid version format: {version}")

latest = parse_version(latest_version)
current = parse_version(current_version)

# Compare major, minor, and patch versions
for latest_part, current_part in zip(latest[:3], current[:3]):
if latest_part > current_part:
return True
elif latest_part < current_part:
return False

# If versions are equal, check pre-release suffixes
if latest[3] is None and current[3] is not None:
return True
elif latest[3] is not None and current[3] is None:
return False
elif latest[3] is not None and current[3] is not None:
# Simple string comparison for pre-release versions
return latest[3] > current[3]

return False


api.add_resource(VersionApi, "/version")
38 changes: 38 additions & 0 deletions api/tests/unit_tests/controllers/test_compare_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest

from controllers.console.version import _has_new_version


@pytest.mark.parametrize(
("latest_version", "current_version", "expected"),
[
("1.0.1", "1.0.0", True),
("1.1.0", "1.0.0", True),
("2.0.0", "1.9.9", True),
("1.0.0", "1.0.0", False),
("1.0.0", "1.0.1", False),
("1.0.0", "2.0.0", False),
("1.0.1", "1.0.0-beta", True),
("1.0.0", "1.0.0-alpha", True),
("1.0.0-beta", "1.0.0-alpha", True),
("1.0.0", "1.0.0-rc1", True),
("1.0.0", "0.9.9", True),
("1.0.0", "1.0.0-dev", True),
],
)
def test_has_new_version(latest_version, current_version, expected):
assert _has_new_version(latest_version=latest_version, current_version=current_version) == expected


def test_has_new_version_invalid_input():
with pytest.raises(ValueError):
_has_new_version(latest_version="1.0", current_version="1.0.0")

with pytest.raises(ValueError):
_has_new_version(latest_version="1.0.0", current_version="1.0")

with pytest.raises(ValueError):
_has_new_version(latest_version="invalid", current_version="1.0.0")

with pytest.raises(ValueError):
_has_new_version(latest_version="1.0.0", current_version="invalid")

0 comments on commit 3af65b2

Please sign in to comment.