Fix PEP-425 defined tag shrinking
This commit is contained in:
parent
df5294379a
commit
a68c09d6b1
2 changed files with 66 additions and 13 deletions
|
@ -7,6 +7,7 @@ import io
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
from itertools import chain
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
import zipfile
|
import zipfile
|
||||||
|
@ -15,6 +16,7 @@ from shutil import move
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
from zapp.support.unpack import cache_wheel_path
|
from zapp.support.unpack import cache_wheel_path
|
||||||
|
from zapp.support.pep425 import compress_tags, decompress_tag
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="The (bootstrap) Zapp compiler")
|
parser = argparse.ArgumentParser(description="The (bootstrap) Zapp compiler")
|
||||||
parser.add_argument("-o", "--out", dest="output", help="Output target file")
|
parser.add_argument("-o", "--out", dest="output", help="Output target file")
|
||||||
|
@ -81,7 +83,14 @@ def load_wheel(opts, manifest, path):
|
||||||
"""Load a single wheel, returning ..."""
|
"""Load a single wheel, returning ..."""
|
||||||
|
|
||||||
def _parse_email(msg):
|
def _parse_email(msg):
|
||||||
return dict(Parser().parsestr(msg).items())
|
msg = Parser().parsestr(msg)
|
||||||
|
def _get(k):
|
||||||
|
v = msg.get_all(k)
|
||||||
|
if len(v) == 1:
|
||||||
|
return v[0]
|
||||||
|
else:
|
||||||
|
return v
|
||||||
|
return {k: _get(k) for k in msg.keys()}
|
||||||
|
|
||||||
# RECORD seems to just record file reference checksums for validation
|
# RECORD seems to just record file reference checksums for validation
|
||||||
# with open(os.path.join(path, "RECORD")) as recordf:
|
# with open(os.path.join(path, "RECORD")) as recordf:
|
||||||
|
@ -105,14 +114,16 @@ def load_wheel(opts, manifest, path):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def wheel_name(wheel):
|
def wheel_name(wheel):
|
||||||
"""Construct the "canonical" filename of the wheel."""
|
"""Construct the "canonical" filename of the wheel."""
|
||||||
|
|
||||||
|
# https://www.python.org/dev/peps/pep-0425/
|
||||||
tags = wheel["wheel"].get("Tag")
|
tags = wheel["wheel"].get("Tag")
|
||||||
if isinstance(tags, list):
|
if isinstance(tags, list):
|
||||||
tags = "-" + ".".join(sorted(wheel["wheel"]["Tag"]))
|
tags = "-" + compress_tags(chain(*[decompress_tag(t) for t in tags]))
|
||||||
elif isinstance(tags, str):
|
elif isinstance(tags, str):
|
||||||
tags = "-" + wheel["wheel"]["Tag"]
|
tags = "-" + tags
|
||||||
else:
|
else:
|
||||||
tags = ""
|
tags = ""
|
||||||
|
|
||||||
|
@ -155,17 +166,23 @@ def rezip_wheels(opts, manifest):
|
||||||
# Zip up the wheels and insert wheel records to the manifest
|
# Zip up the wheels and insert wheel records to the manifest
|
||||||
for w in wheels:
|
for w in wheels:
|
||||||
# Try to cheat and hit in the local cache first rather than building wheels every time
|
# Try to cheat and hit in the local cache first rather than building wheels every time
|
||||||
wf = cache_wheel_path(wheel_name(w))
|
wn = wheel_name(w)
|
||||||
|
|
||||||
|
# We may have a double-path dependency.
|
||||||
|
# If we DON'T, we have to zip
|
||||||
|
if wn not in manifest["wheels"]:
|
||||||
|
wf = cache_wheel_path(wn)
|
||||||
if wf.exists():
|
if wf.exists():
|
||||||
try:
|
try:
|
||||||
wf.touch()
|
wf.touch()
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
wf = str(wf)
|
||||||
else:
|
else:
|
||||||
wf = zip_wheel(opts.tmpdir, w)
|
wf = zip_wheel(opts.tmpdir, w)
|
||||||
|
|
||||||
# Insert a new wheel source
|
# Insert a new wheel source
|
||||||
manifest["wheels"][wheel_name(w)] = {"hashes": [], "source": wf}
|
manifest["wheels"][wn] = {"hashes": [], "source": wf}
|
||||||
|
|
||||||
# Expunge sources available in the wheel
|
# Expunge sources available in the wheel
|
||||||
manifest["sources"] = dsub(manifest["sources"], w["sources"])
|
manifest["sources"] = dsub(manifest["sources"], w["sources"])
|
||||||
|
|
36
zapp/support/pep425.py
Normal file
36
zapp/support/pep425.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
"""An implementation of PEP-425 tag parsing, expansion and compression."""
|
||||||
|
|
||||||
|
import typing as t
|
||||||
|
|
||||||
|
|
||||||
|
class Tag(t.NamedTuple):
|
||||||
|
python: str
|
||||||
|
abi: str
|
||||||
|
arch: str # 'Platform' in the PEP
|
||||||
|
|
||||||
|
|
||||||
|
def decompress_tag(tag: str) -> t.Iterable[Tag]:
|
||||||
|
"""Decompress tag string into a sequence of compatible tuples."""
|
||||||
|
|
||||||
|
pytags, abitags, archtags = tag.split("-", 2)
|
||||||
|
for x in pytags.split('.'):
|
||||||
|
for y in abitags.split('.'):
|
||||||
|
for z in archtags.split('.'):
|
||||||
|
yield Tag(x, y, z)
|
||||||
|
|
||||||
|
|
||||||
|
def compress_tags(tags: t.Iterable[Tag]) -> str:
|
||||||
|
"""Compress a tag sequence into a string encoding compatible tuples."""
|
||||||
|
|
||||||
|
tags = set(tags)
|
||||||
|
pytags = set(t.python for t in tags)
|
||||||
|
abitags = set(t.abi for t in tags)
|
||||||
|
archtags = set(t.arch for t in tags)
|
||||||
|
|
||||||
|
tag = "-".join([
|
||||||
|
".".join(sorted(pytags)),
|
||||||
|
".".join(sorted(abitags)),
|
||||||
|
".".join(sorted(archtags)),
|
||||||
|
])
|
||||||
|
assert set(decompress_tag(tag)) == tags
|
||||||
|
return tag
|
Loading…
Reference in a new issue