diff options
author | Melody Horn <melody@boringcactus.com> | 2021-03-29 18:55:08 -0600 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-03-29 18:55:08 -0600 |
commit | 72c0ecc21f571bba38c889c57be0ba53aa72c015 (patch) | |
tree | 38b6e278e59743da72451572586858430902d8ce /repos | |
parent | 2a45e45fd09f659253b44f35550de056e8e39a59 (diff) | |
download | where-packaged-72c0ecc21f571bba38c889c57be0ba53aa72c015.tar.gz where-packaged-72c0ecc21f571bba38c889c57be0ba53aa72c015.zip |
implement crates.io
Diffstat (limited to 'repos')
-rw-r--r-- | repos/__init__.py | 3 | ||||
-rw-r--r-- | repos/crates_io.py | 47 |
2 files changed, 49 insertions, 1 deletions
diff --git a/repos/__init__.py b/repos/__init__.py index ab6aa76..7023071 100644 --- a/repos/__init__.py +++ b/repos/__init__.py @@ -1,6 +1,6 @@ from typing import Mapping, List -from . import alpine_linux, arch_linux +from . import alpine_linux, arch_linux, crates_io from .base import Repository, Version __all__ = [ @@ -16,6 +16,7 @@ def repos_from(module): all_repos: List[Repository] = [ *repos_from(alpine_linux), *repos_from(arch_linux), + *repos_from(crates_io), ] def get_versions(package: str) -> Mapping[str, Version]: diff --git a/repos/crates_io.py b/repos/crates_io.py new file mode 100644 index 0000000..95078e3 --- /dev/null +++ b/repos/crates_io.py @@ -0,0 +1,47 @@ +import csv +from io import TextIOWrapper +from pathlib import Path +import tarfile +from typing import Mapping + +from .base import Repository, Version + +__all__ = [ + 'crates', +] + +csv.field_size_limit(69696969) + +def parse_cached(cached: Path) -> Mapping[str, Version]: + dump = tarfile.open(cached) + crate_name = dict() + crate_version = dict() + for archive_member in dump.getmembers(): + if archive_member.name.endswith('crates.csv'): + reader = csv.DictReader(TextIOWrapper(dump.extractfile(archive_member), 'UTF-8')) + for crate in reader: + crate_name[crate['id']] = crate['name'] + elif archive_member.name.endswith('versions.csv'): + reader = csv.DictReader(TextIOWrapper(dump.extractfile(archive_member), 'UTF-8')) + for version in reader: + if version['yanked'] == 't': + continue + crate_id = version['crate_id'] + version = version['num'] + this_version = Version(version, version) + if crate_id in crate_version: + if this_version < crate_version[crate_id]: + continue + crate_version[crate_id] = this_version + result = dict() + for crate_id in set(crate_name.keys()).union(crate_version.keys()): + if crate_id in crate_name and crate_id in crate_version: + result[crate_name[crate_id]] = crate_version[crate_id] + return result + +crates = Repository( + family=None, + repo='crates.io', + index_url='https://static.crates.io/db-dump.tar.gz', + parse=parse_cached, +) |