# SPDX-License-Identifier: LGPL-2.1 # Copyright 2022 Jookia <contact@jookia.org> import pathlib import zipfile import subprocess import time def reproducible_date(): fallback = (1980, 1, 1, 1, 1, 1) git_time = subprocess.run( ["git", "show", "-s", "--format=%ct"], capture_output=True ) if git_time.returncode != 0: return fallback commit_time = int(git_time.stdout.decode("utf-8").split("\n")[0]) t = time.gmtime(commit_time) return (t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec) def clean_zip(path): path.unlink(missing_ok=True) def open_zip(path): return zipfile.ZipFile( path, mode="x", compression=zipfile.ZIP_DEFLATED, compresslevel=9 ) def close_zip(zip): zip.close() def find_all_src(srcpath): paths = srcpath.glob("**/*") new_paths = [srcpath] for p in paths: if "__pycache__" in p.as_posix(): continue new_paths.append(p) return new_paths def write_zip_entry(zip, name, data, date): info = zipfile.ZipInfo(filename=name, date_time=date) zip.writestr(info, data, compress_type=zipfile.ZIP_DEFLATED, compresslevel=9) def write_main(zip, date): name = "__main__.py" data = "import src.main\nsrc.main.wait_main()" write_zip_entry(zip, name, data, date) def write_dir(zip, path, date): # For some reason Python needs empty files with the names of directories ending in / name = path.as_posix() + "/" data = "" write_zip_entry(zip, name, data, date) def write_file(zip, path, date): file = path.open() data = file.read() file.close() name = path.as_posix() write_zip_entry(zip, name, data, date) def write_src(zip, date): srcs = sorted(find_all_src(pathlib.Path("src"))) for p in srcs: if p.is_dir(): write_dir(zip, p, date) else: write_file(zip, p, date) def main(): filename = pathlib.Path("NewLang.pyz") date = reproducible_date() clean_zip(filename) zip = open_zip(filename) write_src(zip, date) write_main(zip, date) close_zip(zip) if __name__ == "__main__": main()