Skip to content

Commit 1ca6064

Browse files
committed
Handle no compatibility requirements case
1 parent cc21439 commit 1ca6064

3 files changed

Lines changed: 57 additions & 12 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ python -m github_release_downloader -u OwnerName -n RepoName -r ~1.1 -m .*\.exe
3333
```
3434

3535
## Features
36-
1. Downloads only compatible releases
36+
1. Downloads compatible releases (or latest if no requirements set)
3737
2. Filters assets using regex
3838
3. Has optional download_callback
3939
4. CLI tool can be used in CI

src/github_release_downloader/core.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def main():
4343
args = get_args()
4444
check_and_download_updates(
4545
GitHubRepo(args.user, args.repo_name, args.token),
46-
SimpleSpec(args.require),
46+
SimpleSpec(args.require) if args.require else None,
4747
assets_mask=re.compile(args.mask),
4848
current_version=Version(args.current_version) if args.current_version else None,
4949
downloads_dir=Path(args.output_dir)
@@ -52,7 +52,7 @@ def main():
5252

5353
def check_and_download_updates(
5454
repo: GitHubRepo,
55-
compatibility_spec: SimpleSpec,
55+
compatibility_spec: SimpleSpec = None,
5656
current_version: Version = None,
5757
assets_mask=re.compile('.*'),
5858
downloads_dir=Path(),
@@ -66,14 +66,18 @@ def check_and_download_updates(
6666
if current_version is None:
6767
current_version = Version("0.0.0")
6868
AuthSession.init(repo)
69-
logging.info(f"Compatibility requirement: '{compatibility_spec}'")
70-
71-
versions = list(sorted(compatibility_spec.filter(get_available_versions(repo)))[-10:])
72-
if not versions:
73-
logging.warning(f"No newer compatible versions available.")
69+
if compatibility_spec is None:
70+
logging.info(f"No compatibility requirements set")
71+
download_version = get_latest_version(repo)
72+
else:
73+
logging.info(f"Compatibility requirement: '{compatibility_spec}'")
74+
download_version = get_compatible_version(repo, compatibility_spec)
75+
76+
if download_version is None:
77+
compatible = " compatible" if compatibility_spec is not None else ""
78+
logging.warning(f"No newer{compatible} versions available.")
7479
return
75-
logging.info(f"Available versions: {tuple(map(str, versions))}")
76-
download_version = versions[-1]
80+
7781
if is_already_installed(download_version, current_version, compatibility_spec):
7882
return
7983
tag_name = getattr(download_version, '_origin_tag_name', str(download_version))
@@ -86,6 +90,14 @@ def check_and_download_updates(
8690
cache.version = download_version
8791

8892

93+
def get_compatible_version(repo: GitHubRepo, compatibility_spec: SimpleSpec):
94+
versions = sorted(compatibility_spec.filter(get_available_versions(repo)))[-10:]
95+
if not versions:
96+
return
97+
logging.info(f"Available versions: {tuple(map(str, versions))}")
98+
return versions[-1]
99+
100+
89101
def download_assets(
90102
assets: typing.Iterable[ReleaseAsset],
91103
out_dir=Path(),
@@ -147,6 +159,22 @@ def get_available_versions(repo: GitHubRepo, process_tag: Callable[[str], Versio
147159
break
148160

149161

162+
def get_latest_version(repo: GitHubRepo, process_tag: Callable[[str], Version] = None):
163+
if process_tag is None:
164+
process_tag = parse_tag
165+
logging.info(f"Searching for latest release in 'https://github.com/{repo.user}/{repo.repo}/'...")
166+
request_url = f"https://api.github.com/repos/{repo.user}/{repo.repo}/releases/latest"
167+
data = json.loads(requests.get(request_url, headers=AuthSession.header).text)
168+
if 'message' in data:
169+
return
170+
tag_name = data.get("tag_name")
171+
if tag_name is None:
172+
return
173+
version = process_tag(tag_name)
174+
version._origin_tag_name = tag_name
175+
return version
176+
177+
150178
def parse_tag(tag_name: str):
151179
return Version(tag_name.lstrip("v").strip())
152180

tests.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import os
23
import re
34
import shutil
@@ -15,15 +16,20 @@ class DownloadRelease(unittest.TestCase):
1516
@classmethod
1617
def setUpClass(cls):
1718
cls.repo = GitHubRepo("MBQbUtils", "BulkStartStop", os.environ.get("GITHUB_TOKEN", ""))
18-
cls.spec = SimpleSpec("~1")
19+
cls.spec = SimpleSpec("~1.0")
1920
cls.out_dir = Path("test/out")
21+
logging.basicConfig(
22+
format="[%(asctime)s][%(levelname)s] %(message)s",
23+
datefmt='%H:%M:%S',
24+
level=logging.INFO
25+
)
2026

2127
def tearDown(self):
2228
shutil.rmtree(self.out_dir, True)
2329
for path in glob("repo-*-*.cache"):
2430
Path(path).unlink()
2531

26-
def test_run_and_stop(self):
32+
def test_download_compatible_exe(self):
2733
check_and_download_updates(
2834
self.repo,
2935
self.spec,
@@ -35,6 +41,17 @@ def test_run_and_stop(self):
3541
file_actual = Path(files[0])
3642
self.assertTrue(file_actual.samefile(file_expected))
3743

44+
def test_download_latest_zip(self):
45+
check_and_download_updates(
46+
self.repo,
47+
assets_mask=re.compile(".*\\.zip"),
48+
downloads_dir=self.out_dir
49+
)
50+
files = glob(str(self.out_dir.joinpath("*.zip")))
51+
file_expected = Path(self.out_dir).joinpath("BulkStartStop_portable.zip")
52+
file_actual = Path(files[0])
53+
self.assertTrue(file_actual.samefile(file_expected))
54+
3855

3956
if __name__ == '__main__':
4057
unittest.main()

0 commit comments

Comments
 (0)