mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-08-07 09:23:06 +02:00
Enhance version retrieval logic and add fallback mechanisms in _get_installed_version function
This commit is contained in:
@@ -85,3 +85,4 @@ line_length = 100
|
|||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
version_scheme = "guess-next-dev"
|
version_scheme = "guess-next-dev"
|
||||||
local_scheme = "no-local-version"
|
local_scheme = "no-local-version"
|
||||||
|
version_file = "repeater/_version.py"
|
||||||
|
|||||||
@@ -45,11 +45,24 @@ CHECK_CACHE_TTL = 600 # 10 minutes
|
|||||||
|
|
||||||
|
|
||||||
def _get_installed_version() -> str:
|
def _get_installed_version() -> str:
|
||||||
|
"""
|
||||||
|
Return the highest dist-info version found for pymc_repeater across all
|
||||||
|
directories the running interpreter actually uses.
|
||||||
|
|
||||||
|
Search strategy (union of all three to cover venvs, system, dist-packages):
|
||||||
|
1. site.getsitepackages() / getusersitepackages()
|
||||||
|
2. sys.path entries that look like package directories
|
||||||
|
3. Fallback: importlib.metadata, then the in-process __version__
|
||||||
|
|
||||||
|
Sanity check: the running process __version__ is used as a version floor.
|
||||||
|
If the disk scan returns something older than what is actually running, we
|
||||||
|
return __version__ instead – an older dist-info is definitively stale.
|
||||||
|
"""
|
||||||
import glob
|
import glob
|
||||||
import site as _site
|
import site as _site
|
||||||
|
import sys
|
||||||
|
|
||||||
# Collect all site-packages directories
|
# -- 1. Collect candidate directories ---------------------------------- #
|
||||||
dirs: list = []
|
dirs: list = []
|
||||||
try:
|
try:
|
||||||
dirs.extend(_site.getsitepackages())
|
dirs.extend(_site.getsitepackages())
|
||||||
@@ -59,7 +72,13 @@ def _get_installed_version() -> str:
|
|||||||
dirs.append(_site.getusersitepackages())
|
dirs.append(_site.getusersitepackages())
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
# Also include every sys.path entry that looks like a package directory so
|
||||||
|
# venvs and Debian dist-packages paths are covered.
|
||||||
|
for p in sys.path:
|
||||||
|
if p and ("site-packages" in p or "dist-packages" in p) and p not in dirs:
|
||||||
|
dirs.append(p)
|
||||||
|
|
||||||
|
# -- 2. Scan for dist-info METADATA files ------------------------------ #
|
||||||
pkg_glob = PACKAGE_NAME.replace("-", "_") + "-*.dist-info"
|
pkg_glob = PACKAGE_NAME.replace("-", "_") + "-*.dist-info"
|
||||||
candidates: list = []
|
candidates: list = []
|
||||||
for site_dir in dirs:
|
for site_dir in dirs:
|
||||||
@@ -75,28 +94,50 @@ def _get_installed_version() -> str:
|
|||||||
except OSError:
|
except OSError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# -- 3. Pick the highest candidate ------------------------------------- #
|
||||||
|
disk_version: Optional[str] = None
|
||||||
if candidates:
|
if candidates:
|
||||||
if len(candidates) == 1:
|
if len(candidates) == 1:
|
||||||
return candidates[0]
|
disk_version = candidates[0]
|
||||||
# Multiple dist-info dirs found (stale old version alongside new one).
|
else:
|
||||||
# Return the highest so an old leftover dir doesn't mask the real version.
|
try:
|
||||||
try:
|
from packaging.version import Version
|
||||||
from packaging.version import Version
|
disk_version = str(max(candidates, key=lambda v: Version(v)))
|
||||||
return str(max(candidates, key=lambda v: Version(v)))
|
except Exception:
|
||||||
except Exception:
|
# packaging unavailable – sort lexicographically as best-effort
|
||||||
return candidates[-1] # last found as a best-effort fallback
|
disk_version = sorted(candidates)[-1]
|
||||||
|
|
||||||
# Fallback: importlib.metadata (may be stale but better than nothing)
|
# -- 4. Fallbacks when disk scan found nothing ------------------------- #
|
||||||
|
if disk_version is None:
|
||||||
|
try:
|
||||||
|
from importlib.metadata import version as _pkg_ver
|
||||||
|
disk_version = _pkg_ver(PACKAGE_NAME)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if disk_version is None:
|
||||||
|
try:
|
||||||
|
from repeater import __version__
|
||||||
|
return __version__
|
||||||
|
except Exception:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
# -- 5. Sanity check: never return a version older than what's running -- #
|
||||||
|
# If the running process is already on a higher version than anything found
|
||||||
|
# on disk, the dist-info dirs are stale leftovers and __version__ is truth.
|
||||||
try:
|
try:
|
||||||
from importlib.metadata import version as _pkg_ver
|
from repeater import __version__ as _running
|
||||||
return _pkg_ver(PACKAGE_NAME)
|
from packaging.version import Version
|
||||||
|
if Version(_running) > Version(disk_version):
|
||||||
|
logger.debug(
|
||||||
|
f"[Update] Disk version {disk_version!r} < running {_running!r};"
|
||||||
|
" using running __version__ as installed version."
|
||||||
|
)
|
||||||
|
return _running
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
from repeater import __version__
|
return disk_version
|
||||||
return __version__
|
|
||||||
except Exception:
|
|
||||||
return "unknown"
|
|
||||||
|
|
||||||
# Channels file – persisted so the choice survives daemon restarts
|
# Channels file – persisted so the choice survives daemon restarts
|
||||||
_CHANNELS_FILE = "/var/lib/pymc_repeater/.update_channel"
|
_CHANNELS_FILE = "/var/lib/pymc_repeater/.update_channel"
|
||||||
|
|||||||
Reference in New Issue
Block a user