123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #!/usr/bin/env python
- '''Fetch the MSYS2 installer.'''
- from __future__ import annotations
- import hashlib
- import json
- import shutil
- import sys
- from pathlib import Path
- from tempfile import TemporaryDirectory
- from typing import Final
- from urllib.request import Request, urlopen
- REPO: Final = 'msys2/msys2-installer'
- def get_latest_release() -> tuple[str, str]:
- '''Get the latest release for the repo.'''
- REQUEST: Final = Request(
- url=f'https://api.github.com/repos/{REPO}/releases',
- headers={
- 'Accept': 'application/vnd.github+json',
- 'X-GitHub-API-Version': '2022-11-28',
- },
- method='GET',
- )
- print('>>> Fetching release list')
- with urlopen(REQUEST, timeout=15) as response:
- if response.status != 200:
- print(f'!!! Failed to fetch release list, status={response.status}')
- sys.exit(1)
- data = json.load(response)
- data = list(filter(lambda x: x['name'] != 'Nightly Installer Build', data))
- name = data[0]['name']
- version = data[0]['tag_name'].replace('-', '')
- return name, version
- def fetch_release_asset(tmpdir: Path, name: str, file: str) -> Path:
- '''Fetch a specific release asset.'''
- REQUEST: Final = Request(
- url=f'https://github.com/{REPO}/releases/download/{name}/{file}',
- method='GET',
- )
- TARGET: Final = tmpdir / file
- print(f'>>> Downloading {file}')
- with urlopen(REQUEST, timeout=15) as response:
- if response.status != 200:
- print(f'!!! Failed to fetch {file}, status={response.status}')
- sys.exit(1)
- TARGET.write_bytes(response.read())
- return TARGET
- def main() -> None:
- '''Core program logic.'''
- if len(sys.argv) != 2:
- print(f'{__file__} must be run with exactly one argument.')
- target = Path(sys.argv[1])
- tmp_target = target.with_name(f'.{target.name}.tmp')
- name, version = get_latest_release()
- with TemporaryDirectory() as tmpdir:
- tmppath = Path(tmpdir)
- installer = fetch_release_asset(tmppath, name, f'msys2-base-x86_64-{version}.tar.zst')
- checksums = fetch_release_asset(tmppath, name, f'msys2-base-x86_64-{version}.tar.zst.sha256')
- print('>>> Verifying SHA256 checksum')
- expected_checksum = checksums.read_text().partition(' ')[0].casefold()
- actual_checksum = hashlib.sha256(installer.read_bytes()).hexdigest().casefold()
- if expected_checksum != actual_checksum:
- print('!!! Checksum mismatch')
- print(f'!!! Expected: {expected_checksum}')
- print(f'!!! Actual: {actual_checksum}')
- sys.exit(1)
- print(f'>>> Copying to {target}')
- shutil.copy(installer, tmp_target)
- tmp_target.replace(target)
- if __name__ == '__main__':
- main()
|