diff options
-rw-r--r-- | repos/__init__.py | 3 | ||||
-rw-r--r-- | repos/arch_linux.py | 74 |
2 files changed, 76 insertions, 1 deletions
diff --git a/repos/__init__.py b/repos/__init__.py index 1dea3a1..fc81260 100644 --- a/repos/__init__.py +++ b/repos/__init__.py @@ -1,6 +1,6 @@ from typing import Mapping, List -from . import alpine_linux +from . import alpine_linux, arch_linux from .base import Repository __all__ = [ @@ -15,6 +15,7 @@ def repos_from(module): all_repos: List[Repository] = [ *repos_from(alpine_linux), + *repos_from(arch_linux), ] def get_versions(package: str) -> Mapping[str, Mapping[str, str]]: diff --git a/repos/arch_linux.py b/repos/arch_linux.py new file mode 100644 index 0000000..52ef557 --- /dev/null +++ b/repos/arch_linux.py @@ -0,0 +1,74 @@ +from io import TextIOWrapper +from pathlib import Path +import re +import tarfile +from typing import Mapping, TextIO, Tuple + +from .base import Repository, Version + +__all__ = [ + 'core', + 'community', + 'community_testing', + 'extra', + 'gnome_unstable', + 'kde_unstable', + 'multilib', + 'multilib_testing', + 'testing', +] + +PACKAGE_REVISION_INFO = re.compile(r'(^\d+:)|(-\d+$)') + +def parse_desc(desc_file: TextIO) -> Tuple[str, Version]: + name = None + version = None + next_line_is = None + for line in desc_file: + line = line.strip() + if len(line) == 0: + continue + if line.startswith('%') and line.endswith('%'): + next_line_is = line.strip('%') + continue + if next_line_is == 'NAME': + name = line + elif next_line_is == 'VERSION': + version = line + next_line_is = None + + if name is not None and version is not None: + clean_version = PACKAGE_REVISION_INFO.sub('', version) + return name, Version(version, clean_version) + +def parse_cached(cached: Path) -> Mapping[str, Version]: + db = tarfile.open(cached) + result = dict() + for archive_member in db.getmembers(): + if archive_member.name.endswith('/desc') and archive_member.isfile(): + desc_file = db.extractfile(archive_member) + desc_file = TextIOWrapper(desc_file) + name, version = parse_desc(desc_file) + result[name] = version + return result + +def build_repo(name: str) -> Repository: + url = f'https://mirror.rackspace.com/archlinux/{name}/os/x86_64/{name}.db.tar.gz' + return Repository( + family='Arch Linux', + repo=name, + index_url=url, + parse=parse_cached, + ) + +core = build_repo('core') +community = build_repo('community') +community_testing = build_repo('community-testing') +extra = build_repo('extra') +gnome_unstable = build_repo('gnome-unstable') +kde_unstable = build_repo('kde-unstable') +multilib = build_repo('multilib') +multilib_testing = build_repo('multilib-testing') +testing = build_repo('testing') + +# TODO figure out how to grab this info from AUR |