aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-03-29 18:55:08 -0600
committerMelody Horn <melody@boringcactus.com>2021-03-29 18:55:08 -0600
commit72c0ecc21f571bba38c889c57be0ba53aa72c015 (patch)
tree38b6e278e59743da72451572586858430902d8ce
parent2a45e45fd09f659253b44f35550de056e8e39a59 (diff)
downloadwhere-packaged-72c0ecc21f571bba38c889c57be0ba53aa72c015.tar.gz
where-packaged-72c0ecc21f571bba38c889c57be0ba53aa72c015.zip
implement crates.io
-rw-r--r--repos/__init__.py3
-rw-r--r--repos/crates_io.py47
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,
+)