Skip to content

refactor(version): simplify version comparison logic #10109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 9 additions & 36 deletions api/controllers/console/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import requests
from flask_restful import Resource, reqparse
from packaging import version

from configs import dify_config

Expand Down Expand Up @@ -47,43 +48,15 @@ def get(self):


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:
try:
latest = version.parse(latest_version)
current = version.parse(current_version)

# Compare versions
return latest > current
except version.InvalidVersion:
logging.warning(f"Invalid version format: latest={latest_version}, current={current_version}")
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")
14 changes: 0 additions & 14 deletions api/tests/unit_tests/controllers/test_compare_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,3 @@
)
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")