kopia lustrzana https://github.com/micropython/micropython-lib
142 wiersze
3.8 KiB
Python
142 wiersze
3.8 KiB
Python
#
|
|
# This module overrides distutils (also compatible with setuptools) "sdist"
|
|
# command to perform pre- and post-processing as required for MicroPython's
|
|
# upip package manager.
|
|
#
|
|
# Preprocessing steps:
|
|
# * Creation of Python resource module (R.py) from each top-level package's
|
|
# resources.
|
|
# Postprocessing steps:
|
|
# * Removing metadata files not used by upip (this includes setup.py)
|
|
# * Recompressing gzip archive with 4K dictionary size so it can be
|
|
# installed even on low-heap targets.
|
|
#
|
|
import sys
|
|
import os
|
|
import zlib
|
|
from subprocess import Popen, PIPE
|
|
import glob
|
|
import tarfile
|
|
import re
|
|
import io
|
|
|
|
from distutils.filelist import FileList
|
|
from setuptools.command.sdist import sdist as _sdist
|
|
|
|
|
|
def gzip_4k(inf, fname):
|
|
comp = zlib.compressobj(level=9, wbits=16 + 12)
|
|
with open(fname + ".out", "wb") as outf:
|
|
while 1:
|
|
data = inf.read(1024)
|
|
if not data:
|
|
break
|
|
outf.write(comp.compress(data))
|
|
outf.write(comp.flush())
|
|
os.rename(fname, fname + ".orig")
|
|
os.rename(fname + ".out", fname)
|
|
|
|
|
|
FILTERS = [
|
|
# include, exclude, repeat
|
|
(r".+\.egg-info/(PKG-INFO|requires\.txt)", r"setup.py$"),
|
|
(r".+\.py$", r"[^/]+$"),
|
|
(None, r".+\.egg-info/.+"),
|
|
]
|
|
|
|
|
|
outbuf = io.BytesIO()
|
|
|
|
def filter_tar(name):
|
|
fin = tarfile.open(name, "r:gz")
|
|
fout = tarfile.open(fileobj=outbuf, mode="w")
|
|
for info in fin:
|
|
# print(info)
|
|
if not "/" in info.name:
|
|
continue
|
|
fname = info.name.split("/", 1)[1]
|
|
include = None
|
|
|
|
for inc_re, exc_re in FILTERS:
|
|
if include is None and inc_re:
|
|
if re.match(inc_re, fname):
|
|
include = True
|
|
|
|
if include is None and exc_re:
|
|
if re.match(exc_re, fname):
|
|
include = False
|
|
|
|
if include is None:
|
|
include = True
|
|
|
|
if include:
|
|
print("including:", fname)
|
|
else:
|
|
print("excluding:", fname)
|
|
continue
|
|
|
|
farch = fin.extractfile(info)
|
|
fout.addfile(info, farch)
|
|
fout.close()
|
|
fin.close()
|
|
|
|
|
|
def make_resource_module(manifest_files):
|
|
resources = []
|
|
# Any non-python file included in manifest is resource
|
|
for fname in manifest_files:
|
|
ext = fname.rsplit(".", 1)[1]
|
|
if ext != "py":
|
|
resources.append(fname)
|
|
|
|
if resources:
|
|
print("creating resource module R.py")
|
|
resources.sort()
|
|
last_pkg = None
|
|
r_file = None
|
|
for fname in resources:
|
|
try:
|
|
pkg, res_name = fname.split("/", 1)
|
|
except ValueError:
|
|
print("not treating %s as a resource" % fname)
|
|
continue
|
|
if last_pkg != pkg:
|
|
last_pkg = pkg
|
|
if r_file:
|
|
r_file.write("}\n")
|
|
r_file.close()
|
|
r_file = open(pkg + "/R.py", "w")
|
|
r_file.write("R = {\n")
|
|
|
|
with open(fname, "rb") as f:
|
|
r_file.write("%r: %r,\n" % (res_name, f.read()))
|
|
|
|
if r_file:
|
|
r_file.write("}\n")
|
|
r_file.close()
|
|
|
|
|
|
class sdist(_sdist):
|
|
|
|
def run(self):
|
|
self.filelist = FileList()
|
|
self.get_file_list()
|
|
make_resource_module(self.filelist.files)
|
|
|
|
r = super().run()
|
|
|
|
assert len(self.archive_files) == 1
|
|
print("filtering files and recompressing with 4K dictionary")
|
|
filter_tar(self.archive_files[0])
|
|
outbuf.seek(0)
|
|
gzip_4k(outbuf, self.archive_files[0])
|
|
|
|
return r
|
|
|
|
|
|
# For testing only
|
|
if __name__ == "__main__":
|
|
filter_tar(sys.argv[1])
|
|
outbuf.seek(0)
|
|
gzip_4k(outbuf, sys.argv[1])
|