Coverage for app/venv/lib/python3.14/site-packages/weblate/utils/version.py: 82%

63 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 07:15 +0000

1# Copyright © Michal Čihař <michal@weblate.org> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5from __future__ import annotations 

6 

7import os 

8from operator import itemgetter 

9from typing import TYPE_CHECKING, NamedTuple 

10 

11from dateutil.parser import parse 

12from django.core.cache import cache 

13 

14from weblate.vcs.base import RepositoryError 

15from weblate.vcs.git import GitRepository 

16 

17if TYPE_CHECKING: 17 ↛ 18line 17 didn't jump to line 18 because the condition on line 17 was never true

18 from datetime import datetime 

19 

20 

21def get_root_dir(): 

22 """Return Weblate root dir.""" 

23 curdir = os.path.dirname(os.path.abspath(__file__)) 

24 return os.path.abspath(os.path.join(curdir, "..", "..")) 

25 

26 

27# Weblate version 

28VERSION = "5.14.3" 

29 

30# Version string without suffix 

31VERSION_BASE = VERSION.replace("-dev", "").replace("-rc", "") 

32 

33# User-Agent string to use 

34USER_AGENT = f"Weblate/{VERSION}" 

35 

36# Git tag name for this release 

37TAG_NAME = f"weblate-{VERSION_BASE}" 

38 

39# Type annotations 

40GIT_VERSION: str 

41GIT_REVISION: str | None 

42GIT_LINK: str | None 

43 

44# Grab some information from git 

45try: 

46 # Describe current checkout 

47 GIT_REPO = GitRepository(get_root_dir(), local=True) 

48 GIT_VERSION = GIT_REPO.describe() 

49 GIT_REVISION = GIT_REPO.last_revision 

50 del GIT_REPO 

51except (RepositoryError, OSError): 

52 # Special case for Docker bleeding builds 

53 if "WEBLATE_DOCKER_GIT_REVISION" in os.environ: 53 ↛ 54line 53 didn't jump to line 54 because the condition on line 53 was never true

54 GIT_REVISION = os.environ["WEBLATE_DOCKER_GIT_REVISION"] 

55 GIT_VERSION = f"{VERSION_BASE}-{GIT_REVISION[:10]}" 

56 else: 

57 # Import failed or git has troubles reading 

58 # repo (for example swallow clone) 

59 GIT_VERSION = VERSION 

60 GIT_REVISION = None 

61 

62if GIT_REVISION: 62 ↛ 63line 62 didn't jump to line 63 because the condition on line 62 was never true

63 GIT_LINK = f"https://github.com/WeblateOrg/weblate/commits/{GIT_REVISION}" 

64elif VERSION == VERSION_BASE: 64 ↛ 67line 64 didn't jump to line 67 because the condition on line 64 was always true

65 GIT_LINK = f"https://github.com/WeblateOrg/weblate/releases/tag/weblate-{VERSION}" 

66else: 

67 GIT_LINK = None 

68 

69# Python Package Index URL 

70PYPI = "https://pypi.org/pypi/weblate/json" 

71 

72# Cache to store fetched PyPI version 

73CACHE_KEY = "weblate-version-check" 

74 

75 

76class Release(NamedTuple): 

77 version: str 

78 timestamp: datetime 

79 

80 

81def download_version_info() -> list[Release]: 

82 from weblate.utils.requests import request 

83 

84 response = request("get", PYPI) 

85 result = [] 

86 for version, info in response.json()["releases"].items(): 

87 if not info: 

88 continue 

89 result.append(Release(version, parse(info[0]["upload_time_iso_8601"]))) 

90 return sorted(result, key=itemgetter(1), reverse=True) 

91 

92 

93def flush_version_cache() -> None: 

94 cache.delete(CACHE_KEY) 

95 

96 

97def get_version_info() -> list[Release]: 

98 try: 

99 result = cache.get(CACHE_KEY) 

100 except AttributeError: 

101 # TODO: Remove try/except in Weblate 6 

102 # Can happen on upgrade to 5.4 when unpickling fails because 

103 # of the Release class was moved between modules 

104 result = None 

105 if not result: 

106 result = download_version_info() 

107 cache.set(CACHE_KEY, result, 86400) 

108 return result 

109 

110 

111def get_latest_version() -> Release: 

112 return get_version_info()[0]