# SPDX-License-Identifier: LGPL-2.1 # Copyright 2022 Jookia <contact@jookia.org> import pathlib import zipfile def reproducible_date(): return (2000, 1, 1, 1, 1, 1) def open_new_file(path): path.unlink(missing_ok=True) file = path.open("xb") mode = path.stat().st_mode new_mode = mode | 0o100 # Executable path.chmod(new_mode) return file def write_shebang(file): shebang = "#!/usr/bin/env python3\n" file.write(shebang.encode("utf-8")) def open_zip(file): return zipfile.ZipFile( file, mode="a", compression=zipfile.ZIP_DEFLATED, compresslevel=9 ) def close_zip(zip): zip.close() def close_file(file): file.close() def find_all_src(srcpath): paths = srcpath.glob("**/*") new_paths = [srcpath] for p in paths: if "__pycache__" in p.as_posix(): continue if p.name[0] == ".": continue new_paths.append(p) return new_paths def write_zip_entry(zip, name, data, date): info = zipfile.ZipInfo(filename=name, date_time=date) info.create_system = 3 # UNIX 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("rb") data = file.read() new_data = data.replace(b"\r\n", b"\n") file.close() name = path.as_posix() write_zip_entry(zip, name, new_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(): date = reproducible_date() file = open_new_file(pathlib.Path("NewLang.pyz")) write_shebang(file) zip = open_zip(file) write_src(zip, date) write_main(zip, date) close_zip(zip) close_file(file) if __name__ == "__main__": main()