#!/usr/bin/env python3 import json import logging import sys from urllib.request import urlopen import ruamel.yaml PYPI_INDEX = 'https://pypi.org/pypi' YAML = ruamel.yaml.YAML() YAML.indent(mapping=2, sequence=4, offset=2) YAML.preserve_quotes = True YAML.width = 180 logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s') def get_package_type(module: ruamel.yaml.comments.CommentedMap) -> str: url = module['sources'][0]['url'] if '.whl' in url: return 'bdist_wheel' return 'sdist' def get_current_version(module: ruamel.yaml.comments.CommentedMap ) -> tuple[str | None, str | None]: name = module['name'].replace('python3-','') url = module['sources'][0]['url'] if url.endswith('.git'): return None, None file_name = url.split('/')[-1] file_name = file_name.replace(name, '') parts = file_name.split('-') pkg_version = parts[1].replace('.tar.gz', '') py_version = parts[2] if '.tar.gz' not in parts[1] else None return pkg_version, py_version def get_latest_version(package_name: str, package_type: str, py_version: str | None ) -> tuple[str, str | None]: with urlopen(f'{PYPI_INDEX}/{package_name}/json') as f: data = f.read() d = json.loads(data) version = d['info']['version'] sha = None for entry in d['releases'][version]: if entry['packagetype'] != package_type: continue if py_version is not None and entry['python_version'] != py_version: continue if sha is not None: return version, None sha = entry['digests']['sha256'] return version, sha def update_module(module: ruamel.yaml.comments.CommentedMap) -> None: if not module['name'].startswith('python3-'): logging.warning('Check %s manually', module['name']) return package_type = get_package_type(module) current_version, py_version = get_current_version(module) if current_version is None: return name = module['name'].replace('python3-','') latest_version, sha = get_latest_version(name, package_type, py_version) if current_version == latest_version: return if 'only-arches' in module: logging.warning('Update %s manually', module['name']) return if sha is None: logging.warning('Could not get a unique SHA sum for %s', module['name']) return module['build-commands'][0] = module['build-commands'][0].replace( current_version, latest_version) module['sources'][0]['url'] = module['sources'][0]['url'].replace( current_version, latest_version) module['sources'][0]['sha256'] = sha def update_modules(data) -> None: for module in data['modules']: if isinstance(module, ruamel.yaml.comments.CommentedMap): update_module(module) if __name__ == '__main__': if len(sys.argv) != 2: sys.exit('Input yaml file is missing') try: with open(sys.argv[1]) as f: data = YAML.load(f) except (FileNotFoundError, ruamel.yaml.parser.ParserError, ruamel.yaml.scanner.ScannerError ) as error: sys.exit(error) update_modules(data) with open(sys.argv[1], 'w') as f: YAML.dump(data, f)