import argparse import glob import os from pathlib import Path from zipfile import ZipFile # Exclude some standard library modules to: # 1. Slim down the final zipped file size # 2. Remove functionality we don't want to support. DENY_LIST = [ # Interface to unix databases "dbm", # ncurses bindings (terminal interfaces) "curses", # Tcl/Tk GUI "tkinter", "tkinter", # Tests for the standard library "test", "tests", "idle_test", "__phello__.foo.py", # importlib frozen modules. These are already baked into CPython. "_bootstrap.py", "_bootstrap_external.py", ] strip_file_dir = "" def remove_prefix(text, prefix): if text.startswith(prefix): return text[len(prefix) :] return text def write_to_zip(file_path, strip_file_path, zf, prepend_str=""): stripped_file_path = prepend_str + remove_prefix(file_path, strip_file_dir + "/") path = Path(stripped_file_path) if path.name in DENY_LIST: return zf.write(file_path, stripped_file_path) def main() -> None: global strip_file_dir parser = argparse.ArgumentParser(description="Zip py source") parser.add_argument("paths", nargs="*", help="Paths to zip.") parser.add_argument( "--install-dir", "--install_dir", help="Root directory for all output files" ) parser.add_argument( "--strip-dir", "--strip_dir", help="The absolute directory we want to remove from zip", ) parser.add_argument( "--prepend-str", "--prepend_str", help="A string to prepend onto all paths of a file in the zip", default="", ) parser.add_argument("--zip-name", "--zip_name", help="Output zip name") args = parser.parse_args() zip_file_name = args.install_dir + "/" + args.zip_name strip_file_dir = args.strip_dir prepend_str = args.prepend_str zf = ZipFile(zip_file_name, mode="w") for p in sorted(args.paths): if os.path.isdir(p): files = glob.glob(p + "/**/*.py", recursive=True) for file_path in sorted(files): # strip the absolute path write_to_zip( file_path, strip_file_dir + "/", zf, prepend_str=prepend_str ) else: write_to_zip(p, strip_file_dir + "/", zf, prepend_str=prepend_str) if __name__ == "__main__": main() # pragma: no cover