--- /usr/lib/python3.7/zipapp.py 2021-09-27 23:06:43.602658316 -0500 +++ zipapp.py 2021-09-30 18:57:11.727986187 -0500 @@ -1,4 +1,5 @@ import contextlib +import datetime import os import pathlib import shutil @@ -131,6 +132,14 @@ elif not hasattr(target, 'write'): target = pathlib.Path(target) + # Use a fixed file creation epoch if configured + try: + epoch = int(os.getenv('SOURCE_DATE_EPOCH')) # throws TypeError on None + dt = datetime.datetime.fromtimestamp(epoch) + epoch = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) + except TypeError: + epoch = None + with _maybe_open(target, 'wb') as fd: _write_file_prefix(fd, interpreter) compression = (zipfile.ZIP_DEFLATED if compressed else @@ -139,9 +148,17 @@ for child in source.rglob('*'): arcname = child.relative_to(source) if filter is None or filter(arcname): - z.write(child, arcname.as_posix()) + if not epoch: + z.write(child, arcname.as_posix()) + continue + with open(child, 'rb') as fp: + zinfo = zipfile.ZipInfo(arcname.as_posix(), epoch) + z.writestr(zinfo, fp.read()) if main_py: - z.writestr('__main__.py', main_py.encode('utf-8')) + zinfo = '__main__.py' + if epoch: + zinfo = zipinfo.ZipInfo('__main__.py', epoch) + z.writestr(zinfo, main_py.encode('utf-8')) if interpreter and not hasattr(target, 'write'): target.chmod(target.stat().st_mode | stat.S_IEXEC)