rules_zapp/zapp/support/unpack.py
Reid 'arrdem' McKenzie 5b0062468f Implement re-zipping unzipped wheels
This patch teaches Zapp! to introspect the `sources` of a manifest, and
look for the well-known `WHEEL` file(s) indicative of an
unzipped/installed wheel in the input sources. A wheel can be (somewhat*)
correctly reassembled by zipping its unzipped state, so in the presence
of unzipped wheels Zapp! will re-zip them and enter them into the
manifest appropriately for inclusion.

This fixes #6 the nasty way, as there's no good way to make
`rules_python` provide wheel dependencies or to translate unrolled
wheels back to wheels during rule execution as this would violate
Bazel's file dependency model.
2021-08-29 15:07:56 -06:00

54 lines
1.2 KiB
Python

"""Conditionally unpack a zapp (and its deps)."""
import os
import sys
from pathlib import Path
from zipfile import ZipFile
from zapp.support.manifest import manifest
def cache_root() -> Path:
return Path(os.path.join(os.path.expanduser("~"))) / ".cache" / "zapp"
def cache_wheel_root():
return cache_root() / "wheels"
def cache_wheel_path(wheel: str) -> Path:
return cache_wheel_root() / wheel
def cache_zapp_root():
return cache_root() / "zapps"
def cache_zapp_path(fingerprint):
return cache_zapp_root() / fingerprint
def unpack_deps():
"""Unpack deps, populating and updating the host's cache."""
# Create the cache dir as needed
cache_wheel_root().mkdir(parents=True, exist_ok=True)
# For each wheel, touch the existing cached wheel or unpack this one.
with ZipFile(sys.argv[0], "r") as zf:
for whl, config in manifest()["wheels"].items():
cached_whl = cache_wheel_path(whl)
if cached_whl.exists():
cached_whl.touch()
else:
with open(cached_whl, "wb") as of:
of.write(zf.read(".deps/" + whl))
sys.path.insert(0, str(cached_whl))
def main():
"""Inspect the manifest."""
unpack_deps()